2012-09-18 16 views

Respuesta

19

Para la siguiente clase de muestra:

from django_extensions.db.fields import UUIDField 

def MyClass: 
    uuid = UUIDField(editable=False, blank=True) 
    name = models.CharField() 

Si está utilizando Sur, cree una migración de datos:

python ./manage.py datamigration <appname> --auto 

Y a continuación, utilizar el siguiente código para actualizar la migración con la lógica específica para agregar 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() 

Puede crear diferentes tipos de UUID, cada uno generado ntly. el uuid.py module in Django-extensions tiene la lista completa de los tipos de UUID que puede crear.

Es importante tener en cuenta que si ejecuta esta migración en un entorno con muchos objetos, tiene el potencial de tiempo de espera (por ejemplo, si usa fabric para implementar). Se requerirá un método alternativo para rellenar los campos ya existentes para los entornos de producción.

Es posible que se agote la memoria al tratar de hacer esto con una gran cantidad de objetos (nos encontramos sin memoria y la implementación falla con más de 17,000 objetos).

Para solucionar esto, need to create a custom iterator en su migración (o pegarlo donde sea realmente útil, y consultarlo en su migración). Se vería algo como esto:

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

Y a continuación, sus migraciones cambiarían a tener este aspecto:

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

Aunque los downvoters no pueden ver esto; Lo diré de todos modos: si me has votado negativamente porque ofrecí una recompensa y luego respondí la pregunta, ten en cuenta que no puedo recuperar mi recompensa de todos modos, así que no estoy respondiendo la pregunta por la recompensa. Lo estoy respondiendo porque un tiempo después de que posé la recompensa, tuve que hacerlo de todos modos, así que pensé en compartir con todos cómo lo hice. –

+0

Hola George, personalmente he votado negativamente por esa razón, pero soy nuevo en la pila y no sabía que no puedes recuperar tu propia recompensa. He recuperado mi voto negativo y después de mirar tu perfil puedo ver que eres un miembro comprometido, inteligente y útil de la pila :) –

6

Para agregar valores UUID a todos los registros existentes primero tendrá que asegurarse de que su modelo tiene el UUID archivado con blank=True, null=True

A continuación, ejecute el comando schemamigration con south y luego abra el archivo de migración resultante. y luego editar el archivo de migración con la siguiente como se muestra en este post

Cita:

que necesitará para importar los siguientes uuid importación

Al final de los delanteros() Función añadir las siguientes delanteros def (auto, ORM):

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

Como se ha dicho que la voluntad de bucle throu gh instancias existentes y agregarle un uuid como parte de la migración.

Cuestiones relacionadas