将较大的任务分成较小的部分。
第 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 块
使用 CSVModel 并启用与 Contact 模型的交互,但为 ContactCSVModel.import_data() 提供更小的迭代。我将其设置为 500。根据您的需要更改它。下面的代码示例(链接)是为了让您了解。您需要对其进行一些更改以将其放入现有代码中。如果内存消耗是问题,这将有所帮助。
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-adaptors。如果您依赖此 django 包,则无法切换到批量插入。在 linux 下使用 top 或 htop 检查内存消耗,在 windows 上使用任务管理器。如果进程消耗太多并且操作系统开始交换,请切换到另一个 django 附加组件,该附加组件具有更高效的内存消耗和批量插入作为选项 - 有很多用于 csv 导入。
另一个提示是使用 csv 模块进行阅读,并使用您的 django 模型知识与数据库进行交互。这对你来说并不是一个真正的挑战——只要尝试一下你的大局中的孤立任务,如果它们正在工作,就把它们放在一起——祝你好运。