Codes with typehint errors when using flask-sqlalchemy
# -*- coding: UTF-8 -*-
try:
from typing import List
except ImportError:
from builtins import list as List
from flask_sqlalchemy import SQLAlchemy
import sqlalchemy as sa
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.orm import DeclarativeBase, MappedAsDataclass
class Base(DeclarativeBase, MappedAsDataclass):
"""The base class for creating SQLAlchemy models.
All mixins are defined in the mro list.
All metadata of are defined as attributes.
"""
db = SQLAlchemy(model_class=Base)
roles = db.Table(
"role_users",
sa.Column("user_id", sa.ForeignKey("user.id"), primary_key=True),
sa.Column("role_id", sa.ForeignKey("role.id"), primary_key=True),
)
class User(db.Model):
id: Mapped[int] = mapped_column(primary_key=True, init=False)
# Expression of type "RelationshipProperty[Any]" cannot be assigned to declared type "Mapped[List[Role]]"
# "RelationshipProperty[Any]" is incompatible with "Mapped[List[Role]]"Pylance[reportAssignmentType]
# (https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportAssignmentType)
roles: Mapped[List["Role"]] = db.relationship(
"Role", secondary=roles, back_populates="users", default_factory=list
)
class Role(db.Model):
id: Mapped[int] = mapped_column(primary_key=True, init=False)
# Expression of type "RelationshipProperty[Any]" cannot be assigned to declared type "Mapped[List[User]]"
# "RelationshipProperty[Any]" is incompatible with "Mapped[List[User]]"Pylance[reportAssignmentType]
# (https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportAssignmentType)
users: Mapped[List["User"]] = db.relationship(
"User", secondary=roles, back_populates="roles", default_factory=list
)
Codes working perfectly if only using sqlalchemy
# -*- coding: UTF-8 -*-
try:
from typing import List
except ImportError:
from builtins import list as List
import sqlalchemy as sa
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.orm import DeclarativeBase, MappedAsDataclass
class Base(DeclarativeBase, MappedAsDataclass):
"""The base class for creating SQLAlchemy models.
All mixins are defined in the mro list.
All metadata of are defined as attributes.
"""
roles = sa.Table(
"role_users",
Base.metadata,
sa.Column("user_id", sa.ForeignKey("user.id"), primary_key=True),
sa.Column("role_id", sa.ForeignKey("role.id"), primary_key=True),
)
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True, init=False)
roles: Mapped[List["Role"]] = relationship(
"Role", secondary=roles, back_populates="users", default_factory=list
)
class Role(Base):
__tablename__ = "roles"
id: Mapped[int] = mapped_column(primary_key=True, init=False)
users: Mapped[List["User"]] = relationship(
"User", secondary=roles, back_populates="roles", default_factory=list
)
Problem Description
The typehint of
should be
sq_orm.Relationship[...]
, notsq_orm.RelationshipProperty[...]
.The mismatch of the typehint causes the manual annotation supported by
sqlalchemy
fails:How to fix it
Go here: https://github.com/pallets-eco/flask-sqlalchemy/blob/42a36a3cb604fd39d81d00b54ab3988bbd0ad184/src/flask_sqlalchemy/extension.py#L953-L963
Make this modification:
Things will get corrected.
It is also recommended to modify this place:
https://github.com/pallets-eco/flask-sqlalchemy/blob/42a36a3cb604fd39d81d00b54ab3988bbd0ad184/src/flask_sqlalchemy/extension.py#L977-L979
But the following place should NOT be changed, because it is consistent with
sq_orm
: https://github.com/pallets-eco/flask-sqlalchemy/blob/42a36a3cb604fd39d81d00b54ab3988bbd0ad184/src/flask_sqlalchemy/extension.py#L965-L967Codes with typehint errors when using
flask-sqlalchemy
Codes working perfectly if only using
sqlalchemy
Environment:
3.10.13
3.1.1
2.0.28