"""领取用的分段 UPDATE。 每段 500 个 fid,避开 Oracle 一条 IN 最多 1000 个表达式。 调用方持有事务:本模块不提交。任一段失败由调用方整笔回滚。 """ from __future__ import annotations FID_CHUNK_SIZE = 500 def update_by_fid_chunks( cur, sql_template: str, fids: list[int], binds: dict | None = None, ) -> None: """按每段 500 个 fid 执行同一条 UPDATE。 sql_template 用 {placeholders} 放本段占位符。各段在当前游标上顺序执行,不提交。 空列表不执行。任一段抛错时前面各段已执行但未提交,调用方应整笔回滚。 """ if not fids: return extra = dict(binds or {}) for start in range(0, len(fids), FID_CHUNK_SIZE): chunk = list(fids[start : start + FID_CHUNK_SIZE]) placeholders, fid_binds = _fid_placeholders(chunk) cur.execute( sql_template.format(placeholders=placeholders), {**extra, **fid_binds}, ) def _fid_placeholders(fids: list[int]) -> tuple[str, dict[str, int]]: """把本段 fid 编成 :id0, :id1 占位和 bind。段内从 0 编号。""" fid_binds = {f"id{index}": value for index, value in enumerate(fids)} placeholders = ", ".join(f":id{index}" for index in range(len(fids))) return placeholders, fid_binds