Is the a way to solve the issue with mypy and sqlalchemy when defining the expresison of a hybrid property, it triggered name <func> already defined
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}"
@full_name.expression
def name(cls) -> str:
return cls.first_name + " " + cls.last_name
I don’t want to install external stubs package or ignore it with # type : ignore.
Is there a way to rename the expression or something else ?
>Solution :
I’ve faced a similar issue with mypy when using SQLAlchemy’s hybrid_property. The problem arises because you’re defining the method name twice: once as an instance method and once as a class method for the expression, which causes mypy to report a duplicate definition error.
To resolve this without installing external stubs or using # type: ignore, you can rename the expression method and explicitly assign it to the hybrid_property. Here’s how you can modify your code:
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = 'user'
id: Mapped[int] = mapped_column(primary_key=True)
first_name: Mapped[str] = mapped_column(String(100), nullable=False)
last_name: Mapped[str] = mapped_column(String(100), nullable=False)
def _get_name(self) -> str:
return f"{self.first_name} {self.last_name}"
@classmethod
def _name_expr(cls):
return cls.first_name + " " + cls.last_name
name = hybrid_property(fget=_get_name, expr=_name_expr)
By defining _get_name and _name_expr with different names, you avoid redefining name, and mypy won’t complain about duplicate definitions. Then, you assign them to the hybrid_property named name.
This approach keeps your code clean and type-safe without suppressing type checking or adding external packages.