在绝大多数情况下,SQLAlchemy 语句或查询的“字符串化”很简单:
print(str(statement))
这适用于 ORM Query 以及任何 select() 或其他语句。
注意:以下详细答案正在sqlalchemy documentation 上维护。
要将语句编译为特定方言或引擎,如果语句本身尚未绑定到某个语句,您可以将其传递给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))
关于绑定参数将被“内联”到最终字符串中的原始规定,这里的挑战是 SQLAlchemy 通常不负责此任务,因为这由 Python DBAPI 适当处理,更不用说绕过绑定参数可能是现代 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)