Files
group_fqcd_jr/alembic/versions/20260909_memory_active_key.py
T

44 lines
1.7 KiB
Python
Raw Normal View History

"""中期记忆有效版本唯一性:memory_unit 增加生成列 `active_memory_key` 与唯一键。
依据 `docs/00-新数据库基线设计.md` 第 696 行:同一 `customer_id + memory_key` 可以
存在历史版本和待验证候选,但只能有一条当前"有效"记录;实现时增加生成列
`active_memory_key`(仅当状态为有效时返回 `memory_key`,否则返回 `NULL`),并建立
唯一键 `(customer_id, active_memory_key)`。
本迁移只新增列与唯一键,未重命名、删除或修改任何已有字段。
MySQL 语法说明:VIRTUAL 生成列允许索引,但不允许显式 DEFAULT 值;NULL 语义由
CASE 表达式给出(非 active 状态返回 NULL),因此唯一键不会约束历史版本行。
"""
from alembic import op
revision = "20260909_memory_active_key"
down_revision = "20260909_constraint_fix"
branch_labels = None
depends_on = None
TABLE = "memory_unit"
GENERATED_COLUMN = "active_memory_key"
UNIQUE_KEY = "uk_memory_unit_customer_active_key"
# 生成列表达式中的状态值为 docs/00 规定的"有效"状态。
ACTIVE_STATUS = "active"
EXPRESSION = f"(CASE WHEN `status` = '{ACTIVE_STATUS}' THEN `memory_key` ELSE NULL END)"
def upgrade() -> None:
op.execute(
f"ALTER TABLE `{TABLE}` "
f"ADD COLUMN `{GENERATED_COLUMN}` VARCHAR(128) "
f"GENERATED ALWAYS AS {EXPRESSION} VIRTUAL, "
f"ADD UNIQUE KEY `{UNIQUE_KEY}` (`customer_id`, `{GENERATED_COLUMN}`)"
)
def downgrade() -> None:
# 生成列为本次新增,回退时删除;不触碰任何基线已有字段。
op.execute(
f"ALTER TABLE `{TABLE}` "
f"DROP INDEX `{UNIQUE_KEY}`, "
f"DROP COLUMN `{GENERATED_COLUMN}`"
)