假设我有一个包含 100 万个电子邮件地址的 CSV 文件。我需要遍历文件并添加每个条目,例如:
with open(file) as csv:
for item in csv:
Email.objects.create(email=item)
这看起来像这样通过 django ORM 创建 1M 对象并将它们插入数据库会非常慢。有没有比这更好的方法,还是我应该离开 django 来完成这项任务并直接使用 db 来完成?
假设我有一个包含 100 万个电子邮件地址的 CSV 文件。我需要遍历文件并添加每个条目,例如:
with open(file) as csv:
for item in csv:
Email.objects.create(email=item)
这看起来像这样通过 django ORM 创建 1M 对象并将它们插入数据库会非常慢。有没有比这更好的方法,还是我应该离开 django 来完成这项任务并直接使用 db 来完成?
您也可以尝试使用新的bulk_create
恕我直言,如果它只是一次性插入(1M 记录不会花你几个小时),我认为速度不会有很大问题。如果将来您将使用 django api 来访问这些对象,那么您可能应该避免使用 SQL 级别的插入,而是通过 django 的方法来完成,就像 livar 建议的那样(如果使用 django 1.4)
这是您应该使用 DB-API 来完成的事情,因为您绕过了创建所有模型对象。
此外bulk_create
,只要您的数据库后端支持,您就可以将所有插入放入一个事务中:
from django.db.transaction import commit_on_success
# with commit_on_success(), open(file) as csv: # in Python2.7
with commit_on_success():
for item in csv:
Email.objects.create(email=item)
另请注意,bulk_create
将具有相同值的项目视为相同,因此
Email.objects.bulk_create([Email(email=item), Email(email=item)])
实际上创建一行而不是两行
由于更多的 SQL 周转,事务解决方案仍然比bulk_create
一个慢,但您不必Email()
在内存中创建所有一百万个实例(生成器在这里似乎不起作用)
此外,您可以直接在 SQL 级别执行此操作
您可能想查看Django DSE包,它显然是一个高效的批量插入/更新库。