python - SQLAlchemy:打印实际查询

我真的很希望能够为我的应用程序打印出有效的 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 - 不区分大小写 'in'

python - Python 3.3+ 中的包不需要 __init__.py

linux - Git 状态忽略行尾/相同文件/windows & linux 环境/dropbox

python - set() 是如何实现的?

python - 在 Python 中拆分空字符串时,为什么 split() 返回一个空列表,而 s

linux - ELF文件格式中的section和segment有什么区别

linux - 有没有办法检查是否有指向目录的符号链接(symbolic link)?

python - 关于如何在 python 中使用属性功能的真实示例?