Python Django SQLite在测试时试图覆盖DB

Python Django SQLite在测试时试图覆盖DB,python,django,Python,Django,我在Django的测试套件中遇到了一个奇怪的问题,我被卡住了,所以我正在寻找一些关于如何修复它或者至少在哪里查找的见解 当我运行以下程序来测试我的泰迪熊应用程序时: python manage.py test teddybears 我得到这个错误: ...django/db/backends/sqlite3/base.py", line 344, in execute return Database.Cursor.execute(self, query, params) django.db.u

我在Django的测试套件中遇到了一个奇怪的问题,我被卡住了,所以我正在寻找一些关于如何修复它或者至少在哪里查找的见解

当我运行以下程序来测试我的泰迪熊应用程序时:

python manage.py test teddybears
我得到这个错误:

...django/db/backends/sqlite3/base.py", line 344, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.DatabaseError: table "teddybears_teddybear" already exists
默认情况下,DB不应该以单词“test”作为前缀以避免名称冲突吗?我将DB重命名为“:memory:”以避免出现这种情况,但仍然是相同的错误

开发工作正常,一切正常,我就是无法让测试套件正常工作。如果您能深入了解造成这种情况的原因,或从何处寻找答案,我们将不胜感激

我使用SQLite进行本地开发工作,并使用Django 1.4.3

以下是完整的堆栈跟踪:

> python manage.py test teadybears
Creating test database for alias 'default'...
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 443, in execute_from_command_line
    utility.execute()
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 382, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/commands/test.py", line 49, in run_from_argv
    super(Command, self).run_from_argv(argv)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/base.py", line 196, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/base.py", line 232, in execute
    output = self.handle(*args, **options)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/commands/test.py", line 72, in handle
    failures = test_runner.run_tests(test_labels)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/test/simple.py", line 381, in run_tests
    old_config = self.setup_databases()
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/test/simple.py", line 317, in setup_databases
    self.verbosity, autoclobber=not self.interactive)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/db/backends/creation.py", line 271, in create_test_db
    load_initial_data=False)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 150, in call_command
    return klass.execute(*args, **defaults)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/base.py", line 232, in execute
    output = self.handle(*args, **options)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/base.py", line 371, in handle
    return self.handle_noargs(**options)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/commands/syncdb.py", line 102, in handle_noargs
    cursor.execute(statement)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 344, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.DatabaseError: table "teadybears_teadybear" already exists
我确实有这个,但没什么区别:

if 'test' in sys.argv:
    DATABASES['default']['NAME'] = ':memory:'

2个Grrr

不幸的是,没有解决这个问题。我尝试了所有建议,除了更改DB名称,但也没有解决它

我做了所有建议,包括:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'database.sqlite',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
        'TEST_NAME': 'mud',
    }
}
现在它问我:

python manage.py test teddybears
Creating test database for alias 'default'...
Destroying old test database 'default'...
Type 'yes' if you would like to try deleting the test database 'mud', or 'no' to cancel:
仍然会产生相同的错误

我不想为了解决这个问题而把它转移到另一个干净的项目中,但它仍然很烦人


我已经知道是什么绊倒了我。项目中的一个模型在导致测试中断的元类上设置了一个值

class TeddybearExtra(Teddybear):

    class Meta:
        db_table = 'teddybears_teddybear'

正如您所看到的,它是原始模型的一个子类,由于“db_table”属性是显式设置的,因此它覆盖了自动生成的表名。这里学到的经验是,在元对象上设置db_table属性会导致测试工具出现不好的情况。只有当您确实需要以这种方式处理时,才可以执行此操作。

您是否指向正确的设置模块?尝试:

python manage.py test teddybears --settings=myproject.settings.test

你指的是正确的设置模块吗?尝试:

python manage.py test teddybears --settings=myproject.settings.test

文档中有两个部分可能与您遇到的问题有关:

默认情况下,测试数据库通过将test_uu前置到数据库中定义的数据库的名称设置值来获取其名称。当使用SQLite数据库引擎时,默认情况下测试将使用内存中的数据库(即,数据库将在内存中创建,完全绕过文件系统!)。如果要使用其他数据库名称,请在字典中为数据库中的任何给定数据库指定TEST_名称

如果您的测试依赖于数据库访问,例如创建或查询模型,请确保将您的测试类创建为django.test.TestCase的子类,而不是unittest.TestCase

在上面的示例中,我们实例化了一些模型,但没有将它们保存到数据库中。使用unittest.TestCase可以避免在事务中运行每个测试和刷新数据库的成本,但是对于大多数应用程序,您能够以这种方式编写的测试的范围将相当有限,因此使用django.test.TestCase是最简单的

因此,首先,确保您的测试是从
django.test.TestCase
子类化的。其次,尝试将
TEST\u NAME
设置为
testdb.sqlite
,看看这是否解决了您的问题。您可能还希望在
/Work/database.sqlite
中指定数据库的路径,否则(我认为)将在执行
manage.py
的目录中创建数据库,这可能并不总是您想要的


最后,确保为测试加载了正确的
设置
文件。

文档中有两个部分可能与您遇到的问题有关:

默认情况下,测试数据库通过将test_uu前置到数据库中定义的数据库的名称设置值来获取其名称。当使用SQLite数据库引擎时,默认情况下测试将使用内存中的数据库(即,数据库将在内存中创建,完全绕过文件系统!)。如果要使用其他数据库名称,请在字典中为数据库中的任何给定数据库指定TEST_名称

如果您的测试依赖于数据库访问,例如创建或查询模型,请确保将您的测试类创建为django.test.TestCase的子类,而不是unittest.TestCase

在上面的示例中,我们实例化了一些模型,但没有将它们保存到数据库中。使用unittest.TestCase可以避免在事务中运行每个测试和刷新数据库的成本,但是对于大多数应用程序,您能够以这种方式编写的测试的范围将相当有限,因此使用django.test.TestCase是最简单的

因此,首先,确保您的测试是从
django.test.TestCase
子类化的。其次,尝试将
TEST\u NAME
设置为
testdb.sqlite
,看看这是否解决了您的问题。您可能还希望在
/Work/database.sqlite
中指定数据库的路径,否则(我认为)将在执行
manage.py
的目录中创建数据库,这可能并不总是您想要的


最后,确保为测试加载了正确的
设置
文件。

首先,检查您是否使用
db\u table='teadybeaers\u teadybear'
意外定义了两个模型。并确保仅为测试更改数据库:
if'test'in sys.argv:DATABASES['default']={'ENGINE':'django.DB.backends.sqlite3'}
请在问题中包含
数据库中的
条目,检查您是否无意中使用
db\u table='teadybeaers\u teadybear'
定义了两个模型。并确保仅为测试更改数据库:
if'test'in sys.argv:DATABASES['default']={'ENGINE':'django.DB.backends.sqlite3'}
请在问题.Grrr中包含
设置.py
中的
数据库条目,在我完成键入之前发送。我将default test.py放在其中并删除了所有测试