在loop.run_in_executor中使用Django ORM执行“ select_for_update”

时间:2019-08-14 11:06:38

标签: python django python-3.x python-asyncio django-orm

Env:

python-3.6.4
django-2.1.7
数据库-mysql

示例:

from django.db import transaction

async def some_method():
    with transaction.atomic():
        obj = await loop.run_in_executor(
            None,
            lambda: models.ModelName.objects.select_for_update().get(id=obj_id)
        )
        # do other stuff

引发以下错误:

     raise TransactionManagementError('select_for_update cannot be used outside of a transaction.')
 django.db.transaction.TransactionManagementError: select_for_update cannot be used outside of a transaction.

可以运行类似的代码而不会出错:

async def some_method():
    with transaction.atomic():
        obj = models.ModelName.objects.select_for_update().get(id=obj_id)
        # do other stuff

其他任何没有select_for_update()的查询都可以在loop.run_in_executor中完成,例如obj.save()

上下文:

作为一个实验,我尝试在保持Django ORM的情况下将Django应用程序“迁移”到aiohttp。 (请不要问“为什么”-这是作为实验)

问题:

  1. 是否可以在run_in_executor中调用select_for_update()或 用其他方法?
  2. 如果我在obj.save()中呼叫obj2.save()loop.run_in_executor是否确实在同一笔交易中运行

喜欢:

 async def some_method():
    with transaction.atomic():
        await loop.run_in_executor(
            None,
            obj.save
        )
        await loop.run_in_executor(
            None,
            obj2.save
        )



目的:让我们假设对数据库的调用需要2秒钟(只是假设,原因可能是:连接或未优化的DB,无论如何)-我需要调用DB时不会阻塞。(我知道Mysql有几个“异步” ORM库,但是我尝试保留Django ORM)

0 个答案:

没有答案