Django无法删除数据库:psycopg2.OperationalError:无法删除当前打开的数据库

时间:2016-05-21 20:32:57

标签: django postgresql psycopg2

每当我尝试通过manage.py运行我的Django测试时,测试运行正常,但是当Django破坏数据库时,会发生以下错误:

Destroying test database for alias 'default'...
Traceback (most recent call last):
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 62, in execute
    return self.cursor.execute(sql)
psycopg2.OperationalError: cannot drop the currently open database


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Applications/PyCharm.app/Contents/helpers/pycharm/django_test_manage.py", line 129, in <module>
    utility.execute()
  File "/Applications/PyCharm.app/Contents/helpers/pycharm/django_test_manage.py", line 104, in execute
    PycharmTestCommand().run_from_argv(self.argv)
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/core/management/commands/test.py", line 30, in run_from_argv
    super(Command, self).run_from_argv(argv)
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/core/management/base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/core/management/commands/test.py", line 74, in execute
    super(Command, self).execute(*args, **options)
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/core/management/base.py", line 399, in execute
    output = self.handle(*args, **options)
  File "/Applications/PyCharm.app/Contents/helpers/pycharm/django_test_manage.py", line 91, in handle
    failures = TestRunner(test_labels, verbosity=verbosity, interactive=interactive, failfast=failfast, keepdb='--keepdb' in sys.argv)
  File "/Applications/PyCharm.app/Contents/helpers/pycharm/django_test_runner.py", line 256, in run_tests
    extra_tests=extra_tests, **options)
  File "/Applications/PyCharm.app/Contents/helpers/pycharm/django_test_runner.py", line 156, in run_tests
    return super(DjangoTeamcityTestRunner, self).run_tests(test_labels, extra_tests, **kwargs)
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/test/runner.py", line 534, in run_tests
    self.teardown_databases(old_config)
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/test/runner.py", line 509, in teardown_databases
    connection.creation.destroy_test_db(old_name, self.verbosity, self.keepdb)
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/db/backends/base/creation.py", line 264, in destroy_test_db
    self._destroy_test_db(test_database_name, verbosity)
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/db/backends/base/creation.py", line 283, in _destroy_test_db
    % self.connection.ops.quote_name(test_database_name))
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/db/utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 62, in execute
    return self.cursor.execute(sql)
django.db.utils.OperationalError: cannot drop the currently open database

我已经检查过以确保没有其他任何内容连接到数据库 - 为什么Django不能删除数据库?

注意:我正在使用PostgreSQL

2 个答案:

答案 0 :(得分:16)

TL; DR

如果您只是想要解决方案,请点击此处。 确保您的Postgres服务器具有“postgres”数据库。您可以通过psql连接,然后运行/list/l进行检查。您可以通过在psql中运行:CREATE DATABASE postgres来创建数据库。

扩展

Django更喜欢不从DATABASES设置中指定的“默认”数据库运行“初始化查询”(可能是创建测试数据库)。这被认为是生产数据库,所以在Django最好的利益是不要乱用那里。

这就是为什么在测试开始时会显示(忽略我的文件系统):

    /Users/dcgoss/Desktop/Pickle/PickleBackend/venv/lib/python3.4/site-packages/django/db/backends/postgresql/base.py:247: 
    RuntimeWarning: Normally Django will use a connection to the 'postgres' database to avoid running initialization queries against the production database when it's not needed 
    (for example, when running tests). Django was unable to create a connection to the 'postgres' database and will use the default database instead.
    RuntimeWarning

Django在DATABASES设置中指定的主机上查找名为“postgres”的数据库,这是运行查询以创建和删除测试数据库的位置。 (注意:Django不需要在您的设置中明确指定“postgres”数据库,它只是在您的设置中指定的任何数据库服务器上查找它。)

看来如果这个“postgres”数据库不存在,Django可以创建测试数据库并运行测试,但它无法删除测试数据库。这可能是因为Postgres不允许你删除你当前连接的数据库,但是对我来说似乎没有理由让Django不能将测试数据库从指定的“默认”(生产)数据库中删除设置。我认为它使用“默认”数据库来创建测试数据库,因此似乎没有理由不能删除它。

无论如何,解决方案只是使用简单的SQL语句创建“postgres”数据库:CREATE DATABASE postgres。创建该数据库后,一切正常。

答案 1 :(得分:3)

如果存在postgres数据库,请尝试在pg_hba.conf中添加对'postgres'数据库的访问权限。请参阅:https://www.postgresql.org/docs/9.1/static/auth-pg-hba-conf.html