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

时间:2022-08-18 16:15:56

Whenever I try to run my Django tests via manage.py, the tests run fine however at the end when Django is destroying the database the following error occurs:

每当我尝试通过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

I've checked to ensure that nothing else is connected to the database - why can't Django drop the database?

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

Note: I am using PostgreSQL

注意:我正在使用PostgreSQL

2 个解决方案

#1


12  

TL;DR

If you just want the solution, here it is. Make sure that your Postgres server has a "postgres" database. You can check by connecting via psql, and running /list or /l. You can create the database by running: CREATE DATABASE postgres in psql.

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

Extended

Django prefers to not run "initialization queries" (presumably things like creating the test database) from the "default" database specified in your DATABASES setting. This is presumed to be the production database, so it would be in Django's best interests to not mess around there.

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

This is why at the beginning of the tests, this is shown (ignore my filesystem):

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

    /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 looks for a database named "postgres" on the host specified in your DATABASES settings, this is where it runs the queries to create and delete your test database. (Note: Django does not need the "postgres" database to be explicitly specified in your settings, it just looks for it on whatever database server is specified in your settings).

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

It appears that if this "postgres" database does not exist, Django can create the test database and run the tests, but it cannot delete the test database. This may be because Postgres does not allow you to drop the database you are currently connected to, however to me it seems that there is no reason that Django couldn't just drop the test database from the "default" (production) database specified in the settings. I presume it is using the "default" database to create the test database, so it seems there's no reason why it can't delete it as well.

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

Regardless, the solution was just to create that "postgres" database with a simple SQL statement: CREATE DATABASE postgres. After that database was created, everything worked fine.

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

#2


2  

If postgres database exists, try adding access to 'postgres' database in pg_hba.conf. Refer: https://www.postgresql.org/docs/9.1/static/auth-pg-hba-conf.html

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

#1


12  

TL;DR

If you just want the solution, here it is. Make sure that your Postgres server has a "postgres" database. You can check by connecting via psql, and running /list or /l. You can create the database by running: CREATE DATABASE postgres in psql.

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

Extended

Django prefers to not run "initialization queries" (presumably things like creating the test database) from the "default" database specified in your DATABASES setting. This is presumed to be the production database, so it would be in Django's best interests to not mess around there.

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

This is why at the beginning of the tests, this is shown (ignore my filesystem):

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

    /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 looks for a database named "postgres" on the host specified in your DATABASES settings, this is where it runs the queries to create and delete your test database. (Note: Django does not need the "postgres" database to be explicitly specified in your settings, it just looks for it on whatever database server is specified in your settings).

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

It appears that if this "postgres" database does not exist, Django can create the test database and run the tests, but it cannot delete the test database. This may be because Postgres does not allow you to drop the database you are currently connected to, however to me it seems that there is no reason that Django couldn't just drop the test database from the "default" (production) database specified in the settings. I presume it is using the "default" database to create the test database, so it seems there's no reason why it can't delete it as well.

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

Regardless, the solution was just to create that "postgres" database with a simple SQL statement: CREATE DATABASE postgres. After that database was created, everything worked fine.

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

#2


2  

If postgres database exists, try adding access to 'postgres' database in pg_hba.conf. Refer: https://www.postgresql.org/docs/9.1/static/auth-pg-hba-conf.html

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