SQLAlchemy 2.0 Select API类型标注报错,求解决方案
SQLAlchemy 2.0 + Mypy 类型标注问题排查
环境信息
- Python 3.11
- Mypy 1.4.0
- SQLAlchemy 2.0(采用最新查询模式)
- 已确认无冲突stubs
问题代码
if TYPE_CHECKING: from sqlalchemy.orm import Session from sqlalchemy import Row, Sequence, Tuple from app.models import User as UserDBModel UserRow = Row[Tuple[UserDBModel]] def get_users(db: Session, skip: int = 0, limit: int = 100) -> Sequence[UserRow]: return db.scalars(select(UserDBModel).offset(skip).limit(limit)).all()
报错信息
- 针对
UserRow的报错:
Type argument "sqlalchemy.sql.elements.Tuple" of "Row" must be a subtype of "tuple[Any, ...]" [type-var]
Value of type variable "_TP" of "Row" cannot be "sqlalchemy.sql.elements.Tuple" [type-var]
- 针对函数返回值的报错:
Incompatible return value type (got "typing.Sequence[Row[tuple[User]]]", expected "sqlalchemy.sql.schema.Sequence") [return-value]
疑问
已按报错提示调整但无效,替换Sequence导入路径后问题依旧:
- 是否存在操作错误?
- 若操作无误,有无规避错误的方法?
- 是否属于上游问题,需暂时放弃显式标注?
解决方案
1. 修正UserRow类型定义
SQLAlchemy的Row泛型参数需要Python原生tuple类型,而非SQLAlchemy的Tuple数据库元素类型,直接修改为:
UserRow = Row[tuple[UserDBModel]]
2. 修正Sequence导入
报错是因为误导入了SQLAlchemy的Sequence(数据库序列对象),我们需要的是Python标准库的类型标注用Sequence,调整导入:
if TYPE_CHECKING: from sqlalchemy.orm import Session from sqlalchemy import Row from typing import Sequence
3. 简化返回值类型(优化方案)
使用db.scalars()查询单个模型类时,返回结果会自动提取每行的单个模型实例,无需用Row[tuple[...]]包装,可直接简化函数:
def get_users(db: Session, skip: int = 0, limit: int = 100) -> Sequence[UserDBModel]: return db.scalars(select(UserDBModel).offset(skip).limit(limit)).all()
4. 临时规避方案
如果上述方法仍存在兼容问题,可临时用注释屏蔽报错,或用Any过渡:
def get_users(db: Session, skip: int = 0, limit: int = 100) -> Sequence[UserRow]: # type: ignore[return-value] return db.scalars(select(UserDBModel).offset(skip).limit(limit)).all()
内容的提问来源于stack exchange,提问作者Noam Hudson
相关产品推荐
相关产品推荐

