编程语言
首页 > 编程语言> > python-使用Django ORM进行选择性事务管理

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