繁体   English   中英

Python sqlalhemy 在 for 循环中使用相同的连接连接到 postgres

[英]Python sqlalhemy connect to postgres using the same connection within a for loop

我的程序是这样的:


import sqlalchemy
engine = sqlalchemy.create_engine(DATABASE_URI)

~some code~

for group in groups:
    ~some code~
    for x in y:
        query = ~some query~
        params = ~some params~
        rows = engine.connect().execute(sqlalchemy.text(query), params)

此代码适用于两个循环,然后卡住了。 获得rows后,我用它制作了一个 df ,看起来不错。

使用此查询在 postgres 中检查:

SELECT pid, now() - pg_stat_activity.query_start AS dusration, pg_stat_activity.query, pg_stat_activity.state
FROM pg_stat_activity
WHERE pg_stat_activity.state = 'active'
ORDER BY pg_stat_activity.query_start DESC;

我可以看到有一个查询卡在活动中,我猜它在后面运行,这就是使程序卡住的原因。

我找到了一些关于 session 的帖子,但找不到一个很好的例子来说明如何使用,我不能很好地理解文档,我不确定是否是正确的解决方案?

我使用的查询是相同的,但每次运行的参数不同。

如果您能分享一些提示、链接和任何可以帮助我解决问题的内容,我将不胜感激。

首先,只连接一次,并使用with上下文管理器自动打开和关闭它:

import sqlalchemy
engine = sqlalchemy.create_engine(DATABASE_URI)

~some code~

with engine.connect() as conn:
    for group in groups:
        ~some code~
        for x in y:
            query = ~some query~
            params = ~some params~
            rows = conn.execute(sqlalchemy.text(query), params)

其次,使用会话更安全,因为它们具有内置事务。 只有当你总是只阅读时,才没有区别。

第三,如果你没有使用 SQLAlchemy ORM 或核心功能——比如session.query(User.id, User.name)select([User.id, User.name]) ,你只是假装使用 SQLAlchemy . 我无意粗鲁,但如果您在文本中编写 SQL 查询并仅使用 SQLAlchemy 来执行它们,则应改用psycopg2 如果是这种情况,请注意 SQL 注入

第三,嵌套循环中的每个项目一个查询是性能不佳的一个原因。 如果您可以避免它,请将查询合并为一个。 没有更多上下文,我们无法帮助您做到这一点,而只是举个例子:

for car in brands:
  for model in car.models:
    <SELECT car.price
     FROM cars
     WHERE brand = car.brand
       AND model = car.model>

可以简化为

<SELECT car.brand, car.model, car.price
 FROM cars WHERE car.brand IN ('Renault', 'Ferrari', 'Tesla', 'Fiat')>

即使它返回了太多的行,或者如果您仍然需要进行一些后处理,这很可能是值得的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM