# -*- coding: utf-8 -*- """迁移脚本:为非空邮箱补充唯一索引。""" import logging from sqlalchemy import text from insurance.db.compat import db def migrate(): """创建 wecom_user_mapping.email 非空唯一索引。""" try: from sqlalchemy import inspect inspector = inspect(db.engine) if not inspector.has_table("wecom_user_mapping"): logging.info("wecom_user_mapping 表不存在,跳过邮箱唯一索引") return user_columns = {col["name"] for col in inspector.get_columns("wecom_user_mapping")} if "email" not in user_columns: logging.info("wecom_user_mapping.email 字段不存在,跳过邮箱唯一索引") return index_names = {idx["name"] for idx in inspector.get_indexes("wecom_user_mapping")} if "idx_wecom_user_mapping_email_unique" in index_names: logging.info("邮箱唯一索引已存在,跳过创建") return duplicate_email = db.session.execute(text(""" SELECT email FROM wecom_user_mapping WHERE email IS NOT NULL AND email <> '' GROUP BY email HAVING COUNT(*) > 1 LIMIT 1 """)).fetchone() if duplicate_email: logging.warning( "wecom_user_mapping 存在重复邮箱 %s,跳过邮箱唯一索引创建", duplicate_email[0], ) return db.session.execute(text(""" CREATE UNIQUE INDEX IF NOT EXISTS idx_wecom_user_mapping_email_unique ON wecom_user_mapping (email) WHERE email IS NOT NULL AND email <> '' """)) db.session.commit() logging.info("成功创建 wecom_user_mapping.email 唯一索引") except Exception as e: logging.error("创建邮箱唯一索引失败: %s", e) db.session.rollback() raise def downgrade(): """删除邮箱唯一索引。""" try: db.session.execute(text("DROP INDEX IF EXISTS idx_wecom_user_mapping_email_unique")) db.session.commit() except Exception as e: logging.error("删除邮箱唯一索引失败: %s", e) db.session.rollback() raise