python - 混合 Tornado 和sqlalchemy

标签 python sqlalchemy

我正在尝试编写一个在某些请求处理程序中使用 sqlalchemy 的 Tornado Web 应用程序。这些处理程序有两个部分:一个需要很长时间才能完成,另一个使用 sqlalchemy 并且速度相对较快。 我想让请求的慢速部分异步,而不是 sqlalchemy 部分。我可以执行类似以下代码的操作并且安全吗?

class ExampleHandler(BaseHandler):
    async def post(self):
        loop = asyncio.get_event_loop()
        await loop.run_in_executor(...)   # very slow (no sqlalchemy here)

        with self.db_session() as s:      # sqlalchemy session
            s.add(...)
            s.commit()

        self.render(...)

想法是让 sqlalchemy 仍然阻塞,但计算量大的部分不会阻塞应用程序。

最佳答案

tornado 网络服务器使用异步代码来绕过 python 全局解释器锁的限制。众所周知,GIL 只允许在 python 解释器进程中执行一个线程。由于使用了事件循环,Tornado 能够同时响应许多请求。事件循环一次可以执行一项小任务。让我们以您自己的帖子处理程序来更好地理解这一点。

在此处理程序中,当 python 解释器到达 await 关键字时,它会暂停函数的执行并将其排队等待稍后在其事件循环中使用。然后它检查事件循环以响应可能已经在那里排队的其他事件,例如响应新连接或为另一个处理程序提供服务。

当你阻塞一个异步函数时,你卡住了整个事件循环,因为它无法暂停你的函数并为其他任何东西提供服务。这对您来说实际上意味着您的 Web 服务器将不会在您的异步函数阻塞时接受或服务任何请求。看起来您的 Web 服务器好像挂起,而且确实卡住了。

为了保持服务器响应,您必须找到一种以异步非阻塞方式执行 sqlalchemy 查询的方法。

关于python - 混合 Tornado 和sqlalchemy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53158761/

相关文章:

python - 将表定义类从 SQLAlchemy 隐藏到普通 MySQL

python - 尝试将数据插入 postgresql 时出现语法错误

python - 使用 selenium 在 python 中切换到弹出窗口

python - Pycharm:在Python控制台中运行和运行之间的行为不同?

python - Sqlalchemy:engine.execute() 的 postgresql paramstyle

python - 无法捕获 SQLAlchemy IntegrityError

python - 如何通过 geckodriver 在 Python 中使用 selenium 获取文本

python - 我怎样才能在pygame中获得流畅的运动?

python - 如何解决 sqlalchemy.orm.exc.UnmappedInstanceError

python - SQLAlchemy:是否可以在记录的某个部分之间进行选择