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を使用し、Django1.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
返事:
これが私の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.
}
}
私はそこにこれを持っていましたが、違いはありませんでした:
if 'test' in sys.argv:
DATABASES['default']['NAME'] = ':memory:'
2 XGrrr...。
残念ながら、問題は修正されていません。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:
それでも同じエラーが発生します。
これを修正するためだけに別のクリーンなプロジェクトに移動するのは嫌だと思いますが、それでも面倒です。
何が私をつまずかせているのか理解しました。プロジェクトのモデルの1つに、テストが失敗する原因となったメタクラスに設定された値がありました。
class TeddybearExtra(Teddybear):
class Meta:
db_table = 'teddybears_teddybear'
ご覧のとおり、これは元のモデルのサブクラスであり、「db_table」属性が明示的に設定されているため、自動生成されたテーブル名が上書きされます。ここで学んだ教訓は、メタオブジェクトにdb_table属性を設定すると、テストツールで悪いことが起こるということです。どうしてもこの方法で処理する必要がある場合にのみ、これを実行してください。