Django Channels 异步调用ORM

Database Access — Channels 3.0.4 documentation
https://channels.readthedocs.io/en/stable/topics/databases.html

数据库访问

Django ORM 是一段同步代码,因此如果您想从异步代码访问它,您需要进行特殊处理以确保其连接正确关闭。

如果您正在使用SyncConsumer,或任何基于它的东西——比如 JsonWebsocketConsumer——你不需要做任何特别的事情,因为你的所有代码都已经在同步模式下运行,Channels 将作为SyncConsumer代码的一部分为你做清理工作。

但是,如果您正在编写异步代码,则需要在安全的同步上下文中调用数据库方法,使用database_sync_to_async.

数据库连接

如果您使用线程消费者(同步消费者),通道可能会打开比您习惯的更多的数据库连接 - 每个线程最多可以打开一个连接。

如果您希望控制使用的最大线程数,请将ASGI_THREADS环境变量设置为 您希望允许的最大数量。默认情况下,Python 3.7 及以下版本的线程数设置为“CPU 数 * 5”,Python 3.8+ 版本设置为 min(32, os.cpu_count() + 4)。

为避免连接中有太多线程空闲,您可以改写代码以使用异步使用者,并且仅在需要使用 Django 的 ORM(使用database_sync_to_async)时才使用线程。

database_sync_to_async

channels.db.database_sync_to_async是一个asgiref.sync.sync_to_async 在退出时也会清理数据库连接的版本。

要使用它,请在单独的函数或方法中编写 ORM 查询,然后database_sync_to_async像这样调用它:

from channels.db import database_sync_to_async

async def connect(self):
    self.username = await database_sync_to_async(self.get_name)()

def get_name(self):
    return User.objects.all()[0].name

或者

from channels.db import database_sync_to_async

async def connect(self):
    self.username = await self.get_name()

@database_sync_to_async
def get_name(self):
    return User.objects.all()[0].name

传参:

class test:
    def checkDevice(self, deviceId):
        results = equipment.objects.filter(device_id=deviceId)
        return results
       
    def get(self,device_id):
    	results = await database_sync_to_async(self.checkDevice)(device_id)

如果直接使用的话会提示错误

results = await database_sync_to_async(
    equipment.objects.filter,
    thread_sensitive=True)(device_id=message["device_id"])
if (len(results) == 0):
    logger.info("Wrong check")

django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
不能直接使用 results

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nickdlk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值