如何将 Enum 类型与 SqlModel 和 alembic 一起使用

Tro*_*ndh 6 python sqlalchemy alembic sqlmodel

我正在尝试找到一种方法让 SqlModel 和 Alembic 协同工作。\n我的目标是不必手动编辑自动生成的 Alembic 迁移。

\n

这是我的模型类:

\n
class SongBase(SQLModel):\n    name: str\n    artist: str\n    label: str = Field(index=False)\n    year: Optional[int] = None\n\n\nclass Song(SongBase, table=True):\n    id: int = Field(default=None, primary_key=True, nullable=False)\n\n
Run Code Online (Sandbox Code Playgroud)\n

创建初始迁移等后,我添加我的枚举。在深入挖掘https://github.com/tiangolo/sqlmodel/issues?q=is%3Aissue+is%3Aopen+enum后,这是我最接近的有效方法:

\n
class SongType(enum.Enum):\n    Rock = "Rock"\n    Ballad = "Ballad"\n\n\nclass SongBase(SQLModel):\n    name: str\n    artist: str\n    label: str = Field(index=False)\n    song_type: SongType = Field(\n        sa_column=Column(\n            Enum(SongType),\n            default=None,\n            nullable=True,\n            index=False\n        )\n    )\n    year: Optional[int] = None\n\n\nclass Song(SongBase, table=True):\n    id: int = Field(default=None, primary_key=True, nullable=False)\n\n
Run Code Online (Sandbox Code Playgroud)\n

添加song_type字段生成的 alembic 迁移如下所示:

\n
def upgrade():\n    # ### commands auto generated by Alembic - please adjust! ###\n    op.add_column(\'song\', sa.Column(\'song_type\', sa.Enum(\'Rock\', \'Ballad\', name=\'songtype\'), nullable=True))\n    # ### end Alembic commands ###\n\n\ndef downgrade():\n    # ### commands auto generated by Alembic - please adjust! ###\n    op.drop_column(\'song\', \'song_type\')\n    # ### end Alembic commands ###\n\n
Run Code Online (Sandbox Code Playgroud)\n

据我所知,这类似于我找到的有关如何使 sqlalchemy 和 alembic 与迁移一起工作的文档。但是,当我尝试将此应用到我的数据库时,它失败了:

\n
2021-11-07 14:13:59.425 UTC [150] LOG:  execute __asyncpg_stmt_9__: ALTER TABLE song ADD COLUMN song_type songtype\n2021-11-07 14:13:59.425 UTC [150] ERROR:  type "songtype" does not exist at character 39\n
Run Code Online (Sandbox Code Playgroud)\n

我的包依赖树的相关部分:

\n
\xe2\x95\xb0\xe2\x94\x80 pipenv graph\nalembic==1.7.4\n  - Mako [required: Any, installed: 1.1.5]\n    - MarkupSafe [required: >=0.9.2, installed: 2.0.1]\n  - SQLAlchemy [required: >=1.3.0, installed: 1.4.26]\n    - greenlet [required: !=0.4.17, installed: 1.1.2]\nasyncpg==0.24.0\nfastapi==0.70.0\n  - pydantic [required: >=1.6.2,<2.0.0,!=1.8.1,!=1.8,!=1.7.3,!=1.7.2,!=1.7.1,!=1.7, installed: 1.8.2]\n    - typing-extensions [required: >=3.7.4.3, installed: 3.10.0.2]\n  - starlette [required: ==0.16.0, installed: 0.16.0]\n    - anyio [required: >=3.0.0,<4, installed: 3.3.4]\n      - idna [required: >=2.8, installed: 3.3]\n      - sniffio [required: >=1.1, installed: 1.2.0]\nsqlmodel==0.0.4\n  - pydantic [required: >=1.8.2,<2.0.0, installed: 1.8.2]\n    - typing-extensions [required: >=3.7.4.3, installed: 3.10.0.2]\n  - SQLAlchemy [required: >=1.4.17,<1.5.0, installed: 1.4.26]\n    - greenlet [required: !=0.4.17, installed: 1.1.2]\n  - sqlalchemy2-stubs [required: Any, installed: 0.0.2a19]\n    - typing-extensions [required: >=3.7.4, installed: 3.10.0.2]\n\n
Run Code Online (Sandbox Code Playgroud)\n

我知道我可以手动编辑我的迁移,使其看起来像这样:

\n
"""label\n\nRevision ID: 12e8618deb97\nRevises: c7350c7c7282\nCreate Date: 2021-11-07 15:21:06.927365\n\n"""\nfrom alembic import op\nimport sqlalchemy as sa\nimport sqlmodel\nfrom sqlalchemy.dialects import postgresql\nfrom app.models import SongType\n\n\n# revision identifiers, used by Alembic.\nrevision = \'12e8618deb97\'\ndown_revision = \'c7350c7c7282\'\nbranch_labels = None\ndepends_on = None\n\n\ndef upgrade():\n    song_type = postgresql.ENUM(SongType, name="song_type")\n    song_type.create(op.get_bind(), checkfirst=True)\n    # ### commands auto generated by Alembic - please adjust! ###\n    op.add_column(\'song\', sa.Column(\'song_type\', song_type, nullable=True))\n    # ### end Alembic commands ###\n\n\ndef downgrade():\n    # ### commands auto generated by Alembic - please adjust! ###\n    op.drop_column(\'song\', \'song_type\')\n    # ### end Alembic commands ###\n\n
Run Code Online (Sandbox Code Playgroud)\n

...但我的目标是看看我是否可以使 alembic 正确地自动生成迁移 - 特别是因为在我尝试应用迁移之前不会发生错误,我希望能够使这更安全。

\n

我对有关如何完成这项工作的任何指示非常感兴趣

\n