J'ai beaucoup d'objets à enregistrer 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 les sauvegarder toutes.
Actuellement, j'ai quelque chose comme ça:
for item in items:
object = MyModel(name=item.name)
object.save()
Je me demande si je peux enregistrer 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 seule transaction?
django
django-models
Alexis Métaireau
la source
la source
Réponses:
dès le développement de django, il existe en
bulk_create
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. consultez la documentation djangola source
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()
ne déclenche aucun signal. Je me demande pourquoi.Utilisez la
bulk_create()
méthode. C'est désormais standard dans Django.Exemple:
Entry.objects.bulk_create([ Entry(headline="Django 1.0 Released"), Entry(headline="Django 1.1 Announced"), Entry(headline="Breaking: Django is awesome") ])
la source
a travaillé pour moi pour utiliser la gestion manuelle 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 masse d'une base de données `` native '', mais cela vous permet d'éviter / de réduire les opérations de transport / orms / requête SQL analyser les coûts
la source
commit_on_success
plus. Vous devriez utilisertransaction.atomic()
See: stackoverflow.com/questions/21861207/…Voici comment créer en bloc des entités à partir d'un fichier séparé par colonne, en laissant de côté toutes les routines sans guillemets et sans échappement:
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)
la source
pour une implémentation sur 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 d'éléments à x et crée un enregistrement de base de données si nécessaire.
Documentation Lambda
la source
lambda
doit êtremap
terminéitems
:map(lambda name: MyModel.objects.get_or_create(name = name), items)
L'utilisation de create provoquera une requête par nouvel élément. Si vous souhaitez réduire le nombre de requêtes INSERT, vous devrez utiliser autre chose.
J'ai eu un certain succès en utilisant l'extrait Bulk Insert, même si l'extrait est assez ancien. Il y a peut-être des changements nécessaires pour qu'il fonctionne à nouveau.
http://djangosnippets.org/snippets/446/
la source
Consultez ce billet de blog sur le module bulkops .
Sur mon application django 1.3, j'ai connu une accélération significative.
la source
Le moyen le plus simple consiste à utiliser la
create
méthode Manager, qui crée et enregistre l'objet en une seule étape.for item in items: MyModel.objects.create(name=item.name)
la source
name
des entrées uniques et dupliquées sont possibles, ce serait une bonne idée à utiliserget_or_create
.