Tengo un modelo de 5 columnas con más de 10 000 líneas de datos. Ahora quiero actualizar una columna de todas las líneas en función de otros valores de columna.
En mi opinión, para su escenario "Quiero actualizar una columna de todas las líneas en función de los valores de otras columnas". , la mejor opción es usar la actualización condicional
Supongamos este modelo:
class Person(models.Model): f1 = models.IntegerField() f2 = models.IntegerField() f3 = models.IntegerField() f4 = models.IntegerField()Puedes actualizarlo de esta manera:
rom django.db.models import F, When, Case new_value = Case( When(f1__gte=F('f2'), then=F('f1')), default=F('f2') ) Person.objects.update(f3=new_value)Esto plantea una simple declaración de SQL de actualización:
>>> import logging >>> l = logging.getLogger('django.db.backends') >>> l.setLevel(logging.DEBUG) >>> l.addHandler(logging.StreamHandler()) >>> Person.objects.update(f3=c) (0.000) UPDATE "tt_person" SET "f3" = CASE WHEN ("tt_person"."f1" >= "tt_person"."f2") THEN "tt_person"."f1" ELSE "tt_person"."f2" END; args=() 0La función django lista para usar para realizar actualizaciones masivas es bulk_update() . Aquí un ejemplo:
myModel = MyModel.objects.all() for l in myModel: if c1=='ChkVal1' and c2 < c3: c4='Value 1' elif c1=='ChkVal2' and c2 b> c3: c4='Value 2' else c4='Value 3' MyModel.objects.bulk_update(myModel, update_fields = ['c4'])Recuerde, citando documentos:
- No puede actualizar la clave principal del modelo.
- No se llama al método save() de cada modelo y no se envían las señales pre_save y post_save.
- Si actualiza una gran cantidad de columnas en una gran cantidad de filas, el SQL generado puede ser muy grande. Evite esto especificando un tamaño de lote adecuado.
- La actualización de campos definidos en ancestros de herencia de varias tablas incurrirá en una consulta adicional por ancestro.
- Cuando un lote individual contiene duplicados, solo la primera instancia de ese lote generará una actualización.