gpt4 book ai didi

python - Django 适配器 CSV 需要数小时才能导入

转载 作者:太空狗 更新时间:2023-10-29 21:26:57 24 4
gpt4 key购买 nike

我正在使用 Django adaptors上传一个简单的 CSV。当我导入 100 或 200 个联系人时,它似乎工作得很好。但是当我尝试上传一个包含 5000 个联系人的 165kb 文件时,它永远无法完成。我让它继续尝试,1 小时后我回来时它还在尝试。

这是怎么回事?使用 Django adaptors 导入一个 165kb 的文件不可能花费一个多小时。 . 代码有问题吗?

 def process(self):
self.date_start_processing = timezone.now()
try:


# Try and import CSV
ContactCSVModel.import_data(data=self.filepath, extra_fields=[
{'value': self.group_id, 'position': 5},
{'value': self.uploaded_by.id, 'position': 6}])

self._mark_processed(self.num_records)
except Exception as e:
self._mark_failed(unicode(e))

CsvModel

class ContactCSVModel(CsvModel):

first_name = CharField()
last_name = CharField()
company = CharField()
mobile = CharField()
group = DjangoModelField(Group)
contact_owner = DjangoModelField(User)


class Meta:
delimiter = "^"
dbModel = Contact
update = {'keys': ["mobile", "group"]}

最佳答案

将较大的任务拆分成较小的部分。

第 1 步 - 只需读取 CSV 文件

ContactCSVModel.import_from_filename() 和 ContactCSVModel.import_from_file() 都返回 csv 行。禁用与 Django 模型的交互以跳过与数据库的交互。这应该会大大加快任务速度并打印导入的数据。这绝对有效!

CSV模型

class ContactCSVModel(CsvModel):

first_name = CharField()
last_name = CharField()
company = CharField()
mobile = CharField()
group = DjangoModelField(Group)
contact_owner = DjangoModelField(User)


class Meta:
delimiter = "^"

你的代码

 def process(self):
self.date_start_processing = timezone.now()
try:


# Try and import CSV
lines = ContactCSVModel.import_data(data=self.filepath, extra_fields=[
{'value': self.group_id, 'position': 5},
{'value': self.uploaded_by.id, 'position': 6}])
print lines # or use logging

self._mark_processed(self.num_records)
except Exception as e:
self._mark_failed(unicode(e))

第 2 步 - 启用 django 模型交互但禁用检查数据库中的现有项目。

禁用它,因为启用此功能会查询数据库中 CSV 中的每一行,以根据您的自然键规范检查现有项目(我已阅读源代码)。您可能知道 CSV 中的所有行都是唯一联系人。

如果您的问题是整个导入过程中数据库查询缓慢,这将有所帮助,但如果导入消耗过多内存,则无济于事。

class ContactCSVModel(CsvModel):

first_name = CharField()
last_name = CharField()
company = CharField()
mobile = CharField()
group = DjangoModelField(Group)
contact_owner = DjangoModelField(User)


class Meta:
delimiter = "^"
dbModel = Contact

第 3 步 - 导入大小相同的 CSV block

使用 CSVModel 并启用与 Contact 模型的交互,但为 ContactCSVModel.import_data() 提供更小的迭代。我将其设置为 500。根据您的需要进行更改。下面的代码示例 ( link ) 可以帮助您理解。您需要对其进行一些更改以将其放入现有代码中。如果内存消耗是问题所在,这会有所帮助。

import csv
reader = csv.reader(open(self.filepath, 'rb'))

def gen_chunks(reader, chunksize=100):
"""
Chunk generator. Take a CSV `reader` and yield
`chunksize` sized slices.
"""
chunk = []
for i, line in enumerate(reader):
if (i % chunksize == 0 and i > 0):
yield chunk
del chunk[:]
chunk.append(line)
yield chunk

for chunk in gen_chunks(reader, chunksize=500):
ContactCSVModel.import_data(data=chunk, extra_fields=[
{'value': self.group_id, 'position': 5},
{'value': self.uploaded_by.id, 'position': 6}])

第 4 步 - 针对大内存消耗和缓慢运行

因为 django-adaptors 在导入期间将所有 Contact 模型实例保存在内存中,并且由于多次提交而不是批量插入操作导致操作缓慢 - 它不太适合较大的文件。

你有点依赖于 django 适配器。如果你依赖这个 django 包,你不能切换到批量插入。在 linux 下使用 top 或 htop 检查内存消耗,在 windows 上使用任务管理器。如果进程消耗太多并且操作系统开始交换,请切换到另一个具有更高效内存消耗和批量插入选项的 django 附加组件 - 有很多用于 csv 导入。

另一个提示是使用 csv 模块进行阅读,并使用您的 django 模型知识与数据库进行交互。这对您来说并不是一个真正的挑战 - 只需将其与您的大局中的孤立任务一起尝试,如果它们有效,则将它们放在一起 - 祝您好运。

关于python - Django 适配器 CSV 需要数小时才能导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16004844/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com