gpt4 book ai didi

python - 如何使 Tornado 中的 SQLAlchemy 异步?

转载 作者:IT老高 更新时间:2023-10-28 20:38:59 25 4
gpt4 key购买 nike

如何制作 SQLAlchemyTornado成为 async ?
我在 async mongo example 上找到了 MongoDB 的示例但我找不到像 motor 这样的东西为 SQLAlchemy .有谁知道怎么做SQLAlchemy使用 tornado.gen 执行的查询(我在 MySQL 下面使用 SQLAlchemy ,在我的处理程序从数据库读取并返回结果的那一刻,我想让这个异步)。

最佳答案

ORM 不太适合显式异步编程,也就是说,程序员必须在任何使用网络访问的情况发生时生成显式回调。一个主要原因是 ORM 广泛使用了 lazy loading模式,这或多或少与显式异步不兼容。看起来像这样的代码:

user = Session.query(User).first()
print user.addresses

实际上会发出两个单独的查询 - 当你说 first() 时一个加载一行,然后下一个当你说 user.addresses , 在 .addresses 的情况下集合不存在,或已过期。从本质上讲,几乎每一行处理 ORM 结构的代码都可能在 IO 上阻塞,所以你会在几秒钟内陷入大量的回调意大利面——更糟糕的是,这些代码行中的绝大多数实际上不会在 IO 上阻塞,因此,将回调连接在一起的所有开销都将是简单的属性访问操作,这也将使您的程序效率大大降低。

显式异步模型的一个主要问题是它们为复杂系统增加了巨大的 Python 函数调用开销 - 不仅在面向用户的方面(如延迟加载),而且在内部方面,以及系统如何围绕系统提供抽象Python 数据库 API (DBAPI)。对于 SQLAlchemy 来说,即使拥有基本的异步支持,也会对绝大多数不使用异步模式的程序,甚至那些非高度并发的异步程序造成严重的性能损失。考虑 SQLAlchemy 或任何其他 ORM 或抽象层,可能具有如下代码:
def execute(connection, statement):
cursor = connection.cursor()
cursor.execute(statement)
results = cursor.fetchall()
cursor.close()
return results

上面的代码执行看似简单的操作,即在连接上执行 SQL 语句。但是使用像 psycopg2 的异步扩展这样的完全异步 DBAPI,上面的代码在 IO 上至少阻塞了 3 次。因此,以显式异步风格编写上述代码,即使没有使用异步引擎并且回调实际上没有阻塞,也意味着上述外部函数调用至少变为三个函数调用,而不是一个,不包括施加的开销通过显式异步系统或 DBAPI 调用自身。因此,围绕语句执行的简单抽象,一个简单的应用程序会自动受到 3 倍的函数调用开销的惩罚。在 Python 中, function call overhead is everything .

由于这些原因,我对围绕显式异步系统的炒作仍然不那么兴奋,至少在某种程度上,有些人似乎想要对所有事情都采用异步,比如交付网页(参见 node.js)。我建议改用隐式异步系统,尤其是 gevent ,在这里您可以获得异步模型的所有非阻塞 IO 优点,并且没有显式回调的结构冗长/缺点。我继续尝试理解这两种方法的用例,所以我对显式异步方法作为所有问题的解决方案的吸引力感到困惑,即正如您在 node.js 中看到的那样 - 我们在第一个减少冗长和代码复杂性的地方,对于像交付网页这样的简单事情的显式异步似乎什么都不做,只是添加可以由 gevent 或类似工具自动化的样板,如果阻塞 IO 在一个像这样的情况(很多大容量网站都可以使用同步 IO 模型)。基于 Gevent 的系统已在生产环境中得到验证,并且它们的受欢迎程度正在增长,因此如果您喜欢 ORM 提供的代码自动化,您可能还希望采用像 gevent 这样的系统提供的异步 IO 调度自动化。

更新 : Nick Coghlan 指出了他的 great article on the subject of explicit vs. implicit async这也是必读的。我还了解到 pep-3156 now welcomes interoperability with gevent ,扭转了先前对 gevent 的不兴趣,这在很大程度上要归功于 Nick 的文章。因此,将来,一旦集成这些方法的系统可用,我将推荐使用 gevent 作为数据库逻辑的 Tornado 的混合体。

关于python - 如何使 Tornado 中的 SQLAlchemy 异步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16491564/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com