У меня есть много объектов для сохранения в базе данных, поэтому я хочу создать экземпляры модели с этим.
С помощью django я могу создать все экземпляры моделей с помощью MyModel(data)
, а затем я хочу сохранить их все.
В настоящее время у меня есть что-то вроде этого:
for item in items:
object = MyModel(name=item.name)
object.save()
Мне интересно, могу ли я сохранить список объектов напрямую, например:
objects = []
for item in items:
objects.append(MyModel(name=item.name))
objects.save_all()
Как сохранить все объекты за одну транзакцию?
django
django-models
Алексис Метеро
источник
источник
Ответы:
на момент разработки django существует
bulk_create
метод диспетчера объектов, который принимает на вход массив объектов, созданных с помощью конструктора класса. проверить django docsисточник
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()
не вызывает никаких сигналов. Интересно, почему.Используйте
bulk_create()
метод. Теперь это стандарт в Django.Пример:
Entry.objects.bulk_create([ Entry(headline="Django 1.0 Released"), Entry(headline="Django 1.1 Announced"), Entry(headline="Breaking: Django is awesome") ])
источник
работал у меня, чтобы использовать ручную обработку транзакций для цикла (postgres 9.1):
from django.db import transaction with transaction.commit_on_success(): for item in items: MyModel.objects.create(name=item.name)
на самом деле это не то же самое, что и массовая вставка «родной» базы данных, но позволяет избежать / уменьшить затраты на транспорт / операции orms / анализ запросов sql
источник
commit_on_success
больше нет. Вы должны использоватьtransaction.atomic()
См: stackoverflow.com/questions/21861207/...Вот как массово создавать объекты из файла с разделителями столбцов, оставляя в стороне все процедуры отмены кавычек и отмены экранирования:
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)
источник
для однострочной реализации вы можете использовать лямбда-выражение в карте
map(lambda x:MyModel.objects.get_or_create(name=x), items)
Здесь лямбда сопоставляет каждый элемент в списке элементов с x и при необходимости создает запись в базе данных.
Лямбда-документация
источник
lambda
надоmap
боротьсяitems
:map(lambda name: MyModel.objects.get_or_create(name = name), items)
Использование create вызовет один запрос для каждого нового элемента. Если вы хотите уменьшить количество запросов INSERT, вам нужно будет использовать что-то еще.
У меня был некоторый успех, используя фрагмент Bulk Insert, хотя он довольно старый. Возможно, потребуются некоторые изменения, чтобы он снова заработал.
http://djangosnippets.org/snippets/446/
источник
Посмотрите это сообщение в блоге о модуле Bulkops .
В моем приложении django 1.3 я испытал значительное ускорение.
источник
Самый простой способ - использовать
create
метод Manager, который создает и сохраняет объект за один шаг.for item in items: MyModel.objects.create(name=item.name)
источник
name
уникальны и возможны повторяющиеся входные данные, было бы неплохо использоватьget_or_create
.