postgresql Alembic迁移将串行字段转换为整数

z9smfwbn  于 2023-04-05  发布在  PostgreSQL
关注(0)|答案(2)|浏览(144)

我最初将我的一个SQLAlchemy模型定义为:

class StreetSegment(db.Model):
    id = db.Column(db.Integer, autoincrement=True)    # surrogate ID
    seg_id = db.Column(db.Integer, primary_key=True)  # assigned in another system; don't increment

没有意识到seg_id将成为Postgres数据库中的SERIAL字段。我真正想要的是带有PK约束的INTEGER字段(没有自动增量)。我关闭了自动增量,如下所示:

class StreetSegment(db.Model):
    id = db.Column(db.Integer, autoincrement=True)
    seg_id = db.Column(db.Integer, primary_key=True, autoincrement=False)  # <--- see here

但是当我在Alembic中运行migrate时,没有反映出这种变化。我还尝试编写了一个自定义迁移,其中包含以下操作:

def upgrade():
    op.alter_column('street_segment', 'seg_id', autoincrement=False)

def downgrade():
    op.alter_column('street_segment', 'seg_id', autoincrement=True)

但这给出了警告autoincrement and existing_autoincrement only make sense for MySQL。所以我的问题是:在Postgres中,有没有什么方法可以使用Alembic将SERIAL转换为INTEGER

toe95027

toe950271#

只需将类型显式设置为您想要的类型。这应该可以工作:

op.alter_column('street_segment', 'seg_id', _type=Integer)
06odsfpq

06odsfpq2#

我最终使用了以下代码,基本上使用了原始sql查询,它删除了默认值,使其成为一个整数(因为serial是整数,默认值为序列值)。对于降级,创建序列并设置列的默认值。

table = "users"
id_column = "id"

def upgrade():
    op.execute(f"ALTER TABLE {table} ALTER COLUMN {id_column} DROP DEFAULT")
    op.execute(f"DROP SEQUENCE {table}_{id_column}_seq")

    # ALTER TABLE yourtable ALTER COLUMN yourcolumn DROP DEFAULT;

def downgrade():
    op.execute(f"CREATE SEQUENCE {table}_{id_column}_seq")
    op.execute(f"SELECT SETVAL('{table}_{id_column}_seq',  (SELECT MAX({id_column})+1 FROM {table}));")
    op.execute(f"ALTER TABLE {table} ALTER {id_column} SET DEFAULT nextval('{table}_{id_column}_seq')")
    op.execute(f"ALTER SEQUENCE {table}_{id_column}_seq OWNED BY {table}.{id_column}")

相关问题