我在 Django 的测试套件中遇到了一个奇怪的问题,我被卡住了,所以我正在寻找一些关于如何修复它或至少在哪里寻找的见解。
当我运行以下命令来测试我的 teddybears 应用程序时:
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
默认情况下,数据库不应该以“test”一词为前缀以避免名称冲突吗?我将数据库重命名为“: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
回复:
这是我的数据库设置:
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.
}
}
我确实有这个,但它没有任何区别:
if 'test' in sys.argv:
DATABASES['default']['NAME'] = ':memory:'
2 X 咕噜……
不幸的是没有解决这个问题。除了更改数据库名称外,我已经尝试了所有建议的方法,但这也没有解决它。
我做了所有的建议,包括:
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:
仍然产生相同的错误。
不想将它移到另一个干净的项目来解决这个问题,但它仍然很烦人。
我已经弄清楚是什么绊倒了我。项目中的一个模型在 Meta Class 上设置了一个值,导致测试中断。
class TeddybearExtra(Teddybear):
class Meta:
db_table = 'teddybears_teddybear'
如您所见,它是原始模型的子类,并且由于明确设置了“db_table”属性,它覆盖了自动生成的表名。这里学到的教训是,在 Meta 对象上设置 db_table 属性会导致测试工具发生坏事。仅当您绝对需要以这种方式处理时才这样做。