SQLAlchemy混合属性表达式引发Mypy‘name已定义’错误的解决方法
解决SQLAlchemy Hybrid Property触发Mypy重复定义错误的方案
首先纠正你代码里的笔误:@full_name.expression应该改成@name.expression——毕竟你的hybrid property叫name,这个错误先修掉。
接下来针对Mypy报的“name # type: ignore的解决办法:
方法一:重命名表达式方法
给类级别的表达式方法起个不一样的名字,Mypy就不会把它和实例级的name属性当成重复定义了,同时@name.expression依然能正确关联到对应的hybrid property:
from sqlalchemy import String, mapped_column from sqlalchemy.orm import Mapped, Base from sqlalchemy.ext.hybrid import hybrid_property class User(Base): first_name: Mapped[str] = mapped_column(String(100), nullable=False) last_name: Mapped[str] = mapped_column(String(100), nullable=False) @hybrid_property def name(self) -> str: return f"{self.first_name} {self.last_name}" @name.expression def _name_expression(cls) -> str: return cls.first_name + " " + cls.last_name
这里把表达式方法命名为_name_expression,既符合内部方法的命名习惯,又能避开Mypy的重复定义检查。
方法二:用@overload标注重载类型
通过typing.overload分别标注实例方法和类方法的类型,让Mypy明白name是同一个名称的两种重载形式,而非重复定义:
from typing import overload from sqlalchemy import String, mapped_column from sqlalchemy.orm import Mapped, Base from sqlalchemy.ext.hybrid import hybrid_property class User(Base): first_name: Mapped[str] = mapped_column(String(100), nullable=False) last_name: Mapped[str] = mapped_column(String(100), nullable=False) @overload def name(self) -> str: ... @overload @classmethod def name(cls) -> str: ... @hybrid_property def name(self) -> str: return f"{self.first_name} {self.last_name}" @name.expression def name(cls) -> str: return cls.first_name + " " + cls.last_name
这种方式直接告诉Mypy,name既可以作为实例方法返回字符串,也可以作为类方法返回SQL表达式字符串,自然就不会报错了。
内容的提问来源于stack exchange,提问作者Arlème Johnson
相关产品推荐
相关产品推荐

