diff --git a/alembic/versions/025_add_user_wechat_fields.py b/alembic/versions/025_add_user_wechat_fields.py new file mode 100644 index 000000000..2e0ef4ee0 --- /dev/null +++ b/alembic/versions/025_add_user_wechat_fields.py @@ -0,0 +1,72 @@ +"""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: + """检查 PostgreSQL 表中某列是否已存在。""" + conn = op.get_bind() + result = conn.execute( + sa.text( + "SELECT 1 FROM information_schema.columns " + "WHERE table_name = :table AND column_name = :column" + ), + {"table": table, "column": column}, + ) + return result.scalar() is not None + + +def _index_exists(index: str) -> bool: + """检查 PostgreSQL 中某索引是否已存在。""" + conn = op.get_bind() + result = conn.execute( + sa.text("SELECT 1 FROM pg_indexes WHERE indexname = :index"), + {"index": index}, + ) + return result.scalar() is not None + + +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") diff --git a/packages/adapters/sqlalchemy_impl/models.py b/packages/adapters/sqlalchemy_impl/models.py index 94aaff0f4..982875e00 100755 --- a/packages/adapters/sqlalchemy_impl/models.py +++ b/packages/adapters/sqlalchemy_impl/models.py @@ -30,6 +30,9 @@ class UserModel(Base): used_storage_gb = Column(Integer, nullable=False, default=0) # 管理员标识 is_admin = Column(Boolean, nullable=False, default=False) + # 微信登录(小程序端) + wechat_openid = Column(String(128), nullable=True, unique=True, index=True) + wechat_unionid = Column(String(128), nullable=True, unique=True, index=True) created_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))