我真的很希望能够为我的应用程序打印出有效的 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/