私は頻繁にテストケースを実行しますdjangoプロジェクト。しかし、1つ 天気の良い日、djangoが実際にチェックすることが私に起こりました settings.DATABASE_NAMEdbテストケースの実行中の実際の存在。 なぜそうなのですか。私が思ったのは、ジャンゴが settings.DATABASE_NAMEを作成し、「test_」というテストデータベースを作成します+ settings.DATABASE_NAME。また、データベースが name = settings.DATABASE_NAMEは、実際に存在するかどうか( テストデータベースの作成)?理想的には、名前だけをチェックする必要があります しかし、データベースの実際の存在ではありませんか?
djangoのソースコードを閲覧してtestdbの作成に使用される「接続」は、実際にはDATABASE設定オプションを使用して作成されていることがわかりました。実際の存在ではなく、設定の値について気にする必要があります。
回答:
回答№1の場合は3きちんとした質問...あなたが知っている、これは私には決して起こらなかった。簡単な答えは、Django自体はそうではないということです。 必要 DATABASE_NAMEが実際に存在することを確認するには、ただし、テストデータベースを作成するには、データベースに接続する必要があります。ほとんどのデータベースは、接続文字列を作成するためにDATABASE_NAMEを受け入れます(一部は必要とします)。多くの場合、これは、接続先のデータベース名が接続セッションのアクセス許可に寄与するためです。
テストデータベースはまだ存在しないため、djangoは、テストデータベースを作成するために、最初に通常のsettings.DATABASE_NAMEを使用して接続する必要があります。
したがって、次のように機能します。
- Djangoのテストランナーは、バックエンド固有のデータベースハンドラーに渡されます
- バックエンド固有のデータベースハンドラーには、
create_test_db
これは通常の設定を使用してデータベースに接続します。プレーンを使用してこれを行いますcursor = self.connection.cursor()
コマンド。これは明らかに通常の設定値を使用します。これは、この時点で存在していることがわかっているのはそれだけだからです。 - データベースに接続すると、バックエンド固有のハンドラーが
CREATE DATABASE
新しいテストデータベースの名前を指定したコマンド。 - バックエンド固有のハンドラーは接続を閉じてから、テストランナーに戻ります。テストランナーは通常のハンドラーを交換します。
settings.DATABASE_NAME
test_database_nameの場合 - その後、テストは通常どおり実行されます。以降のすべての呼び出し
connection.cursor()
通常の設定モジュールを使用しますが、そのモジュールのデータベース名はスワップアウトされています - 最後に、テストランナーは、バックエンド固有のハンドラーを呼び出した後、古いデータベース名を復元します。
destroy_test_db
関数。
興味がある場合は、主要部分に関連するコードはdjango.db.backends.creationにあります。 _create_test_db
関数。
私はそれが可能だろうと思いますDjangoの設計者は、すべてのDBが接続文字列に現在のデータベース名を必要とするわけではないため、データベースごとに例外を作成しますが、それには少しリファクタリングが必要になります。今、 create_test_db
関数は実際には次のいずれかにあります backend
基本クラス、およびほとんどの実際のバックエンドハンドラーはそれをオーバーライドしないため、ダウンストリームにプッシュして各バックエンドで複製するためのかなりの量のコードがあります。