4

私はしばらくの間、南でdjangoアプリを開発していて、一種の緩い継続的デプロイを行っています。最初の移行の直後に、次のようなデータ移行をいくつか行いました。

def forwards(self, orm):                                                   
    from django.core.management import call_command                        
    call_command("loaddata", "#######.json")    

当時は何も考えていませんでした。データベースに手動でデータを入力し、それをすべてフィクスチャにダンプするのは簡単でした。そして、ついにいくつかの単体テストを書いたとき、私は次のようなエラーを受け取り始めました:

Creating test database for alias 'default'...
Problem installing fixture '/home/axel/Workspace/02_ereader_blast/content/fixtures/99_deals.json': Traceback (most recent call last):
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/core/management/commands/loaddata.py", line 196, in handle
    obj.save(using=using)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/core/serializers/base.py", line 165, in save
    models.Model.save_base(self.object, using=using, raw=True)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/db/models/base.py", line 551, in save_base
    result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/db/models/manager.py", line 203, in _insert
    return insert_query(self.model, objs, fields, **kwargs)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/db/models/query.py", line 1593, in insert_query
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 910, in execute_sql
    cursor.execute(sql, params)
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 52, in execute
    return self.cursor.execute(query, args)
DatabaseError: Could not load content.BookDeal(pk=1): column "entry_id" of relation "content_bookdeal" does not exist
LINE 1: INSERT INTO "content_bookdeal" ("id", "book_id", "entry_id",...
                                                         ^


Installed 19 object(s) from 1 fixture(s)
Problem installing fixture '/home/axel/Workspace/02_ereader_blast/content/fixtures/99_deals_entries.json': Traceback (most recent call last):
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/core/management/commands/loaddata.py", line 190, in handle
    for obj in objects:
  File "/home/axel/Workspace/02_ereader_blast/venv/local/lib/python2.7/site-packages/django/core/serializers/json.py", line 47, in Deserializer
    raise DeserializationError(e)
DeserializationError: Entry has no field named 'book_deals'

私の知る限り、loaddataコマンドは、当時の南の状態ではなく、最新のモデルを使用しています。それ以降、モデルを大幅に変更したため、現在のモデルは古いデータを無効として解釈しています。

だから私の質問は:

  • これが起こらないように、将来のデータ移行を設定するための最良の方法は何ですか?
  • どうすればこの状況から抜け出し、ベストプラクティスの土地に持ち込むことができますか?
4

2 に答える 2

2

私はこのstackoverflowの質問のおかげで解決策を見つけました:

後方移行後にフィクスチャからデータをロードするdjango/loaddataはデータベーススキーマではなくモデルスキーマを使用しています

一番上の回答で述べたように、loaddataコマンドがモデルを取得する場所に非常にエレガントにパッチを適用するスニペットを使用しました。

これらのデータ移行のフリーズを拡大して、直接ではなく、ormから必要なすべてのモデルにアクセスできるようにする必要があったことに注意してください。

これは問題を解決する正しい方法のように感じます。

于 2013-02-22T21:55:19.940 に答える
0

私のアプローチは、完全なハック/南部の悪用/最悪の種類の実践である可能性が非常に高いと思います。ただし... djangoモデルがデータテーブルに準拠していることがわかっている場合。私は新たなスタートアプローチに行くかもしれません:

  1. 関連する移行フォルダーの名前を変更 (または削除) します。
  2. south_migrationhistory データ テーブルで、新しいスタートを作成しようとしているアプリに関連付けられているすべてのエントリを削除します。
  3. python manage.py convert_to_south app-name.
  4. すべてがうまくいくはずです。

データ テーブルが標準的で、django モデルが適切でない場合、django モデルをデータ テーブルに適合させる方法は次のとおりです。

python manage.py inspectdb > inspectdb.py

これで、モデルの django コードの 2 つのバージョンを比較して、それらを一致させることができます。これにより、フレッシュ スタート シーケンスを実行できます。

于 2013-02-22T21:07:23.603 に答える