web-dev-qa-db-fra.com

Créez en bloc des objets de modèle dans django

J'ai beaucoup d'objets à sauvegarder dans la base de données et je souhaite donc créer des instances de modèle avec cela.

Avec Django, je peux créer toutes les instances de modèles, avec MyModel(data), puis je veux toutes les enregistrer.

Actuellement, j'ai quelque chose comme ça:

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

Je me demande si je peux sauvegarder directement une liste d'objets, par exemple:

objects = []
for item in items:
    objects.append(MyModel(name=item.name))
objects.save_all()

Comment sauvegarder tous les objets en une transaction?

77
Alexis Métaireau

à partir du Django version de développement 1.4, il existe bulk_create en tant que méthode de gestion d'objets qui prend en entrée un tableau d'objets créés à l'aide du constructeur de classe. check out Django docs

81
ecbtln

Utilisez la méthode bulk_create() . C'est standard dans Django maintenant.

Exemple:

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

Voici comment créer en bloc des entités à partir d'un fichier séparé par des colonnes, en laissant de côté toutes les routines sans guillemets et sans échappements:

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)
4
Ivan Klass

a travaillé pour moi à utiliser le traitement manuel des transactions pour la boucle (postgres 9.1):

from Django.db import transaction
with transaction.commit_on_success():
    for item in items:
        MyModel.objects.create(name=item.name)

en fait, ce n'est pas la même chose que l'insertion en bloc d'une base de données 'native', mais cela vous permet d'éviter/réduire le transport/orms opérations/requête SQL analyser les coûts

4
eviltnan

Utiliser create entraînera une requête par nouvel élément. Si vous souhaitez réduire le nombre de requêtes INSERT, vous devez utiliser autre chose.

L'utilisation de l'extrait d'insertion en bloc a été un succès, même si l'extrait est assez ancien. Certains changements sont peut-être nécessaires pour que cela fonctionne à nouveau.

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

2
OmerGertel

pour une implémentation à une seule ligne, vous pouvez utiliser une expression lambda dans une carte

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

Ici, lambda fait correspondre chaque élément de la liste à x et crée un enregistrement de base de données si nécessaire.

Documentation Lambda

2
FallenAngel

Découvrez ce billet de blog sur le module bulk .

Sur mon Django 1.3, j’ai connu une accélération significative.

2
MrJ