From b2ccbee1abc4506fbdaec090c57dc0d5f53d535f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Thu, 27 Aug 2026 14:51:05 +0800 Subject: [PATCH] =?UTF-8?q?fix(scripts):=20backfill=5Fgroup=5Fmembers=20?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E5=87=BD=E6=95=B0=E5=8C=96=E8=BF=87=20MySQL?= =?UTF-8?q?=20only=5Ffull=5Fgroup=5Fby(=E5=8D=95=E5=BA=93=E6=94=B6?= =?UTF-8?q?=E6=95=9B)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit max(timestamp)+裸 sender_name 的 GROUP BY 是 SQLite 方言行为,MySQL 8 默认 only_full_group_by 直接 1055 拒绝——2026-08-27 单库收敛(本地+调度器同连 Docker MySQL)时在 MySQL 上实跑触发。改 row_number() OVER 取每 (room_id, talker_id) 最新一行的 sender_name + count() OVER 计数:两库通用,且语义从 「碰巧取 max 行」变为严格最新一条。另 gitignore 补 *.db.retired (smoke.db 退役改名后 *.db 规则罩不住)。 Co-Authored-By: Claude --- .gitignore | 1 + .../scripts/backfill_group_members.py | 21 +++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 4b5b46c..d19070e 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ media/ # Local scratch DBs used for Alembic autogenerate (see migrations/env.py) *.db +*.db.retired *.sqlite *.sqlite3 .playwright-mcp/ diff --git a/yunke-server/scripts/backfill_group_members.py b/yunke-server/scripts/backfill_group_members.py index 6852f5e..03f5676 100644 --- a/yunke-server/scripts/backfill_group_members.py +++ b/yunke-server/scripts/backfill_group_members.py @@ -26,13 +26,22 @@ from app.storage.repos import _upsert_one logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") log = logging.getLogger("backfill_group_members") -# max(timestamp) 裸列:SQLite 保证 sender_name 取自 timestamp 最大的那行 +# row_number() 窗口取 timestamp 最新一行的 sender_name:MySQL 8 的 +# only_full_group_by 拒绝 SQLite 式「max()+裸列」(1055),窗口写法两库通用 +# 且语义严格(最新一条的昵称),不依赖方言碰巧行为 SQL = sa_text(""" -SELECT room_id, talker_id, sender_name, max(timestamp) AS last_ts, count(*) AS msg_count -FROM message -WHERE channel = 'wechat' AND room_id IS NOT NULL AND room_id != '' - AND talker_id IS NOT NULL AND talker_id != '' -GROUP BY room_id, talker_id +SELECT room_id, talker_id, sender_name, last_ts, msg_count +FROM ( + SELECT room_id, talker_id, sender_name, timestamp AS last_ts, + count(*) OVER (PARTITION BY room_id, talker_id) AS msg_count, + row_number() OVER ( + PARTITION BY room_id, talker_id ORDER BY timestamp DESC + ) AS rn + FROM message + WHERE channel = 'wechat' AND room_id IS NOT NULL AND room_id != '' + AND talker_id IS NOT NULL AND talker_id != '' +) t +WHERE rn = 1 """)