我真的很希望能够为我的应用程序打印出有效的 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)
https://stackoverflow.com/questions/5631078/
相关文章:
javascript - 可以使用 scrapy 从使用 AJAX 的网站中抓取动态内容吗?
linux - 重新加载 Flash 17 次会导致错误 #2046 并需要重新启动浏览器
python - Python 3.3+ 中的包不需要 __init__.py
linux - Git 状态忽略行尾/相同文件/windows & linux 环境/dropbox
python - 在 Python 中拆分空字符串时,为什么 split() 返回一个空列表,而 s
linux - ELF文件格式中的section和segment有什么区别