"""Task: Add wechat_openid / wechat_unionid to users Revision ID: 025 Revises: 024 Create Date: 2026-07-05 补录微信小程序登录所需的 wechat 字段。 生产数据库已手动添加过这些字段和索引,因此 upgrade 做幂等检查, 避免在已有字段的库上执行报错。 """ import sqlalchemy as sa from alembic import op revision = "025" down_revision = "024" branch_labels = None depends_on = None def _column_exists(table: str, column: str) -> bool: """检查列是否已存在。离线模式下返回 False。""" conn = op.get_bind() try: result = conn.execute( sa.text("SELECT 1 FROM information_schema.columns " "WHERE table_name = :table AND column_name = :column"), {"table": table, "column": column}, ) if result is None: return False return result.scalar() is not None except Exception: return False def _index_exists(index: str) -> bool: """检查索引是否已存在。离线模式下返回 False。""" conn = op.get_bind() try: result = conn.execute( sa.text("SELECT 1 FROM pg_indexes WHERE indexname = :index"), {"index": index}, ) if result is None: return False return result.scalar() is not None except Exception: return False def upgrade() -> None: # wechat_openid if not _column_exists("users", "wechat_openid"): op.add_column( "users", sa.Column("wechat_openid", sa.String(length=128), nullable=True), ) # wechat_unionid if not _column_exists("users", "wechat_unionid"): op.add_column( "users", sa.Column("wechat_unionid", sa.String(length=128), nullable=True), ) # 唯一索引 if not _index_exists("ix_users_wechat_openid"): op.create_index("ix_users_wechat_openid", "users", ["wechat_openid"], unique=True) if not _index_exists("ix_users_wechat_unionid"): op.create_index("ix_users_wechat_unionid", "users", ["wechat_unionid"], unique=True) def downgrade() -> None: op.drop_index("ix_users_wechat_unionid", table_name="users") op.drop_index("ix_users_wechat_openid", table_name="users") op.drop_column("users", "wechat_unionid") op.drop_column("users", "wechat_openid")