This commit is contained in:
jxxghp
2025-08-19 12:02:53 +08:00
parent 4bc24f3b00
commit be08d6ebb5

View File

@@ -0,0 +1,125 @@
"""2.1.9
Revision ID: d58298a0879f
Revises: 4666ce24a443
Create Date: 2025-08-19 11:56:39.652032
"""
import contextlib
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import sqlite
from app.core.config import settings
# revision identifiers, used by Alembic.
revision = 'd58298a0879f'
down_revision = '4666ce24a443'
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
if settings.DB_TYPE.lower() == "postgresql":
# PostgreSQL序列修复将SQLite的Sequence转换为PostgreSQL的Identity
fix_postgresql_sequences()
# ### end Alembic commands ###
def downgrade() -> None:
pass
def fix_postgresql_sequences():
"""
修复PostgreSQL数据库中的序列问题
将SQLite迁移过来的Sequence转换为PostgreSQL的Identity
"""
connection = op.get_bind()
# 获取所有表名
result = connection.execute(sa.text("""
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
AND table_type = 'BASE TABLE'
"""))
tables = [row[0] for row in result.fetchall()]
print(f"发现 {len(tables)} 个表需要检查序列")
for table_name in tables:
fix_table_sequence(connection, table_name)
def fix_table_sequence(connection, table_name):
"""
修复单个表的序列
"""
try:
# 检查表是否有id列
result = connection.execute(sa.text(f"""
SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_name = '{table_name}'
AND column_name = 'id'
"""))
id_column = result.fetchone()
if not id_column:
print(f"{table_name} 没有id列跳过")
return
column_name, data_type, is_nullable, column_default = id_column
# 检查是否已经是Identity类型
if column_default and 'GENERATED BY DEFAULT AS IDENTITY' in column_default:
print(f"{table_name} 的id列已经是Identity类型跳过")
return
# 检查是否有序列
result = connection.execute(sa.text(f"""
SELECT sequence_name
FROM information_schema.sequences
WHERE sequence_name LIKE '{table_name}_id_seq'
"""))
sequence_exists = result.fetchone()
if sequence_exists:
print(f"{table_name} 存在序列,需要修复")
convert_to_identity(connection, table_name)
except Exception as e:
print(f"修复表 {table_name} 序列时出错: {e}")
def convert_to_identity(connection, table_name):
"""
将序列转换为Identity
"""
try:
# 获取当前序列的最大值
result = connection.execute(sa.text(f"""
SELECT COALESCE(MAX(id), 0) + 1 as next_value
FROM {table_name}
"""))
next_value = result.fetchone()[0]
# 删除旧的序列
connection.execute(sa.text(f"DROP SEQUENCE IF EXISTS {table_name}_id_seq"))
# 修改列定义添加Identity
connection.execute(sa.text(f"""
ALTER TABLE {table_name}
ALTER COLUMN id SET DATA TYPE INTEGER,
ALTER COLUMN id SET DEFAULT NULL,
ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY (START WITH {next_value})
"""))
print(f"{table_name} 序列已转换为Identity起始值为 {next_value}")
except Exception as e:
print(f"转换表 {table_name} 序列时出错: {e}")
raise