baodan/api/insurance/db/migrate_026.py

101 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""迁移 026用户产品小册子资料库与海报产品来源快照。"""
import logging
from sqlalchemy import inspect, text
logger = logging.getLogger(__name__)
def _primary_key_sql(dialect: str) -> str:
if dialect == "postgresql":
return "BIGSERIAL PRIMARY KEY"
if dialect in ("mysql", "mariadb"):
return "BIGINT AUTO_INCREMENT PRIMARY KEY"
return "INTEGER PRIMARY KEY AUTOINCREMENT"
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 migrate():
"""幂等创建用户资料表并扩展海报关联字段。"""
from insurance.db.compat import db
dialect = db.engine.dialect.name
inspector = inspect(db.engine)
if not inspector.has_table("insurance_user_product_materials"):
db.session.execute(text(f"""
CREATE TABLE insurance_user_product_materials (
id {_primary_key_sql(dialect)},
owner_user_id VARCHAR(64) NOT NULL,
tenant_id VARCHAR(64) NOT NULL DEFAULT 'default',
company_id VARCHAR(50),
company_name VARCHAR(100),
product_name VARCHAR(150),
plan_type VARCHAR(20),
original_name VARCHAR(200) NOT NULL,
file_key VARCHAR(500) NOT NULL,
file_size BIGINT NOT NULL DEFAULT 0,
page_count INTEGER,
sha256 VARCHAR(64) NOT NULL,
parse_status VARCHAR(20) NOT NULL DEFAULT 'pending',
parse_message VARCHAR(500) NOT NULL DEFAULT '',
parse_error TEXT,
parse_task_id VARCHAR(200),
parse_started_at TIMESTAMP,
parse_finished_at TIMESTAMP,
parsed_rules TEXT,
confirmed_rules TEXT,
confirmed_by VARCHAR(64),
confirmed_at TIMESTAMP,
review_status VARCHAR(20) NOT NULL DEFAULT 'private',
status SMALLINT NOT NULL DEFAULT 1,
deleted_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
"""))
db.session.commit()
logger.info("[migrate_026] 已创建 insurance_user_product_materials")
desired_indexes = {
"idx_user_material_owner_updated": "owner_user_id, updated_at",
"idx_user_material_owner_sha256": "owner_user_id, sha256",
"idx_user_material_parse_status": "parse_status",
}
existing_indexes = _index_names(db, "insurance_user_product_materials")
for index_name, columns in desired_indexes.items():
if index_name not in existing_indexes:
db.session.execute(text(
f"CREATE INDEX {index_name} "
f"ON insurance_user_product_materials ({columns})"
))
extra_columns = {
"product_source_type": "VARCHAR(20)",
"product_source_id": "VARCHAR(64)",
"product_snapshot_json": "TEXT",
}
for table_name in ("poster_case_uploads", "poster_records"):
current_columns = _column_names(db, table_name)
for column_name, column_type in extra_columns.items():
if column_name not in current_columns:
db.session.execute(text(
f"ALTER TABLE {table_name} ADD COLUMN {column_name} {column_type}"
))
db.session.execute(text(
f"UPDATE {table_name} "
"SET product_source_type = 'library_product', product_source_id = product_id "
"WHERE product_id IS NOT NULL AND product_id <> '' "
"AND (product_source_type IS NULL OR product_source_type = '')"
))
db.session.commit()
logger.info("[migrate_026] 用户产品资料库迁移完成")