2010-08-31 31 views
49

Tengo una gran cantidad de objetos para guardar en la base de datos, por lo que quiero crear instancias de modelo con eso.Creación masiva de objetos de modelo en django

Con django, puedo crear todas las instancias de modelos, con MyModel(data), y luego quiero guardarlas todas.

Actualmente, tengo algo por el estilo:

for item in items: 
    object = MyModel(name=item.name) 
    object.save() 

Me pregunto si puedo guardar una lista con los objetos, 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?

+0

parece que la pelota está rodando en la implementación de una solución para este https://code.djangoproject.com/ticket/19527 – DanH

+1

preguntando por list.save_all? Casi podría responderse a sí mismo simplemente parafrasear esa pregunta y usar 2 primeras palabras de su pregunta de tema. –

Respuesta

60

como de la versión de desarrollo django 1.4, existe bulk_create como un método administrador de objetos que toma como entrada una matriz de objetos creado usando el constructor de la clase. echa un vistazo a django docs

+11

documentos de Django para' bulk_create': https://docs.djangoproject.com/en/dev/ref/models/querysets/#bulk-create – funkotron

+1

Pero recuerda que bulk_create tiene algunas limitaciones, como que no crea claves primarias si es un AutoField que save() hace automáticamente. –

+0

@HiteshGarg, ¿Eso sigue siendo cierto ahora? –

-17

La manera más fácil es utilizar el método de administrador create, que crea y guarda el objeto en un solo paso.

for item in items: 
    MyModel.objects.create(name=item.name) 
+0

+1. Si 'name' es único y las entradas duplicadas son posibles, sería una buena idea usar' get_or_create'. –

+12

¿Cómo responde esto la pregunta? Model.objects.create es equivalente a object = MoModel (..) object.save(). Y esto no lo hace en una transacción ... – automagic

2

para una sola aplicación de línea, se puede utilizar una expresión lambda en un mapa

map(lambda x:MyModel.objects.get_or_create(name=x), items) 

Aquí, lambda coincide con cada elemento de la lista de elementos a X, crea un registro de base de datos si es necesario.

Lambda Documentation

+0

Probablemente quiera mencionar que el 'lambda' tiene que ser' map' ped sobre 'items':' map (nombre lambda: MyModel.objects.get_or_create (name = name), artículos) ' –

+0

Ja, esa es otra forma en que trato de decir (: – FallenAngel

2

el uso de crear provocará una consulta por cada nuevo artículo. Si desea reducir el número de consultas INSERT, necesitará usar algo más.

Tuve cierto éxito con el fragmento de inserción masiva, aunque el fragmento es bastante antiguo. Quizás haya algunos cambios necesarios para que funcione nuevamente.

http://djangosnippets.org/snippets/446/

2

Echa un vistazo a esta publicación en el blog en el módulo bulkops.

En mi aplicación django 1.3, he experimentado una aceleración significativa.

4

trabajaron para mí utilizar transacción manual de manipulación 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 la misma, como inserción masiva base de datos de 'nativo', pero le permite evitar/descrease transporte/operaciones ORMs/consulta SQL analizar los costos

2

Aquí es cómo granel a crear entidades de la columna de archivos separados, dejando a un lado todas las unquoting y ONU-escapar rutinas:

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

Utilice el método bulk_create().Es norma en Django ahora: Official Django Documentation bulk_create()

Ejemplo:

>>> Entry.objects.bulk_create([ 
...  Entry(headline="Django 1.0 Released"), 
...  Entry(headline="Django 1.1 Announced"), 
...  Entry(headline="Breaking: Django is awesome") 
... ]) 
+0

Modificado en Django 1.10: Soporte para establecer claves primarias en objetos creado usando bulk_create() cuando se agregó PostgreSQL. –

Cuestiones relacionadas