119 lines
4.0 KiB
Python
119 lines
4.0 KiB
Python
"""V15 T+ 持久化任务、幂等和重试元数据。"""
|
||
|
||
from collections.abc import Sequence
|
||
|
||
from alembic import op
|
||
import sqlalchemy as sa
|
||
from sqlalchemy.dialects.mysql import BIGINT
|
||
|
||
revision: str = "e5f607a8b9c0"
|
||
down_revision: str | Sequence[str] | None = "d4e5f6a7b8c9"
|
||
branch_labels: str | Sequence[str] | None = None
|
||
depends_on: str | Sequence[str] | None = None
|
||
|
||
|
||
def upgrade() -> None:
|
||
"""仅扩展管理元数据,不改原始暂存行或工资业务表。"""
|
||
op.add_column(
|
||
"tplus_sync_batches",
|
||
sa.Column("entity_types_json", sa.JSON(), comment="请求读取的实体类型;历史批次可为空"),
|
||
)
|
||
op.add_column(
|
||
"tplus_sync_batches",
|
||
sa.Column(
|
||
"skipped_record_count",
|
||
sa.Integer(),
|
||
nullable=False,
|
||
server_default="0",
|
||
comment="重复快照跳过条数",
|
||
),
|
||
)
|
||
op.add_column(
|
||
"tplus_sync_batches",
|
||
sa.Column("parent_batch_no", sa.String(32), comment="重试来源批次号,保留原批次记录"),
|
||
)
|
||
op.add_column(
|
||
"tplus_sync_batches",
|
||
sa.Column("request_key", sa.String(36), comment="请求幂等键,空值用于历史和直接CLI任务"),
|
||
)
|
||
op.add_column(
|
||
"tplus_sync_batches",
|
||
sa.Column(
|
||
"requested_by", BIGINT(unsigned=True), comment="请求用户ID,CLI任务为空,无物理外键"
|
||
),
|
||
)
|
||
op.add_column(
|
||
"tplus_sync_batches",
|
||
sa.Column("audit_result_json", sa.JSON(), comment="关联核验结果,只含系统字典和汇总"),
|
||
)
|
||
op.alter_column(
|
||
"tplus_sync_batches",
|
||
"started_at",
|
||
existing_type=sa.DateTime(),
|
||
nullable=True,
|
||
comment="开始执行时间(排队时为空)",
|
||
)
|
||
op.alter_column(
|
||
"tplus_sync_batches",
|
||
"sync_mode",
|
||
existing_type=sa.String(16),
|
||
nullable=False,
|
||
comment="任务方式:FULL全量 AUDIT关联核验 INCREMENTAL预留",
|
||
)
|
||
op.alter_column(
|
||
"tplus_sync_batches",
|
||
"status",
|
||
existing_type=sa.String(16),
|
||
nullable=False,
|
||
comment="状态:QUEUED/RUNNING/SUCCEEDED/PARTIAL/FAILED",
|
||
)
|
||
op.create_unique_constraint(
|
||
"uk_tplus_sync_batches_request_key", "tplus_sync_batches", ["request_key"]
|
||
)
|
||
op.create_index(
|
||
"idx_tplus_sync_batches_parent_status", "tplus_sync_batches", ["parent_batch_no", "status"]
|
||
)
|
||
op.execute(
|
||
"UPDATE tplus_sync_batches SET skipped_record_count=GREATEST(0, source_record_count-staged_record_count-failed_record_count) WHERE status='SUCCEEDED' AND sync_mode='FULL'"
|
||
)
|
||
|
||
|
||
def downgrade() -> None:
|
||
"""回滚前关闭 worker;原始暂存数据和历史批次仍保留。"""
|
||
op.execute(
|
||
"UPDATE tplus_sync_batches SET started_at=create_time, status='FAILED', finished_at=CURRENT_TIMESTAMP, error_message='任务管理版本已回滚' WHERE status='QUEUED'"
|
||
)
|
||
op.execute("UPDATE tplus_sync_batches SET started_at=create_time WHERE started_at IS NULL")
|
||
op.drop_index("idx_tplus_sync_batches_parent_status", table_name="tplus_sync_batches")
|
||
op.drop_constraint("uk_tplus_sync_batches_request_key", "tplus_sync_batches", type_="unique")
|
||
for name in (
|
||
"audit_result_json",
|
||
"requested_by",
|
||
"request_key",
|
||
"parent_batch_no",
|
||
"skipped_record_count",
|
||
"entity_types_json",
|
||
):
|
||
op.drop_column("tplus_sync_batches", name)
|
||
op.alter_column(
|
||
"tplus_sync_batches",
|
||
"started_at",
|
||
existing_type=sa.DateTime(),
|
||
nullable=False,
|
||
comment="开始读取时间",
|
||
)
|
||
op.alter_column(
|
||
"tplus_sync_batches",
|
||
"sync_mode",
|
||
existing_type=sa.String(16),
|
||
nullable=False,
|
||
comment="同步模式:FULL全量 INCREMENTAL增量",
|
||
)
|
||
op.alter_column(
|
||
"tplus_sync_batches",
|
||
"status",
|
||
existing_type=sa.String(16),
|
||
nullable=False,
|
||
comment="状态:RUNNING/SUCCEEDED/PARTIAL/FAILED",
|
||
)
|