使用 Sqlalchemy 连接和 Postgres 从原始字符串编译查询(不使用 .text(...))

Posted

技术标签:

【中文标题】使用 Sqlalchemy 连接和 Postgres 从原始字符串编译查询(不使用 .text(...))【英文标题】:Compile query from raw string (without using .text(...)) using Sqlalchemy connection and Postgres 【发布时间】:2019-10-10 06:04:57 【问题描述】:

我正在使用 Sqlalchemy 1.3 连接到 PostgreSQL 9.6 数据库(通过 Psycopg)。

我有一个非常 非常 使用 Psycopg2 语法格式化的原始 Sql 字符串,由于一些遗留问题,我无法修改:

statement_str = SELECT * FROM users WHERE user_id=%(user_id)s

注意%(user_id)s

我可以很高兴地使用 sqlalchemy 连接执行它,只需这样做:

connection = sqlalch_engine.connect()
rows = conn.execute(statement_str, user_id=self.user_id)

而且效果很好。我得到了我的用户,一切都很好。

现在,出于调试目的,我希望将 %(user_id)s 参数扩展为实际值的实际查询。例如:如果user_id = "foo",则得到SELECT * FROM users WHERE user_id = 'foo'

我见过大量使用sqlalchemy.text(...) 生成语句然后获得编译版本的示例。这要归功于其他答案,例如 this one 或 this one 在我有 SqlAlchemy 查询时能够产生像样的 str

但是,在这种特殊情况下,因为我使用的是更特定于光标的语法%(user_id),所以我不能这样做。如果我尝试:

text(statement_str).bindparams(user_id="foo")

我得到: This text() construct doesn't define a bound parameter named 'user_id'

所以我想我正在寻找的是类似的东西

conn.compile(statement_str, user_id=self.user_id)

但我没能得到那个。

【问题讨论】:

【参考方案1】:

不确定这是不是你想要的,但这里是。

假设 statement_str 实际上是一个字符串:

import sqlalchemy as sa

statement_str = "SELECT * FROM users WHERE user_id=%(user_id)s"
params = 'user_id': 'foo'

query_text = sa.text(statement_str % params)

# str(query_text) should print "select * from users where user_id=foo"

【讨论】:

感谢您的回答。问题在于text(...) 试图将%(user_id)s 转义为%%(user_id) 哦,好的。很高兴您找到了解决方案。【参考方案2】:

好的,我认为我明白了。

SqlAlchemy 的raw_connection + Psycopg 的mogrify 的组合似乎就是答案。

conn = sqlalch_engine.raw_connection()
try:
    cursor = conn.cursor()
    s_str = cursor.mogrify(statement_str, 'user_id': self.user_id)
    s_str = s_str.decode("utf-8")  # mogrify returns bytes

    # Some cleanup for niceness:
    s_str = s_str.replace('\n', ' ')
    s_str = re.sub(r'\s2,', ' ', s_str)
finally:
    conn.close()

我希望其他人觉得这有帮助

【讨论】:

以上是关于使用 Sqlalchemy 连接和 Postgres 从原始字符串编译查询(不使用 .text(...))的主要内容,如果未能解决你的问题,请参考以下文章

MFC连接postgre数据库

libpq VS qpsql(postgre 的 QT 驱动程序)

SQLAlchemy 和多个进程的连接问题

尝试连接数据库和 Web 容器时 SQLAlchemy 连接被拒绝

Sqlalchemy 连接超时

使用 Sqlalchemy 连接和 Postgres 从原始字符串编译查询(不使用 .text(...))