You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为SQLAlchemy Mixins正确添加MyPy类型注解?

解决方案:用Protocol和交集类型实现类型标注

方案思路

通过Protocol定义"包含file字段"的类型约束,结合交集类型(Python 3.10+)或typing_extensions.Intersection(旧版本Python),让类型检查器识别同时满足"SQLAlchemy ORM模型"和"拥有file字段"的类。既无需创建额外ORM模型类,又能保证类型安全。

代码实现

1. 定义HasFile协议

创建仅用于类型标注的Protocol,描述具有file类属性的类型:

from typing import Protocol, ClassVar
from sqlalchemy import Column, String

class HasFile(Protocol):
    file: ClassVar[Column[String]]

这个Protocol仅用于类型检查,不会被SQLAlchemy注册为ORM模型。

2. 约束TypeVar并标注函数

使用交集类型约束TypeVar,确保传入的model既是BaseModel的子类,又实现HasFile协议:

from typing import List, Type, TypeVar
from sqlalchemy.orm import Session

# Python 3.10+ 支持原生交集类型
T = TypeVar("T", bound=BaseModel & HasFile)

# Python 3.9及以下版本,需安装typing_extensions后使用
# from typing_extensions import Intersection
# T = TypeVar("T", bound=Intersection[BaseModel, HasFile])

def file_query(db: Session, model: Type[T], file: str) -> List[T]:
    return db.query(model).filter(model.file == file).all()

效果说明

  • 类型检查器(如mypy、pyright)会自动验证:传入的model必须是继承BaseModel的ORM类,且包含file字段,非法传入会直接报错。
  • 无需创建额外中间ORM类,避免被SQLAlchemy错误注册为不存在的数据库表。
  • 函数返回值的类型会被正确推导为传入模型的实例列表,保持代码的类型一致性。

内容的提问来源于stack exchange,提问作者Albert Iribarne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:57:24