Skip to content

uselist not inferred correctly for relationship when a non-string type annotation is used in Mapped #10815

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
DavideCanton opened this issue Jan 2, 2024 · 4 comments
Labels
bug Something isn't working near-term release addition to the milestone which indicates this should be in a near-term release orm - annotated declarative issues with the new annotations-based declarative ORM approach orm
Milestone

Comments

@DavideCanton
Copy link

Describe the bug

It seems that the one-to-one example for a relationship does not infer correctly the uselist value if the mapped argument is not a string annotation.

The difference is in the value inferred for uselist in the Parent.child relationship, that is correctly inferred to False in the example, while it is inferred to True if the type annotation for child is changed to Mapped[Child].

In the docs of the uselist parameter (https://docs.sqlalchemy.org/en/20/orm/relationship_api.html#sqlalchemy.orm.relationship.params.uselist) it is stated that uselist may be derived from whether the mapped argument is a collection or not, but in this case Mapped[Child] is not a collection, so I would expect uselist set to False.

Optional link from https://docs.sqlalchemy.org which documents the behavior that is expected

https://docs.sqlalchemy.org/en/20/orm/relationship_api.html#sqlalchemy.orm.relationship.params.uselist

SQLAlchemy Version in Use

2.0.24

DBAPI (i.e. the database driver)

psycopg2

Database Vendor and Major Version

PostgreSQL 13

Python Version

3.10

Operating system

Windows

To Reproduce

from sqlalchemy import ForeignKey
from sqlalchemy.orm import Mapped, mapped_column, relationship, DeclarativeBase


class Base(DeclarativeBase):
    pass


class Child(Base):
    __tablename__ = "child"

    id: Mapped[int] = mapped_column(primary_key=True)
    parent_id: Mapped[int] = mapped_column(ForeignKey("parent.id"))
    parent: Mapped["Parent"] = relationship(back_populates="child")


class Parent(Base):
    __tablename__ = "parent"

    id: Mapped[int] = mapped_column(primary_key=True)
    # this relationship has uselist=True
    child: Mapped[Child] = relationship(back_populates="parent")
    # this relationship has uselist=False
    # child: Mapped["Child"] = relationship(back_populates="parent")

Error

# Copy the complete stack trace and error message here, including SQL log output if applicable.

Additional context

No response

@DavideCanton DavideCanton added the requires triage New issue that requires categorization label Jan 2, 2024
@DavideCanton
Copy link
Author

Just to add some further information, adding from __future__ import annotations makes it work correctly with Mapped[Child].

@sqla-tester
Copy link
Collaborator

Mike Bayer has proposed a fix for this issue in the main branch:

TODO / WIP: fix lh relationship annotation https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5059

@zzzeek zzzeek added bug Something isn't working orm near-term release addition to the milestone which indicates this should be in a near-term release orm - annotated declarative issues with the new annotations-based declarative ORM approach and removed requires triage New issue that requires categorization labels Jan 2, 2024
@zzzeek zzzeek added this to the 2.0.x milestone Jan 2, 2024
@zzzeek
Copy link
Member

zzzeek commented Jan 2, 2024

thanks for reporting

@sqla-tester
Copy link
Collaborator

Mike Bayer has proposed a fix for this issue in the rel_2_0 branch:

force uselist=False for all collection class not present https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5060

sqlalchemy-bot pushed a commit that referenced this issue Jan 2, 2024
Fixed issue where ORM Annotated Declarative would mis-interpret the left
hand side of a relationship without any collection specified as
uselist=True if the left type were given as a class and not a string,
without using future-style annotations.

Fixes: #10815
Change-Id: I85daccec03f7e6ea3b49eb07c06e0f85e361a1c0
(cherry picked from commit c1139c2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working near-term release addition to the milestone which indicates this should be in a near-term release orm - annotated declarative issues with the new annotations-based declarative ORM approach orm
Projects
None yet
Development

No branches or pull requests

3 participants