有没有更有效的方法来做到这一点?
for item in item_list:
e, new = Entry.objects.get_or_create(
field1 = item.field1,
field2 = item.field2,
)
有没有更有效的方法来做到这一点?
for item in item_list:
e, new = Entry.objects.get_or_create(
field1 = item.field1,
field2 = item.field2,
)
您无法使用 get_or_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")
,您必须自己正确创建和转义。
我会说没有。
但我想知道你item
的 s 是什么类型,如果它们有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
标志,那么数据库将强制执行唯一性,您可以捕获异常并继续前进。这将通过避免尝试选择现有对象来防止额外的 DB 命中。
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