Существует ли более эффективный путь к тому, чтобы сделать это?
for item in item_list:
e, new = Entry.objects.get_or_create(
field1 = item.field1,
field2 = item.field2,
)
С помощью get_or_create (или даже create) нельзя выполнять приличную массовую вставку (или даже создать), и нет API, чтобы легко это сделать.
Если ваша таблица достаточно проста, чтобы создавать строки с помощью необработанного SQL не слишком сложно, это не так уж сложно; что-то вроде:
INSERT INTO site_entry (field1, field2)
(
SELECT i.field1, i.field2
FROM (VALUES %s) AS i(field1, field2)
LEFT JOIN site_entry as existing
ON (existing.field1 = i.field1 AND existing.field2 = i.field2)
WHERE existing.id IS NULL
)
где% s - это строка типа ("field1, field2"), ("field3, field4"), ("field5, field6")
, которую вам нужно будет создать и сбежать как следует.
Зависит от того, к чему вы стремитесь. Вы можете использовать функцию manage.py
loaddata
для загрузки данных в соответствующем формате (JSON, XML, YAML, ...).
См. Также это обсуждение .
Я бы сказал, что нет.
Но мне интересно, к какому типу относятся ваши item
, если они имеют в качестве атрибутов field1
и field2
. Похоже, что существует другой класс, представляющий запись, но не производный от models.Model
. Возможно, вы можете опустить этот класс и сразу создать экземпляры Entry
вместо создания этих элементов.
Если вы не уверены, что вещи в вашем item_list
уже существуют в вашей БД, и вам нужны объекты модели, то get_or_create
определенно подойдет.
Если вы знаете, что этих объектов в вашей БД НЕТ, то лучше сделать так:
for item in item_list:
new = Entry.objects.create(
field1 = item.field1,
field2 = item.field2,
)
А если вам не нужны объекты, то просто игнорируйте возврат из вызова функции. Это не ускорит работу с БД, но поможет с управлением памятью, если это проблема.
Если вы не уверены, что данные уже есть в БД, но у любого поля есть флаг unique=True
, то БД обеспечит уникальность, и вы можете просто поймать исключение и двигаться дальше. Это предотвратит лишнее попадание в БД, избежав попытки выбрать существующий объект.
from django.db import IntegrityError
for item in item_list:
try:
new = Entry.objects.create(
field1 = item.field1,
field2 = item.field2,
)
except IntegrityError:
continue
Вы можете увеличить скорость в любом случае, если будете вручную управлять транзакциями. Django автоматически создает и фиксирует транзакцию для каждого сохранения, но предоставляет некоторые декораторы, которые значительно повышают эффективность, если вы знаете, что будете делать много сохранений в БД в определенной функции. Документация Django объясняет все это лучше, чем я здесь, но вы, вероятно, захотите обратить особое внимание на django.db.transaction.commit_on_success