使用 sqlmodel 的 alembic 迁移尝试更改主键列
Posted
技术标签:
【中文标题】使用 sqlmodel 的 alembic 迁移尝试更改主键列【英文标题】:alembic migrations with sqlmodel attempts to alter primary key colum 【发布时间】:2021-12-20 06:21:03 【问题描述】:鉴于此模型:
from typing import Optional
from sqlmodel import SQLModel, Field
class SongBase(SQLModel):
name: str
artist: str = Field(index=False)
#label: Optional[str] = Field(None, index=False)
year: Optional[int] = Field(None, index=False)
class Song(SongBase, table=True):
id: int = Field(default=None, primary_key=True, index=False)
class SongCreate(SongBase):
pass
我使用alembic revision --autogenerate -m "init"
创建了一个初始的alembic修订,然后使用alembic upgrade head
应用它。
现在我取消注释label
字段,然后运行alembic revision --autogenerate -m "label"
。
我的迁移显示如下:
revision = '083a8e84f047'
down_revision = 'c1b2ad7d0a39'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('song', sa.Column('label', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
op.alter_column('song', 'id',
existing_type=sa.INTEGER(),
nullable=True,
autoincrement=True)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('song', 'id',
existing_type=sa.INTEGER(),
nullable=False,
autoincrement=True)
op.drop_column('song', 'label')
# ### end Alembic commands ###
为什么 alembic 试图更改 id 字段? 我们正在尝试评估 sqlmodel/alembic 以查看它是否适用于生产工作负载,并且必须手动进行迁移以摆脱这些主键操作对我来说似乎有点危险。我做错了什么让 alembic 想以这种方式编辑我的主键字段吗?
编辑:为了披露,模型来自这篇文章/示例:https://github.com/testdrivenio/fastapi-sqlmodel-alembic
【问题讨论】:
仅供参考:我用常规的 sqlaclhemy 模型而不是 SqlModels 测试了另一个项目,我仍然可以看到它确实不应该触及的 alembic 接触字段。我不知道我正在运行的 postgres 版本和 alembic 之间是否存在差异。这东西看起来很危险。 【参考方案1】:在此处进行了更多研究,并查看了 alembic repo 中的一些 github 讨论。我认为发生的情况是 id
列没有明确设置 alembic 似乎需要的 nullable=False
。然后在最初的“迁移”期间,它忽略了这个事实(如果那是一个错误,idk),这使得模型从一开始就不同步。因此,每次迁移都会尝试使其重新同步。
无论如何,修复似乎总是显式声明主键字段的可为空参数:
class SongBase(SQLModel):
name: str
artist: str
label: str = Field(index=False)
year: Optional[int] = None
class Song(SongBase, table=True):
id: int = Field(default=None, primary_key=True, nullable=False)
class SongCreate(SongBase):
pass
【讨论】:
以上是关于使用 sqlmodel 的 alembic 迁移尝试更改主键列的主要内容,如果未能解决你的问题,请参考以下文章