出于学习目的,我创建了包含10 000行的csv文件和包含100万行的第2个文件,每行4列。我们的想法是将数据最有效地添加到表中。 (我正在使用SQL数据库)
第一种方法 - @transaction.atomic
@transaction.atomic
def insert(request):
data_reader = csv.reader(open(csv_filepathname), delimiter=',', quotechar='"')
for row in data_reader:
nela = Nela() # my model name
nela.name = row[0]
nela.last = row[1]
nela.almost = row[2]
nela.number = row[3]
nela.save()
insert(request)
1)对于10 000行,需要2.1006858348846436来插入数据
2)对于100万行,它大概是~220.xx秒
我的第二种方法是使用bulk_create()
def insert(request):
data_reader = csv.reader(open(csv_filepathname), delimiter=',', quotechar='"')
header = next(data_reader)
Nela.objects.bulk_create([Nela(name=row[0], last=row[1], almost=row[2], number=row[3]) for row in data_reader])
insert(request)
1)对于10 000行,它需要0.4592757225036621,这是很酷的,比使用@transaction.atomic
2)然而,对于100万行,它失败了,它超出了SQL基础的限制。
有没有人知道为什么会出现这样的错误?
我一直在阅读django docs bulk_create,但除了关于SQL Lite batch_size
的注释外,我找不到任何有用的东西。
答案 0 :(得分:2)
问题是您创建并提供给bulk_create
的百万个对象列表。即使您只是传入迭代器,Django也会将其转换为列表,以便在继续之前优化插入。解决方案是使用islice
在Django之外进行自己的批处理。
from itertools import islice
data_reader = csv.reader(open(csv_filepathname), delimiter=',', quotechar='"')
header = next(data_reader)
batch_size = 10000
while True:
batch = [Nela(name=row[0], last=row[1], almost=row[2], number=row[3])
for row in islice(data_reader, batch_size)]
if not batch:
break
Nela.objects.bulk_create(batch, batch_size)