bigywater.tech
Flask · 96

SQLAlchemy 查询日志

想看 ORM 到底发了什么 SQL,怎么开日志?日志里会不会泄漏敏感参数?怎么只记录慢查询?这篇在真实的 PostgreSQL 上把几种做法的输出和开销逐个打印出来。

cached since
同一条语句第二次执行时日志里的标记——SQLAlchemy 编译缓存命中
hide_parameters
打开后日志里不再出现参数值
21%
1000 次简单查询时 INFO 日志写到内存多出的耗时

ECHO 的输出

实测 · 本机执行输出
    INFO sqlalchemy.engine.Engine BEGIN (implicit)
    INFO sqlalchemy.engine.Engine INSERT INTO u (name, pw) VALUES (%(name)s::VARCHAR, %(pw)s::VARCHAR) RETURNING u.id
    INFO sqlalchemy.engine.Engine [generated in 0.00004s] {'name': 'n0', 'pw': 'secret-hash'}
    INFO sqlalchemy.engine.Engine COMMIT
    INFO sqlalchemy.engine.Engine BEGIN (implicit)
    INFO sqlalchemy.engine.Engine INSERT INTO u (name, pw) VALUES (%(name)s::VARCHAR, %(pw)s::VARCHAR) RETURNING u.id
    INFO sqlalchemy.engine.Engine [cached since 0.0008152s ago] {'name': 'n1', 'pw': 'secret-hash'}
    INFO sqlalchemy.engine.Engine COMMIT
    INFO sqlalchemy.engine.Engine BEGIN (implicit)
    INFO sqlalchemy.engine.Engine SELECT u.id, u.name, u.pw
    FROM u
    WHERE u.name = %(name_1)s::VARCHAR
    INFO sqlalchemy.engine.Engine [generated in 0.00004s] {'name_1': 'n0'}
    INFO sqlalchemy.engine.Engine SELECT u.id, u.name, u.pw
    …(共 18 行)
  出现 "cached since" 的行数: 2 | 出现 "generated in" 的行数: 2

上一篇:悲观锁;下一篇:Flask-Migrate Migration 文件。

DEBUG 日志

实测 · 本机执行输出
    SELECT u.id, u.name 
    Col ('id', 'name')
    Row (1, 'n0')
    Row (2, 'n1')

参数与敏感信息

实测 · 本机执行输出
  默认                     日志里能看到 "hunter2-hash":True
    ['BEGIN (implicit)', "[generated in 0.00004s] {'name': 'alice', 'pw': 'hunter2-hash'}"]
  hide_parameters=True   日志里能看到 "hunter2-hash":False
    ['BEGIN (implicit)', '[generated in 0.00004s] [SQL parameters hidden due to hide_parameters=True]']

RECORD_QUERIES

实测 · 本机执行输出
    select 1                             0.2 ms
    select pg_sleep(0.2)               203.6 ms

自己写慢查询日志

实测 · 本机执行输出
  只记下了: [(153, 'select pg_sleep(0.15)')]

日志的开销

实测 · 本机执行输出
  不开日志           101.2 ms
  INFO(echo)     122.9 ms

分步演示

SQLAlchemy 查询日志
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动。Flask-SQLAlchemy 3.1.1、psycopg 3.3.6、自己起的 PostgreSQL(非默认端口)
    • 没有验证:日志写到文件或终端时的开销、结构化日志(JSON)与采样、慢查询在 PostgreSQL 服务端的 log_min_duration_statement、EXPLAIN ANALYZE 的集成
    京ICP备2026067502号-1京公网安备11010502063487号