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