可以将 SQLAlchemy 配置为非阻塞吗?
Posted
技术标签:
【中文标题】可以将 SQLAlchemy 配置为非阻塞吗?【英文标题】:Can SQLAlchemy be configured to be non-blocking? 【发布时间】:2012-04-30 03:20:22 【问题描述】:我的印象是,通过 SQLAlchemy 进行的数据库调用会阻塞,并且不适合在同步代码以外的任何地方使用。我是正确的(我希望我不是!)还是有办法将其配置为非阻塞?
【问题讨论】:
简答,不。阻塞的是数据库,而不是 SQLalchemy 本身。不过,没有什么能阻止您在单独的线程中执行数据库操作。 @AdamKG 这可能应该是一个答案,而不是评论! :-) 【参考方案1】:您可以使用gevent 以非阻塞方式使用 SQLA。这是一个使用 psycopg2 的示例,使用 psycopg2 的coroutine support:
https://bitbucket.org/zzzeek/green_sqla/
我还听说人们对pymysql 使用相同的想法。由于 pymysql 是纯 Python 并使用套接字库,gevent 将套接字库修补为异步。
【讨论】:
太棒了!谢谢你。以这种方式使用它时,是否有任何我应该注意的警告(未出现在文档中)? 不确定。我发现使用禁用池的 NullPool 似乎效果更好。否则有什么东西让它挂了。所以也许要谨慎开始...... @zzzeek 您的挂起可能来自使用非猴子补丁线程的 SQLAlchemy 的默认池 (QueuePool)。根据 groups.google.com/forum/#!msg/gevent/533wzrnL0Fs/ijL34u5prYIJ 的示例应用 gevent 的猴子补丁或制作绿色版本的 QueuePool。当我拥有它时,这修复了相同的行为。 你为什么不需要在那里修补 sqlalchemy/util/queue.py ?也使用 threading.RLock。 @zzzeek 该链接不再有效...您在其他地方还有可用的示例吗?【参考方案2】:看看Tornado,他们有一些简洁的非阻塞库,尤其是 tornado.gen。
我们将它与 Momoko 一起使用,这是一个用于 Tornado 的非阻塞 psycopg 包装器库。到目前为止一切都很好。也许唯一的缺点是您丢失了 SQLAlchemy 为您提供的所有模型对象内容。不过性能是不真实的。
【讨论】:
我一直在关注 Tornado,我很可能会沿着这条路走下去。也许我应该编写一些演示代码来测试这一点,但如果 psycopg 驱动程序支持异步数据库调用(显然支持),我想可以使用 SQLAlchemy 进行非阻塞数据库调用。 @Matty 好主意,我很想听听你的做法。我想您在使用 SQLAlchemy 时会遇到的主要问题之一是不确切知道何时会进行阻塞调用。当然,您总是可以深入研究代码,以弄清楚我的直觉何时会说这将是大量工作。 @Kahunza 在快速查看 psycopg2 的文档后,似乎有一个参数可以包含在传递给 SQLAlchemy 的create_engine()
函数的连接字符串中。也许其中一位维护者会插话,或者我会在他们的名单上询问。干杯!
@Matty:你有没有想过这个问题?【参考方案3】:
如果没有 greenlet 的帮助,答案是否定的,在 asyncio 的上下文中。
但是,可以在 asyncio 中仅使用 SQLAlchemy 的一部分。请在GINO project 中找到示例,其中我们仅使用没有引擎和完整执行上下文的 SQLAlchemy 核心在 asyncio 中制作简单的 ORM。
【讨论】:
以上是关于可以将 SQLAlchemy 配置为非阻塞吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何将套接字重置为阻塞模式(在我将其设置为非阻塞模式之后)?