我真的很希望能够为我的应用程序打印出有效的 SQL,包括值,而不是绑定(bind)参数,但是在 SQLAlchemy 中如何做到这一点并不明显(根据设计,我很确定)。

有没有人以一般的方式解决了这个问题?

最佳答案

在绝大多数情况下,SQLAlchemy 语句或查询的“字符串化”非常简单:

print(str(statement))
这适用于 ORM Query 以及任何 select() 或其他语句。
注意 :以下详细答案正在 sqlalchemy documentation 上维护。
要获得编译为特定方言或引擎的语句,如果语句本身尚未绑定(bind)到一个,您可以将其传递给 compile() :
print(statement.compile(someengine))
或没有引擎:
from sqlalchemy.dialects import postgresql
print(statement.compile(dialect=postgresql.dialect()))
当给定一个 ORM Query 对象时,为了获得 compile() 方法,我们只需要先访问 .statement 访问器:
statement = query.statement
print(statement.compile(someengine))
关于绑定(bind)参数要“内联”到最终字符串中的原始规定,这里的挑战是 SQLAlchemy 通常不承担此任务,因为 Python DBAPI 对此进行了适当处理,更不用说绕过绑定(bind)参数了可能是现代 Web 应用程序中最广泛利用的安全漏洞。 SQLAlchemy 在某些情况下(例如发出 DDL)执行此字符串化的能力有限。为了访问此功能,可以使用传递给 compile_kwargs 的“literal_binds”标志:
from sqlalchemy.sql import table, column, select

t = table('t', column('x'))

s = select([t]).where(t.c.x == 5)

print(s.compile(compile_kwargs={"literal_binds": True}))
上述方法有一个警告,即它仅支持基本
类型,例如整数和字符串,此外如果是 bindparam没有预设值直接使用,将无法
要么将其字符串化。
要支持不支持的类型的内联文字呈现,请实现
目标类型的 TypeDecorator,其中包括TypeDecorator.process_literal_param 方法:
from sqlalchemy import TypeDecorator, Integer


class MyFancyType(TypeDecorator):
    impl = Integer

    def process_literal_param(self, value, dialect):
        return "my_fancy_formatting(%s)" % value

from sqlalchemy import Table, Column, MetaData

tab = Table('mytable', MetaData(), Column('x', MyFancyType()))

print(
    tab.select().where(tab.c.x > 5).compile(
        compile_kwargs={"literal_binds": True})
)
产生输出,如:
SELECT mytable.x
FROM mytable
WHERE mytable.x > my_fancy_formatting(5)

关于python - SQLAlchemy:打印实际查询,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5631078/

10-16 20:34