Tengo muchos objetos para guardar en la base de datos, por lo que quiero crear instancias de modelo con eso.
Con django, puedo crear todas las instancias de modelos, con MyModel(data)
, y luego quiero guardarlas todas.
Actualmente, tengo algo así:
for item in items:
object = MyModel(name=item.name)
object.save()
Me pregunto si puedo guardar una lista de objetos directamente, por ejemplo:
objects = []
for item in items:
objects.append(MyModel(name=item.name))
objects.save_all()
¿Cómo guardar todos los objetos en una transacción?
django
django-models
Alexis Métaireau
fuente
fuente
Respuestas:
A partir del desarrollo de django, existe
bulk_create
un método de administrador de objetos que toma como entrada una matriz de objetos creados usando el constructor de clases. echa un vistazo a los documentos de djangofuente
bulk_create
: docs.djangoproject.com/en/dev/ref/models/querysets/#bulk-createIf the model’s primary key is an AutoField it does not retrieve and set the primary key attribute, as save() does, unless the database backend supports it (currently only PostgreSQL).
bulk_create()
no activa ninguna señal. Me pregunto porque.bulk_create()
Método de uso . Ahora es estándar en Django.Ejemplo:
Entry.objects.bulk_create([ Entry(headline="Django 1.0 Released"), Entry(headline="Django 1.1 Announced"), Entry(headline="Breaking: Django is awesome") ])
fuente
Me funcionó para usar el manejo manual de transacciones para el bucle (postgres 9.1):
from django.db import transaction with transaction.commit_on_success(): for item in items: MyModel.objects.create(name=item.name)
de hecho, no es lo mismo que la inserción masiva de la base de datos 'nativa', pero le permite evitar / disminuir el transporte / operaciones de orms / costos de análisis de consultas SQL
fuente
commit_on_success
. Debe usartransaction.atomic()
Ver: stackoverflow.com/questions/21861207/…A continuación, se explica cómo crear entidades de forma masiva a partir de archivos separados por columnas, dejando de lado todas las rutinas sin comillas y sin escape:
SomeModel(Model): @classmethod def from_file(model, file_obj, headers, delimiter): model.objects.bulk_create([ model(**dict(zip(headers, line.split(delimiter)))) for line in file_obj], batch_size=None)
fuente
para una implementación de una sola línea, puede usar una expresión lambda en un mapa
map(lambda x:MyModel.objects.get_or_create(name=x), items)
Aquí, lambda hace coincidir cada elemento en la lista de elementos ax y crea un registro de base de datos si es necesario.
Documentación de Lambda
fuente
lambda
tiene quemap
pasaritems
:map(lambda name: MyModel.objects.get_or_create(name = name), items)
El uso de crear generará una consulta por cada elemento nuevo. Si desea reducir la cantidad de consultas INSERT, deberá usar algo más.
He tenido cierto éxito con el fragmento de inserción masiva, aunque el fragmento es bastante antiguo. Quizás se requieran algunos cambios para que vuelva a funcionar.
http://djangosnippets.org/snippets/446/
fuente
Consulte esta publicación de blog sobre el módulo bulkops .
En mi aplicación django 1.3, he experimentado una aceleración significativa.
fuente
La forma más sencilla es utilizar el
create
método Manager, que crea y guarda el objeto en un solo paso.for item in items: MyModel.objects.create(name=item.name)
fuente
name
es único y son posibles entradas duplicadas, sería una buena idea utilizarloget_or_create
.