2016-05-12 6 views
0

djangoの移行(django v1.7 +)を使用してデータベースを変更しました。 データベースに存在するデータは無効です。Djangoデータベースの移行をunittestする方法は?

基本的には、ユニットテストの中で、移行前のデータベースを構築し、データを追加し、移行を適用し、すべてがスムーズに行われたことを確認したいと思います。

どのようにしない:unittestの

をロードする際

  1. が新しい移行を控える私はsettings.MIGRATION_MODULESをオーバーライドについてsome stuffが見つかりましたが、それを使用する方法を考え出すことができませんでした。私がexecutor.loader.applied_migrationsを調べると、まだすべてがリストされています。私が新しい移行を防ぐ唯一の方法は、ファイルを実際に削除することでした。私が使用できる解決策ではありません。

  2. 我々は、これは非常に簡単である必要があり、移行を防ぐことができる場合(旧モデルを使用して)unittestのデータベースに

    をレコードを作成します。

  3. myModel.object.create(...)

    は、私はおそらく私が見つけたことを、今、これをうまくすることができると思うの移行を適用test_executor:計画移行ファイルを指して、それを実行に設定されていますか?ええ、そうですか?ちょうど移行前に作成されたインスタンスを取得し、それを確認します。データベース内の古いデータは、今、私はこれはかなり簡単なはず期待して、再び新しいモデル

    に一致する:-Dのための任意のコード

  4. 確認を得ましたすべての正しい方法で変更されています。

だから、挑戦は本当にただ、最新の移行スクリプトを塗布した後、我々は準備ができたら、それを適用するからunittestのを防ぐ​​方法を働いていますか?


おそらく私は間違ったアプローチをしていますか?フィクスチャを作成して、最終的にすべてが良いことを確認するだけですか? Fixtureは、移行が適用される前にロードされるのですか、またはすべて完了した後にロードされますか?私は、多分?その後、前方一つ一つをロールバック、特定の状態にそれをロールすることができましたMigrationExecutorを使用して.migrateで特定の移行を選び出すことで


。しかし、それは疑問を浮き彫りにしている。現在、実際のALTER TABLE命令がないために、sqliteを回避しています。ジュリーはまだ出ている。私たちは、テストのために、移行を無視するsettings_test.pyに次のコードを使用している

+0

この場合、バージョン管理システムが役立つ場合があります。古い移行と新しい移行を持つ2つのブランチを維持する必要があります。これは、設定やコードなどが異なるプロダクション環境や開発環境用に別のブランチがある場合と似ています。 – xyres

+0

@xyresはさまざまなコミットをチェックアウトしますが、一般的にunittestの範囲には入りません。 –

答えて

0

:ここ

MIGRATION_MODULES = dict(
    (app.split('.')[-1], '.'.join([app, 'nonexistent_django_migrations_module'])) 
    for app in INSTALLED_APPS 
) 

アイデアのアプリケーションのどれもがnonexistent_django_migrations_moduleフォルダを持っていないので、Djangoは単に何の移行を見つけていないだろうということで。

+0

Thx。これは移行を見つけることができないように機能しますが、あまり役に立たないようです。どうすれば移行をテストできますか? –

+0

明らかに私はあなたの質問を誤解しています - 実際には移行ロジック自体をテストしたいのですか? – zsepi

+0

はい...移行前のデータベースを作成して移行し、その結果をテストするテスト。 –

0

私は、現在のデータベーススキーマと始まるからunittestのを阻止することができませんでしたが、私は移行の歴史の中で、以前のポイントに戻すことは非常に簡単です見つけた:

ある「0014_nulls_permitted」どこ

from django.db.migrations.executor import MigrationExecutor 
executor.migrate([("workflow_engine", "0014_nulls_permitted")]) 
executor.loader.build_graph() 

NBの移行ディレクトリ内のファイル...:executor.migrateの呼び出し間executor.loader.build_graphを実行するには、migraを完了するのに非常に重要な部分であると思われます私がORMを経由してモデルのインスタンスを作成し

print [x[1] for x in sorted(executor.loader.applied_migrations)] 

[u'0001_initial', u'0002_fix_foreignkeys', ... u'0014_nulls_permitted'] 

、データベースがした保証:1は、現在のようなものを確認することができますデータベースに適用される

移行を期待するかもしれないようションとなっ事が振る舞います古い状態でSQLを直接実行すると、次のようになります。

job = Job.objects.create(....) 
from django.db import connection 
cursor = connection.cursor() 
cursor.execute('UPDATE workflow_engine_job SET next_job_state=NULL') 

今私は古い状態のデータベースを持っていることを知っていて、転送の移行をテストできます。 0015がデフォルト値にすべてNULLのフィールドを変換するデータベースを介して行く

executor.migrate([("workflow_engine", "0016_nulls_banished")]) 
executor.loader.build_graph() 

移行:だから0016_nulls_banishedは、マイグレーションファイルです。移行012はスキーマを変更します。いくつかのプリントステートメントを散らばって、起こっていると思われることが起こっていることを確認することができます。

これで、移行が正常に実行されたことを確認できます。この場合、データベースにNULLが残っていないことを確認します。

jobs = Job.objects.all() 
self.assertTrue(all([j.next_job_state is not None for j in jobs])) 
関連する問題