125 lines
4.5 KiB
Python
125 lines
4.5 KiB
Python
"""迁移 027:PPT/海报品牌策略与后台对象软删除字段。"""
|
||
import logging
|
||
|
||
from sqlalchemy import inspect, text
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
def _column_names(db, table_name: str) -> set[str]:
|
||
return {item["name"] for item in inspect(db.engine).get_columns(table_name)}
|
||
|
||
|
||
def _index_names(db, table_name: str) -> set[str]:
|
||
return {item["name"] for item in inspect(db.engine).get_indexes(table_name)}
|
||
|
||
|
||
def _add_columns(db, table_name: str, columns: dict[str, str]):
|
||
existing = _column_names(db, table_name)
|
||
for name, definition in columns.items():
|
||
if name not in existing:
|
||
db.session.execute(text(
|
||
f"ALTER TABLE {table_name} ADD COLUMN {name} {definition}"
|
||
))
|
||
|
||
|
||
def _add_index(db, table_name: str, index_name: str, columns: str):
|
||
if index_name not in _index_names(db, table_name):
|
||
db.session.execute(text(
|
||
f"CREATE INDEX {index_name} ON {table_name} ({columns})"
|
||
))
|
||
|
||
|
||
def migrate():
|
||
"""幂等增加品牌策略和软删除字段。"""
|
||
from insurance.db.compat import db
|
||
|
||
db.session.execute(text("""
|
||
CREATE TABLE IF NOT EXISTS insurance_ppt_scenarios (
|
||
code VARCHAR(50) PRIMARY KEY,
|
||
name VARCHAR(100) NOT NULL,
|
||
base_scenario VARCHAR(50),
|
||
generation_mode VARCHAR(20) NOT NULL DEFAULT 'single',
|
||
description TEXT,
|
||
status SMALLINT NOT NULL DEFAULT 1,
|
||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||
is_builtin BOOLEAN NOT NULL DEFAULT FALSE,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
deleted_at TIMESTAMP
|
||
)
|
||
"""))
|
||
# 先提交新表,确保后续 inspector 使用的独立连接能够看到它。
|
||
db.session.commit()
|
||
|
||
_add_columns(db, "insurance_ppt_companies", {
|
||
"masking_enabled": "BOOLEAN NOT NULL DEFAULT FALSE",
|
||
"logo_enabled": "BOOLEAN NOT NULL DEFAULT TRUE",
|
||
"deleted_at": "TIMESTAMP",
|
||
})
|
||
_add_columns(db, "insurance_ppt_products", {
|
||
"masking_enabled": "BOOLEAN NOT NULL DEFAULT FALSE",
|
||
"deleted_at": "TIMESTAMP",
|
||
})
|
||
_add_columns(db, "insurance_ppt_templates", {
|
||
"deleted_at": "TIMESTAMP",
|
||
})
|
||
_add_columns(db, "poster_copy_templates", {
|
||
"deleted_at": "TIMESTAMP",
|
||
})
|
||
|
||
# 新增字段提交后再检查并创建索引,避免 DDL 对其他连接不可见。
|
||
db.session.commit()
|
||
|
||
_add_index(
|
||
db, "insurance_ppt_companies",
|
||
"idx_ppt_companies_status_deleted", "status, deleted_at",
|
||
)
|
||
_add_index(
|
||
db, "insurance_ppt_scenarios",
|
||
"idx_ppt_scenarios_status_deleted", "status, deleted_at",
|
||
)
|
||
|
||
builtins = [
|
||
("single_savings", "单份储蓄计划", "single_savings", "single", 10),
|
||
("multi_savings_comparison", "双/多储蓄险对比", "multi_savings_comparison", "compare", 20),
|
||
("savings_iul_comprehensive", "储蓄险 + IUL 综合方案", "savings_iul_comprehensive", "portfolio", 30),
|
||
("generic_single", "通用单产品", "generic_single", "single", 40),
|
||
("generic_compare", "通用同险种对比", "generic_compare", "compare", 50),
|
||
("generic_portfolio", "通用组合方案", "generic_portfolio", "portfolio", 60),
|
||
]
|
||
for code, name, base_scenario, generation_mode, sort_order in builtins:
|
||
db.session.execute(text("""
|
||
INSERT INTO insurance_ppt_scenarios
|
||
(code, name, base_scenario, generation_mode, status, sort_order, is_builtin)
|
||
SELECT :code, :name, :base_scenario, :generation_mode, 1, :sort_order, TRUE
|
||
WHERE NOT EXISTS (
|
||
SELECT 1 FROM insurance_ppt_scenarios WHERE code = :code
|
||
)
|
||
"""), {
|
||
"code": code,
|
||
"name": name,
|
||
"base_scenario": base_scenario,
|
||
"generation_mode": generation_mode,
|
||
"sort_order": sort_order,
|
||
})
|
||
_add_index(
|
||
db, "insurance_ppt_products",
|
||
"idx_ppt_products_status_deleted", "status, deleted_at",
|
||
)
|
||
_add_index(
|
||
db, "insurance_ppt_products",
|
||
"idx_ppt_products_company_deleted", "company_id, deleted_at",
|
||
)
|
||
_add_index(
|
||
db, "insurance_ppt_templates",
|
||
"idx_ppt_templates_status_deleted", "status, deleted_at",
|
||
)
|
||
_add_index(
|
||
db, "poster_copy_templates",
|
||
"idx_copy_templates_status_deleted", "status, deleted_at",
|
||
)
|
||
|
||
db.session.commit()
|
||
logger.info("[migrate_027] 品牌策略与软删除字段迁移完成")
|