批量创建失败,有一百万行

2024-10-03 19:29:27 发布

您现在位置:Python中文网/ 问答频道 /正文

为了便于学习,我创建了包含10000行的csv文件和具有100万行的第二个文件,每行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)对于10000行,插入数据需要2.1006858348846436

2)对于100万行,大约是220.xx秒

我的第二种方法是使用bulk_create()

^{pr2}$

1)对于10000行,它需要0.4592757225036621,这很酷,比使用@transaction.atomic快4倍多

2)但是,对于100万行,它失败并且超出了SQL基的限制。在

有人知道为什么会出现这样的错误吗?在

我一直在阅读django文档bulk_create,但是除了关于sqllite的batch_size的注释之外,我找不到任何有用的东西。在


Tags: 文件csv数据方法namesqldatarequest
1条回答
网友
1楼 · 发布于 2024-10-03 19:29:27

问题是您创建并提供给bulk_create的百万对象列表。即使您只是传入一个迭代器,Django也会将其转换为一个列表,以便在继续之前优化插入。解决方案是在Django之外使用islice进行自己的批处理。在

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)

相关问题 更多 >