使用django ORM进行多处理?

时间:2017-09-28 10:57:02

标签: python django django-orm python-multiprocessing

我有一个Django ORM数据库(mysql或sqlite),并希望用相当计算密集的操作来处理每一行。我现在所拥有的是:

entries = Entry.objects.filter(language='')
for e in entry:
    e.language = detect_language(e.text)
    e.save()

如果数据库是瓶颈,我会使用一个事务来加速它。但是,detect_language函数占用的时间最多。我可以尝试多次并行运行脚本,但这会引入竞争条件。

我认为可以使用multiprocessing使用Pool.map()完成此操作 - 主进程提取数据库条目,子进程运行detect_language。我不确定如何详细说明,例如是否保存子进程或主进程中的条目。

在进程之间传递ORM对象时有什么需要注意的吗?您能举一个简短的例子来说明如何在多处理中使用ORM吗?

我刚刚把它绑起来,这样的东西似乎工作得很好。我仍然想知道这里是否有任何警告,或者是否可以提高性能(例如批量更新数据库):

def detect_and_save(obj):
    obj.language = detect_language(obj.text)
    obj.save()

with multiprocessing.Pool(processes=3) as pool:
    pool.map(detect_and_save, entries)

1 个答案:

答案 0 :(得分:0)

  1. 您不需要传递完整的ORM对象-您只需传递函数需要的参数并将其结果保存到ORM对象即可。
  2. 您可以使用bulk_update(可从Django 2.2或3rd party library获得)保存在单个查询中。
texts = [e.text for e in entries]
with multiprocessing.Pool() as pool:
    languages = pool.map(detect_language, texts)
for e, l in zip(entries, languages):
    e.language = l
Entry.objects.bulk_update(entries, ['language'])