per la seguente classe di esempio:
from django_extensions.db.fields import UUIDField
def MyClass:
uuid = UUIDField(editable=False, blank=True)
name = models.CharField()
Se stai usando Sud, creare una migrazione dei dati:
python ./manage.py datamigration <appname> --auto
e quindi utilizzare il codice riportato di seguito per aggiornare la migrazione con la logica specifica per aggiungere un 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()
È possibile creare diversi tipi di UUID, ogni generato differe nte me nte. il uuid.py module in Django-extensions ha l'elenco completo dei tipi di UUID che è possibile creare.
È importante notare che se si esegue questa migrazione in un ambiente con molti oggetti, è possibile che scada il tempo (ad esempio, se si utilizza il fabric da distribuire). Per gli ambienti di produzione sarà necessario un metodo alternativo di compilazione dei campi già esistenti.
È possibile che si esaurisca la memoria mentre si tenta di eseguire questa operazione su un numero elevato di oggetti (ci siamo trovati a corto di memoria e con la distribuzione non riuscita con oltre 17.000 oggetti).
Per aggirare questo, è need to create a custom iterator nella migrazione (o incollarlo dove è veramente utile, e fare riferimento ad esso nella migrazione). Sarebbe simile a questa:
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()
E poi i tuoi migrazioni cambierebbero di simile a questa:
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()
Anche se i downvoters non possono vederlo; Lo dirò comunque: se mi hai downvoted perché ho offerto un premio e poi risposto alla domanda, sii avvisato che non posso ottenere comunque la mia ricompensa, quindi non sto rispondendo alla domanda per la taglia. Lo sto rispondendo perché qualche tempo dopo aver posato la taglia, dovevo farlo comunque, così ho pensato di condividere con tutti come l'ho fatto. –
Ciao George, personalmente ho downvoted per quella ragione, ma sono nuovo per accatastare e non sapevo che non si potesse riavere indietro la propria ricompensa. Ho ritirato il mio downvote e dopo aver visto il tuo profilo puoi vedere che sei un membro impegnato, intelligente e utile dello stack :) –