これを行う最も簡単な方法は、列を変更するスキーマ移行を作成してから、データ移行を作成して値を正しく入力することです。使用しているデータベースによっては、少し異なる方法でこれを行う必要があります。
スクライト
Sqlite の場合、リレーションにセンチネル値を追加し、datamigration を使用して問題なく入力できます。
0001_schema_migration_add_foreign_key_to_new_model_from_existing_model.py
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
db.add_column('existing_model_table', 'new_model',
self.gf('django.db.models.fields.related.ForeignKey')(default=0, to=orm['appname.new_model']), keep_default=False)
0002_data_migration_for_new_model.py
:
class Migration(DataMigration):
def forwards(self, orm):
for m in orm['appname.existing_model'].objects.all():
m.new_model = #custom criteria here
m.save()
これで問題なく動作します。
Postgres と MySQL
MySql では、有効なデフォルトを指定する必要があります。0
が実際に有効な Foreignkey でない場合は、そのことを示すエラーが表示されます。
デフォルトの 1 にすることもできますが、それが有効な外部キーではない場合があります (環境が異なり、一部の環境が他のデータベースに公開されているため、私に起こりました。そのため、ID はめったに一致しません (クロス神が意図したように、データベースの識別)。
2 番目の問題は、South と MySQL がうまく連携しないことです。部分的には、MySQL には DDL トランザクションの概念がないためです。
必然的に直面するいくつかの問題 (上記のエラーやorm
、SchemaMigration 内の項目を としてマークするよう求める South からのエラーを含む) を回避するには、上記のスクリプトを次no-dry-run
のように変更する必要があります。0001
0001_schema_migration_add_foreign_key_to_new_model_from_existing_model.py
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
id = 0
if not db.dry_run:
new_model = orm['appname.new_model'].objects.all()[0]
if new_model:
id = new_model.id
db.add_column('existing_model_table', 'new_model',
self.gf('django.db.models.fields.related.ForeignKey')(default=id, to=orm['appname.new_model']), keep_default=False)
0002_data_migration_for_new_model.py
その後、通常どおりファイルを実行できます。
上記と同じ例を Postgres と MySql に使用することをお勧めします。最初の例では、Postgres で何の問題も覚えていませんが、2 番目の例は両方で動作することは確かです (テスト済み)。