在使用带有Django的ThreadPoolExecutor时,数据库“正由其他用户访问”错误

我正在开发一个项目,我们解析一个有点大的文件并使用ThreadPoolExecutor异步处理每一行(我们为每一行进行API调用).这曾经是同步完成的,我们有一个通过测试套件.但是,现在,当运行测试时,Django的默认测试运行器会在teardown_databases中出错:

Traceback (most recent call last):
  File "manage.py", line 34, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.5/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.5/site-packages/django/core/management/__init__.py", line 359, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.5/site-packages/django/core/management/commands/test.py", line 29, in run_from_argv
    super(Command, self).run_from_argv(argv)
  File "/usr/local/lib/python3.5/site-packages/django/core/management/base.py", line 294, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.5/site-packages/django/core/management/base.py", line 345, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.5/site-packages/django/core/management/commands/test.py", line 72, in handle
    failures = test_runner.run_tests(test_labels)
  File "/usr/local/lib/python3.5/site-packages/django/test/runner.py", line 551, in run_tests
    self.teardown_databases(old_config)
  File "/usr/local/lib/python3.5/site-packages/django/test/runner.py", line 526, in teardown_databases
    connection.creation.destroy_test_db(old_name, self.verbosity, self.keepdb)
  File "/usr/local/lib/python3.5/site-packages/django/db/backends/base/creation.py", line 264, in destroy_test_db
    self._destroy_test_db(test_database_name, verbosity)
  File "/usr/local/lib/python3.5/site-packages/django/db/backends/base/creation.py", line 283, in _destroy_test_db
    % self.connection.ops.quote_name(test_database_name))
  File "/usr/local/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.5/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.5/site-packages/django/db/backends/utils.py", line 62, in execute
    return self.cursor.execute(sql)
django.db.utils.OperationalError: database "test_sftpm_db" is being accessed by other users
DETAIL:  There are 10 other sessions using the database.

(我们使用10名工人)

我试图在代码中的许多地方手动关闭连接,但无济于事.有没有正确的方法解决这个问题?

解决方法:

这看起来比Postgres更多Django的问题 –
 例如看这张票:https://code.djangoproject.com/ticket/22420

根据您提供的内容,我发现Django在尝试删除它之前没有关闭所有测试数据库的连接.在这种情况下,Postges尝试保护其他会话免受数据丢失的影响,因此在它们全部断开连接之前,它不能删除/重命名数据库.

如果需要,可以使用已使用的pg_terminate_backend(..)函数和pg_stat_activity视图手动删除测试数据库:

select pg_terminate_backend(pid) 
from pg_stat_activity 
where
  datname = 'DATABASE_NAME'
;

drop database DATABASE_NAME;

如果由于某种原因,有人非常快速并且设法在两个命令之间建立连接,则drop database将再次失败.在这种情况下,您可以重复它,但在撤销权限之前从公共连接到此数据库 – 这将阻止与它的连接:

revoke connect on database DATABASE_NAME from public;

……然后重复上述操作.

相关文章

文章浏览阅读601次。Oracle的数据导入导出是一项基本的技能,...
文章浏览阅读553次。开头还是介绍一下群,如果感兴趣polardb...
文章浏览阅读3.5k次,点赞3次,收藏7次。折腾了两个小时多才...
文章浏览阅读2.7k次。JSON 代表 JavaScript Object Notation...
文章浏览阅读2.9k次,点赞2次,收藏6次。navicat 连接postgr...
文章浏览阅读1.4k次。postgre进阶sql,包含分组排序、JSON解...