自动生成Alembic修订版本时出现SQLModel错误
问题描述
我有一个repository.models.models文件,代码如下:
from datetime import date from typing import Type, Optional, List from sqlmodel import SQLModel, Field, Relationship class Compra(SQLModel, table=True): com_id: Optional[int] = Field(default=None, primary_key=True) data: Type[date] item: str valor: float forn_id: Optional[int] = Field(default=None, foreign_key="fornecedor.forn_id") fornecedor: Optional["Fornecedor"] = Relationship(back_populates="compras") class Fornecedor(SQLModel, table=True): forn_id: Optional[int] = Field(default=None, primary_key=True) nome: str rating: int = 5 compras: List[Compra] = Relationship(back_populates="fornecedores")
执行Alembic自动生成修订命令:
alembic revision --autogenerate -m "Create models"
触发如下错误回溯:
Traceback (most recent call last): File "/home/andre/.cache/pypoetry/virtualenvs/rest-api-for-bizagi-9TxUSah3-py3.10/bin/alembic", line 8, in <module> sys.exit(main()) File "/home/andre/.cache/pypoetry/virtualenvs/rest-api-for-bizagi-9TxUSah3-py3.10/lib/python3.10/site-packages/alembic/config.py", line 590, in main CommandLine(prog=prog).main(argv=argv) File "/home/andre/.cache/pypoetry/virtualenvs/rest-api-for-bizagi-9TxUSah3-py3.10/lib/python3.10/site-packages/alembic/config.py", line 584, in main self.run_cmd(cfg, options) File "/home/andre/.cache/pypoetry/virtualenvs/rest-api-for-bizagi-9TxUSah3-py3.10/lib/python3.10/site-packages/alembic/config.py", line 561, in run_cmd fn( File "/home/andre/.cache/pypoetry/virtualenvs/rest-api-for-bizagi-9TxUSah3-py3.10/lib/python3.10/site-packages/alembic/command.py", line 229, in revision script_directory.run_env() File "/home/andre/.cache/pypoetry/virtualenvs/rest-api-for-bizagi-9TxUSah3-py3.10/lib/python3.10/site-packages/alembic/script/base.py", line 569, in run_env util.load_python_file(self.dir, "env.py") File "/home/andre/.cache/pypoetry/virtualenvs/rest-api-for-bizagi-9TxUSah3-py3.10/lib/python3.10/site-packages/alembic/util/pyfiles.py", line 94, in load_python_file module = load_module_py(module_id, path) File "/home/andre/.cache/pypoetry/virtualenvs/rest-api-for-bizagi-9TxUSah3-py3.10/lib/python3.10/site-packages/alembic/util/pyfiles.py", line 110, in load_module_py spec.loader.exec_module(module) # type: ignore File "<frozen importlib._bootstrap_external>", line 883, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "/home/andre/Projects/rest_api_for_bizagi/migrations/env.py", line 9, in <module> from repository.models import Fornecedor, Compra # noqa File "/home/andre/Projects/rest_api_for_bizagi/./repository/models/__init__.py", line 1, in <module> from .models import Fornecedor # noqa File "/home/andre/Projects/rest_api_for_bizagi/./repository/models/models.py", line 6, in <module> class Compra(SQLModel, table=True): File "/home/andre/.cache/pypoetry/virtualenvs/rest-api-for-bizagi-9TxUSah3-py3.10/lib/python3.10/site-packages/sqlmodel/main.py", line 293, in __new__ col = get_column_from_field(v) File "/home/andre/.cache/pypoetry/virtualenvs/rest-api-for-bizagi-9TxUSah3-py3.10/lib/python3.10/site-packages/sqlmodel/main.py", line 421, in get_column_from_field sa_type = get_sqlachemy_type(field) File "/home/andre/.cache/pypoetry/virtualenvs/rest-api-for-bizagi-9TxUSah3-py3.10/lib/python3.10/site-packages/sqlmodel/main.py", line 375, in get_sqlachemy_type if issubclass(field.type_, str): TypeError: issubclass() arg 1 must be a class
已确认Alembic配置正常且能连接数据库(首次空白修订成功更新数据库),若省略table=True参数则生成空白修订。请问该错误的原因是什么?
错误原因及修复方案
核心错误原因
Compra类中data字段的类型注解错误:
data: Type[date]
这里误用了Type[date](表示date类本身的类型),但SQLModel需要的是字段值的类型注解date(表示字段存储date类型的实例)。当SQLModel尝试将Type[date]映射为SQLAlchemy类型时,执行issubclass(field.type_, str)时,field.type_是Type[date]而非合法的类对象,因此抛出TypeError。
额外修正点
Fornecedor类的Relationship中back_populates值不匹配:
原代码中Fornecedor.compras的back_populates设为"fornecedores",但Compra类中对应的关联字段是fornecedor,需改为:
compras: List[Compra] = Relationship(back_populates="fornecedor")
修复后的完整代码
from datetime import date from typing import Optional, List from sqlmodel import SQLModel, Field, Relationship class Compra(SQLModel, table=True): com_id: Optional[int] = Field(default=None, primary_key=True) data: date # 移除Type[]修正类型注解 item: str valor: float forn_id: Optional[int] = Field(default=None, foreign_key="fornecedor.forn_id") fornecedor: Optional["Fornecedor"] = Relationship(back_populates="compras") class Fornecedor(SQLModel, table=True): forn_id: Optional[int] = Field(default=None, primary_key=True) nome: str rating: int = 5 compras: List[Compra] = Relationship(back_populates="fornecedor") # 修正back_populates值
内容的提问来源于stack exchange,提问作者André Carvalho
相关产品推荐
相关产品推荐

