From 6a853fef3c5d9f4c10f0863d8a06de0f0c5ee3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=B5=E5=BA=94?= Date: Tue, 7 Jul 2026 07:44:30 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A1=A5=E5=BB=BA=E7=BC=BA=E5=A4=B1?= =?UTF-8?q?=E7=9A=84=20Alembic=20=E8=BF=81=E7=A7=BB=E6=96=87=E4=BB=B6=2002?= =?UTF-8?q?6-029?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 生产 DB 已执行过 026-029 迁移但文件丢失(可能 rebase 导致), 导致 alembic 报 'Can't locate revision identified by 029_user_phone'。 补建内容: - 026: users 表加 name, avatar, updated_at - 027: users 表加 ban_reason, ban_at - 028: users 表加 admin_status, admin_remarks - 029: users 表加 phone 所有 upgrade 做幂等检查(IF NOT EXISTS),安全用于已有字段的库。 --- .../versions/026_add_user_profile_fields.py | 54 +++++++++++++++++++ alembic/versions/027_add_user_ban_fields.py | 42 +++++++++++++++ alembic/versions/028_add_user_admin_fields.py | 42 +++++++++++++++ alembic/versions/029_add_user_phone.py | 38 +++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 alembic/versions/026_add_user_profile_fields.py create mode 100644 alembic/versions/027_add_user_ban_fields.py create mode 100644 alembic/versions/028_add_user_admin_fields.py create mode 100644 alembic/versions/029_add_user_phone.py diff --git a/alembic/versions/026_add_user_profile_fields.py b/alembic/versions/026_add_user_profile_fields.py new file mode 100644 index 000000000..353635a23 --- /dev/null +++ b/alembic/versions/026_add_user_profile_fields.py @@ -0,0 +1,54 @@ +"""Add user profile fields (name, avatar, updated_at) + +Revision ID: 026 +Revises: 025 +Create Date: 2026-07-05 + +补录用户资料字段。生产数据库已手动添加过这些字段, +因此 upgrade 做幂等检查,避免在已有字段的库上执行报错。 +""" + +import sqlalchemy as sa + +from alembic import op + +revision = "026" +down_revision = "025" +branch_labels = None +depends_on = None + + +def _column_exists(table: str, column: str) -> bool: + conn = op.get_bind() + result = conn.execute( + sa.text( + "SELECT COUNT(*) FROM information_schema.columns " "WHERE table_name = :table AND column_name = :column" + ), + {"table": table, "column": column}, + ) + return result.scalar() > 0 + + +def upgrade() -> None: + if not _column_exists("users", "name"): + op.add_column("users", sa.Column("name", sa.String(100), nullable=True)) + + if not _column_exists("users", "avatar"): + op.add_column("users", sa.Column("avatar", sa.String(500), nullable=True)) + + if not _column_exists("users", "updated_at"): + op.add_column( + "users", + sa.Column( + "updated_at", + sa.DateTime(), + nullable=True, + server_default=sa.func.now(), + ), + ) + + +def downgrade() -> None: + op.drop_column("users", "updated_at") + op.drop_column("users", "avatar") + op.drop_column("users", "name") diff --git a/alembic/versions/027_add_user_ban_fields.py b/alembic/versions/027_add_user_ban_fields.py new file mode 100644 index 000000000..53ca97068 --- /dev/null +++ b/alembic/versions/027_add_user_ban_fields.py @@ -0,0 +1,42 @@ +"""Add user ban fields (ban_reason, ban_at) + +Revision ID: 027 +Revises: 026 +Create Date: 2026-07-05 + +补录用户封禁字段。生产数据库已手动添加过这些字段, +因此 upgrade 做幂等检查。 +""" + +import sqlalchemy as sa + +from alembic import op + +revision = "027" +down_revision = "026" +branch_labels = None +depends_on = None + + +def _column_exists(table: str, column: str) -> bool: + conn = op.get_bind() + result = conn.execute( + sa.text( + "SELECT COUNT(*) FROM information_schema.columns " "WHERE table_name = :table AND column_name = :column" + ), + {"table": table, "column": column}, + ) + return result.scalar() > 0 + + +def upgrade() -> None: + if not _column_exists("users", "ban_reason"): + op.add_column("users", sa.Column("ban_reason", sa.Text(), nullable=True)) + + if not _column_exists("users", "ban_at"): + op.add_column("users", sa.Column("ban_at", sa.DateTime(), nullable=True)) + + +def downgrade() -> None: + op.drop_column("users", "ban_at") + op.drop_column("users", "ban_reason") diff --git a/alembic/versions/028_add_user_admin_fields.py b/alembic/versions/028_add_user_admin_fields.py new file mode 100644 index 000000000..9983d05aa --- /dev/null +++ b/alembic/versions/028_add_user_admin_fields.py @@ -0,0 +1,42 @@ +"""Add user admin fields (admin_status, admin_remarks) + +Revision ID: 028 +Revises: 027 +Create Date: 2026-07-05 + +补录管理员备注字段。生产数据库已手动添加过这些字段, +因此 upgrade 做幂等检查。 +""" + +import sqlalchemy as sa + +from alembic import op + +revision = "028" +down_revision = "027" +branch_labels = None +depends_on = None + + +def _column_exists(table: str, column: str) -> bool: + conn = op.get_bind() + result = conn.execute( + sa.text( + "SELECT COUNT(*) FROM information_schema.columns " "WHERE table_name = :table AND column_name = :column" + ), + {"table": table, "column": column}, + ) + return result.scalar() > 0 + + +def upgrade() -> None: + if not _column_exists("users", "admin_status"): + op.add_column("users", sa.Column("admin_status", sa.String(50), nullable=True)) + + if not _column_exists("users", "admin_remarks"): + op.add_column("users", sa.Column("admin_remarks", sa.Text(), nullable=True)) + + +def downgrade() -> None: + op.drop_column("users", "admin_remarks") + op.drop_column("users", "admin_status") diff --git a/alembic/versions/029_add_user_phone.py b/alembic/versions/029_add_user_phone.py new file mode 100644 index 000000000..963e88cf1 --- /dev/null +++ b/alembic/versions/029_add_user_phone.py @@ -0,0 +1,38 @@ +"""Add user phone field + +Revision ID: 029 +Revises: 028 +Create Date: 2026-07-05 + +补录用户手机号字段。生产数据库已手动添加过该字段, +因此 upgrade 做幂等检查。 +""" + +import sqlalchemy as sa + +from alembic import op + +revision = "029" +down_revision = "028" +branch_labels = None +depends_on = None + + +def _column_exists(table: str, column: str) -> bool: + conn = op.get_bind() + result = conn.execute( + sa.text( + "SELECT COUNT(*) FROM information_schema.columns " "WHERE table_name = :table AND column_name = :column" + ), + {"table": table, "column": column}, + ) + return result.scalar() > 0 + + +def upgrade() -> None: + if not _column_exists("users", "phone"): + op.add_column("users", sa.Column("phone", sa.String(20), nullable=True)) + + +def downgrade() -> None: + op.drop_column("users", "phone")