2012-09-18 9 views

risposta

19

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() 
+4

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. –

+0

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 :) –

6

Per aggiungere i valori UUID a tutti i record esistenti prima è necessario assicurarsi che il proprio modello ha l'UUID archiviato con blank=True, null=True

Quindi eseguire il comando schemamigration con sud e quindi aprire il file di migrazione risultante. e quindi modificare il file di migrazione con il seguente come mostrato in questo post

Citazione:

avrete bisogno di importare i seguenti importazione uuid

Alla fine degli attaccanti() funzione aggiungere le seguenti avanti DEF (auto, ORM):

... 
for a in MyModel.objects.all(): 
    a.uuid = u'' + str(uuid.uuid1().hex) 
    a.save() 

Come ha dichiarato che ciclo volontà throu gh istanze esistenti e aggiungere un uuid ad esso come parte della migrazione.

Problemi correlati