python-使用Django ORM进行选择性事务管理
作者:互联网
我正在尝试使用MySQL上的Django ORM设计批量数据导入任务.通常,我只是使用LOAD DATA INFILE,但是我批量导入的数据包含三个表上的记录,并且某些记录可能已经存在,因此我必须检查是否存在预先存在的记录,创建或检索其ID. ,然后在创建或检索其他记录时使用此ID.
默认情况下,导入速率为0.8行/秒.太可怕了.通过在受影响的表上运行DISABLE KEYS,我设法将其提高到1.5行/秒,但是由于我有几百万行,所以这仍然太慢了.
关于加快Django的ORM批量导入复杂表关系的方法,是否有任何一般性建议?
我正在考虑禁用Django的事务管理,以便将整个导入包装在单个事务中.但是,由于导入需要很长时间,因此导入过程会定期更新状态模型以报告完成百分比.如果我将整个导入包装在一个事务中,它将无法更新此状态记录.那么,有什么方法可以仅对一组特定的模型禁用事务管理,并且仍然允许其提交单独的模型?
我想做类似的事情:
from django.db import transaction
transaction.enter_transaction_management()
transaction.managed(True)
from myapp.models import Status, Data
status = Status.objects.get(id=123)
try:
data = magically_get_data_iter()
for row in data:
d,_ = Data.objects.get_or_create(**data.keys())
d.update(data)
d.save() # not actually visible in admin until the commit below
if not row.i % 100:
status.current_row = row.i
status.total_rows = row.total
# obviously doesn't work, but this should somehow actually commit
status.save(commit=True)
finally:
transaction.commit()
解决方法:
通过将批量更新的模型和将状态记录存储在不同数据库中的模型,然后禁用对先前数据库的事务管理,我解决了这一问题.
例如我上面的示例的简化:
django.db.transaction.enter_transaction_management(using='primary')
django.db.transaction.managed(True, using='primary')
i = 0
for record in records:
i += 1
r = PrimaryDBModel(**record)
r.save() # This will no be committed until the end.
if not i % 100:
SecondaryDBModel.update()
status = SecondaryDBModel(id=123)
status.current_row = i
status.save() # This will committed immediately.
django.db.transaction.commit(using='primary')
django.db.transaction.leave_transaction_management(using='primary')
标签:django-orm,python,django,mysql 来源: https://codeday.me/bug/20191201/2083940.html