Neo
16c6fb0d3b
fix(backend): F1-5b A6 ETL 连接显式 client_encoding=UTF8 防御 GBK (W1)
Windows GBK 环境下 psycopg2/libpq 在拼接连接字符串时,会读取系统
用户名 / 计算机名,若含中文(0xd6 是 GBK 首字节)会触发
UnicodeDecodeError。admin_db_health.py:105-115 已用显式 DSN +
PGCLIENTENCODING 修过,但 database.py 中的 4 个 connect 函数遗漏。
变更:
- apps/backend/app/database.py
- 新增 _CONN_KWARGS = {**_KEEPALIVE_KWARGS, "client_encoding": "UTF8"}
- 4 处 psycopg2.connect 调用从 **_KEEPALIVE_KWARGS 改为 **_CONN_KWARGS:
* get_connection(zqyy_app 业务库)
* get_etl_global_readonly_connection(ETL 全局只读)
* get_etl_readonly_connection(ETL RLS 只读)
* get_etl_write_connection(ETL 可写)
业务影响:
- 影响 75+ 调用点(grep 统计),Windows GBK 环境下未来出现
UnicodeDecodeError 概率大幅降低
- Linux UTF-8 环境无影响
- ETL RLS / FDW 链路无逻辑变化(client_encoding 是协议层)
验证:
- 后端 reload + /health 200 OK
- /api/admin/db-health 测试库 connected(test_zqyy_app + test_etl_feiqiu)
- BE-3 / T3 unit test 5/5 PASS,间接证明 ETL 连接链路无破坏
§3.3 标"sandbox 无关",4b 跳过(client_encoding 是协议层,与 sandbox
业务时钟无关)。
未加 feature flag ETL_FORCE_UTF8(§8.3 兜底建议):client_encoding=UTF8
是 PostgreSQL 默认安全设置,无需 flag 控制。若未来出现特殊业务字段
含非 UTF-8 字节再考虑加 flag。
审计:docs/audit/changes/2026-05-05__wave1_f1_5b_a6_etl_conn_utf8.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 22:11:43 +08:00
..
2026-05-05 15:14:29 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-04-20 06:32:07 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-02-19 08:35:13 +08:00
2026-04-20 06:32:07 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:39:13 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:35:42 +08:00
2026-04-06 01:05:06 +08:00
2026-04-20 06:35:42 +08:00
2026-04-20 06:32:58 +08:00
2026-05-04 02:30:19 +08:00
2026-04-20 06:32:58 +08:00
2026-04-20 06:48:27 +08:00
2026-05-04 02:30:19 +08:00
2026-05-04 02:30:19 +08:00
2026-05-04 02:30:19 +08:00
2026-05-04 02:30:19 +08:00
2026-04-22 21:56:46 +08:00
2026-05-02 03:11:39 +08:00
2026-05-04 02:30:19 +08:00
2026-05-04 02:30:19 +08:00
2026-05-04 02:30:19 +08:00
2026-05-02 03:11:39 +08:00
2026-05-03 21:08:13 +08:00
2026-05-04 02:30:19 +08:00
2026-05-04 07:36:20 +08:00
2026-05-04 09:46:27 +08:00
2026-05-05 00:30:10 +08:00
2026-05-04 07:42:51 +08:00
2026-05-04 08:10:57 +08:00
2026-05-04 08:12:12 +08:00
2026-05-04 09:54:35 +08:00
2026-05-05 11:53:08 +08:00
2026-05-05 03:01:48 +08:00
2026-05-05 22:11:43 +08:00
2026-05-05 18:43:35 +08:00
2026-05-05 19:17:19 +08:00
2026-05-05 18:43:54 +08:00
2026-05-05 18:43:08 +08:00
2026-05-05 19:17:02 +08:00
2026-05-05 18:43:08 +08:00
2026-05-05 19:17:19 +08:00
2026-05-05 19:16:47 +08:00
2026-05-05 19:16:47 +08:00
2026-05-05 15:01:51 +08:00
2026-05-05 02:03:43 +08:00
2026-05-05 02:03:20 +08:00