一部のモデルにUUIDフィールドを追加してから、Southに移行しました。作成する新しいオブジェクトには、UUIDフィールドが正しく設定されています。しかし、すべての古いデータのUUIDフィールドはnullです。データベースに既に存在するデータの後にUUIDフィールドが追加されました。既存のデータのUUIDフィールドに値を設定する方法はありますか?
既存のデータにUUIDデータを設定する方法はありますか?次のサンプルクラスの
一部のモデルにUUIDフィールドを追加してから、Southに移行しました。作成する新しいオブジェクトには、UUIDフィールドが正しく設定されています。しかし、すべての古いデータのUUIDフィールドはnullです。データベースに既に存在するデータの後にUUIDフィールドが追加されました。既存のデータのUUIDフィールドに値を設定する方法はありますか?
既存のデータにUUIDデータを設定する方法はありますか?次のサンプルクラスの
:
from django_extensions.db.fields import UUIDField
def MyClass:
uuid = UUIDField(editable=False, blank=True)
name = models.CharField()
あなたが南を使用している場合は、データの移行を作成します。その後、
python ./manage.py datamigration <appname> --auto
と特定のロジックでの移行を更新するには、次のコードを使用しますUUIDを追加するには:
from django_extensions.utils import uuid
def forwards(self, orm):
for item in orm['mypp.myclass'].objects.all():
if not item.uuid:
item.uuid = uuid.uuid4() #creates a random GUID
item.save()
def backwards(self, orm):
for item in orm['mypp.myclass'].objects.all():
if item.uuid:
item.uuid = None
item.save()
異なる種類のUUIDを作成できますntly。 uuid.py module in Django-extensionsには、作成できるUUIDの種類の完全なリストがあります。
オブジェクトの数が多い環境でこの移行を実行すると、タイムアウトする可能性があることに注意してください(たとえば、ファブリックを使用して配置する場合など)。実環境では、すでに存在するフィールドを埋める別の方法が必要になります。
多数のオブジェクトに対してこれを実行しようとしている間にメモリが不足する可能性があります(メモリが不足し、デプロイメントが17,000+オブジェクトで失敗していることがわかりました)。
この問題を回避するには、移行時にneed to create a custom iteratorを使用します(または、実際に便利な場所に貼り付け、移行時に参照してください)。それはこのようなものになります。
def queryset_iterator(queryset, chunksize=1000):
import gc
pk = 0
last_pk = queryset.order_by('-pk')[0].pk
queryset=queryset.order_by('pk')
if queryset.count() < 1
return []
while pk < last_pk:
for row in queryset.filter(pk__gt=pk)[:chunksize]:
pk = row.pk
yield row
gc.collect()
をしてからの移行は、このように見えるように変更します
class Migration(DataMigration):
def forwards(self, orm):
for item in queryset_iterator(orm['myapp.myclass'].objects.all()):
if not item.uuid:
item.uuid = uuid.uuid1()
item.save()
def backwards(self, orm):
for item in queryset_iterator(orm['myapp.myclass'].objects.all()):
if item.uuid:
item.uuid = None
item.save()
まず、あなたのモデルが持っていることを確認する必要がありますすべての既存のレコードにUUID値を追加するにはblank=True, null=True
で提出されたUUID
次に、southと一緒にschemamigrationコマンドを実行して、結果の移行ファイルを開きます。 そして、このpost
見積もりに示すように、次を使用して移行ファイルを編集します。
あなたが前方に()関数の最後に次のimport UUID
をインポートする必要があります(自己、ORM)前方DEF次の行を追加しますように述べている。意志ループthrouとして
... for a in MyModel.objects.all(): a.uuid = u'' + str(uuid.uuid1().hex) a.save()
既存のインスタンスを表示し、移行の一部としてuuidを追加します。
Djangoのドキュメントにこの正確な質問に対するexcellent, updated answer for Django 1.9があります。
多くの時間を節約できました。
ダウンローダはこれを見ることはできませんが、私はとにかくそれを言うでしょう:もし私が恩恵を申し立てて、私の恩返しを得ることができないと言われたら、恩恵を申し立てたので、あなたは私を落胆させました。私は恩恵を訴えた後、しばらくしなければならなかったので、私はそれに答えています。 –
こんにちはジョージ、私は個人的にその理由でdownvotedが、私は積み重ねが新しく、自分の賞金を得ることができないことを知らなかった。私は私のdownvoteを取り戻して、あなたのプロフィールを見た後にあなたがスタックのコミットされた、スマートで有用なメンバーであることがわかります:) –