fix: 0064迁移改为幂等操作(列/表存在性检查),避免Duplicate column错误
This commit is contained in:
@@ -7,6 +7,7 @@ Create Date: 2026-09-06
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import inspect
|
||||
|
||||
|
||||
revision = "0064"
|
||||
@@ -15,24 +16,48 @@ branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def _column_exists(table_name: str, column_name: str) -> bool:
|
||||
bind = op.get_bind()
|
||||
insp = inspect(bind)
|
||||
if not insp.has_table(table_name):
|
||||
return False
|
||||
return column_name in [c["name"] for c in insp.get_columns(table_name)]
|
||||
|
||||
|
||||
def _table_exists(table_name: str) -> bool:
|
||||
bind = op.get_bind()
|
||||
insp = inspect(bind)
|
||||
return insp.has_table(table_name)
|
||||
|
||||
|
||||
def _add_column_if_not_exists(table_name: str, column):
|
||||
if not _column_exists(table_name, column.name):
|
||||
op.add_column(table_name, column)
|
||||
|
||||
|
||||
def _create_table_if_not_exists(table_name: str, *columns, **kwargs):
|
||||
if not _table_exists(table_name):
|
||||
op.create_table(table_name, *columns, **kwargs)
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ── 扩展 park_tenants 表 ──
|
||||
op.add_column("park_tenants", sa.Column("default_company_discount", sa.Integer(), nullable=False, server_default="0"))
|
||||
op.add_column("park_tenants", sa.Column("default_user_discount", sa.Integer(), nullable=False, server_default="0"))
|
||||
_add_column_if_not_exists("park_tenants", sa.Column("default_company_discount", sa.Integer(), nullable=False, server_default="0"))
|
||||
_add_column_if_not_exists("park_tenants", sa.Column("default_user_discount", sa.Integer(), nullable=False, server_default="0"))
|
||||
|
||||
# ── 扩展 park_companies 表 ──
|
||||
op.add_column("park_companies", sa.Column("compute_balance", sa.Integer(), nullable=False, server_default="0"))
|
||||
op.add_column("park_companies", sa.Column("compute_balance_used", sa.Integer(), nullable=False, server_default="0"))
|
||||
_add_column_if_not_exists("park_companies", sa.Column("compute_balance", sa.Integer(), nullable=False, server_default="0"))
|
||||
_add_column_if_not_exists("park_companies", sa.Column("compute_balance_used", sa.Integer(), nullable=False, server_default="0"))
|
||||
|
||||
# ── 扩展 company_members 表 ──
|
||||
op.add_column("company_members", sa.Column("role", sa.String(length=32), nullable=False, server_default="staff"))
|
||||
op.add_column("company_members", sa.Column("compute_balance", sa.Integer(), nullable=False, server_default="0"))
|
||||
op.add_column("company_members", sa.Column("compute_balance_used", sa.Integer(), nullable=False, server_default="0"))
|
||||
op.add_column("company_members", sa.Column("left_at", sa.String(length=32), nullable=False, server_default=""))
|
||||
op.add_column("company_members", sa.Column("left_reason", sa.Text(), nullable=False, server_default=""))
|
||||
_add_column_if_not_exists("company_members", sa.Column("role", sa.String(length=32), nullable=False, server_default="staff"))
|
||||
_add_column_if_not_exists("company_members", sa.Column("compute_balance", sa.Integer(), nullable=False, server_default="0"))
|
||||
_add_column_if_not_exists("company_members", sa.Column("compute_balance_used", sa.Integer(), nullable=False, server_default="0"))
|
||||
_add_column_if_not_exists("company_members", sa.Column("left_at", sa.String(length=32), nullable=False, server_default=""))
|
||||
_add_column_if_not_exists("company_members", sa.Column("left_reason", sa.Text(), nullable=False, server_default=""))
|
||||
|
||||
# ── 新建 tenant_discounts 表 ──
|
||||
op.create_table(
|
||||
_create_table_if_not_exists(
|
||||
"tenant_discounts",
|
||||
sa.Column("id", sa.String(length=64), primary_key=True),
|
||||
sa.Column("tenant_id", sa.String(length=64), unique=True, index=True),
|
||||
@@ -45,7 +70,7 @@ def upgrade():
|
||||
)
|
||||
|
||||
# ── 新建 tenant_user_discounts 表 ──
|
||||
op.create_table(
|
||||
_create_table_if_not_exists(
|
||||
"tenant_user_discounts",
|
||||
sa.Column("id", sa.String(length=64), primary_key=True),
|
||||
sa.Column("tenant_id", sa.String(length=64), index=True),
|
||||
@@ -58,7 +83,7 @@ def upgrade():
|
||||
)
|
||||
|
||||
# ── 新建 compute_recharges 表 ──
|
||||
op.create_table(
|
||||
_create_table_if_not_exists(
|
||||
"compute_recharges",
|
||||
sa.Column("id", sa.String(length=64), primary_key=True),
|
||||
sa.Column("company_id", sa.String(length=64), index=True, server_default=""),
|
||||
@@ -74,7 +99,7 @@ def upgrade():
|
||||
)
|
||||
|
||||
# ── 新建 compute_balance_allocations 表 ──
|
||||
op.create_table(
|
||||
_create_table_if_not_exists(
|
||||
"compute_balance_allocations",
|
||||
sa.Column("id", sa.String(length=64), primary_key=True),
|
||||
sa.Column("company_id", sa.String(length=64), index=True),
|
||||
@@ -87,7 +112,7 @@ def upgrade():
|
||||
)
|
||||
|
||||
# ── 新建 compute_usage_records 表 ──
|
||||
op.create_table(
|
||||
_create_table_if_not_exists(
|
||||
"compute_usage_records",
|
||||
sa.Column("id", sa.String(length=64), primary_key=True),
|
||||
sa.Column("user_id", sa.String(length=64), index=True),
|
||||
@@ -104,20 +129,34 @@ def upgrade():
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_table("compute_usage_records")
|
||||
op.drop_table("compute_balance_allocations")
|
||||
op.drop_table("compute_recharges")
|
||||
op.drop_table("tenant_user_discounts")
|
||||
op.drop_table("tenant_discounts")
|
||||
if _table_exists("compute_usage_records"):
|
||||
op.drop_table("compute_usage_records")
|
||||
if _table_exists("compute_balance_allocations"):
|
||||
op.drop_table("compute_balance_allocations")
|
||||
if _table_exists("compute_recharges"):
|
||||
op.drop_table("compute_recharges")
|
||||
if _table_exists("tenant_user_discounts"):
|
||||
op.drop_table("tenant_user_discounts")
|
||||
if _table_exists("tenant_discounts"):
|
||||
op.drop_table("tenant_discounts")
|
||||
|
||||
op.drop_column("company_members", "left_reason")
|
||||
op.drop_column("company_members", "left_at")
|
||||
op.drop_column("company_members", "compute_balance_used")
|
||||
op.drop_column("company_members", "compute_balance")
|
||||
op.drop_column("company_members", "role")
|
||||
if _column_exists("company_members", "left_reason"):
|
||||
op.drop_column("company_members", "left_reason")
|
||||
if _column_exists("company_members", "left_at"):
|
||||
op.drop_column("company_members", "left_at")
|
||||
if _column_exists("company_members", "compute_balance_used"):
|
||||
op.drop_column("company_members", "compute_balance_used")
|
||||
if _column_exists("company_members", "compute_balance"):
|
||||
op.drop_column("company_members", "compute_balance")
|
||||
if _column_exists("company_members", "role"):
|
||||
op.drop_column("company_members", "role")
|
||||
|
||||
op.drop_column("park_companies", "compute_balance_used")
|
||||
op.drop_column("park_companies", "compute_balance")
|
||||
if _column_exists("park_companies", "compute_balance_used"):
|
||||
op.drop_column("park_companies", "compute_balance_used")
|
||||
if _column_exists("park_companies", "compute_balance"):
|
||||
op.drop_column("park_companies", "compute_balance")
|
||||
|
||||
op.drop_column("park_tenants", "default_user_discount")
|
||||
op.drop_column("park_tenants", "default_company_discount")
|
||||
if _column_exists("park_tenants", "default_user_discount"):
|
||||
op.drop_column("park_tenants", "default_user_discount")
|
||||
if _column_exists("park_tenants", "default_company_discount"):
|
||||
op.drop_column("park_tenants", "default_company_discount")
|
||||
|
||||
Reference in New Issue
Block a user