Skip to content

warn and deprecate for back_populates with viewonly=True #5149

@marty-se

Description

@marty-se

We're having some issues with back_populates of relationships referring to other relationships with viewonly=True. We get duplicates in the relationship list that the back_populates refers to. Test case:

import sqlalchemy
from sqlalchemy import Column
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import attributes
from sqlalchemy.orm import relationship

Base = declarative_base()


class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    boston_addresses = relationship(
        "Address",
        # primaryjoin="and_(User.id==Address.user_id, Address.city=='Boston')",  # Not necessary but shows the use case
        viewonly=True)  # Setting viewonly = False prevents the issue


class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('user.id'))
    user = relationship('User', back_populates='boston_addresses')

    city = Column(String)


def main():
    session = setup_database_and_session()

    user = User()

    session.add(user)
    session.commit()

    # user.boston_addresses   # Reading the value here prevents the issue

    address = Address(user=user, city='Boston')
    
    actual = user.boston_addresses
    expected = [address]
    assert actual == expected, f"{actual} != {expected}"


def setup_database_and_session():
    engine = sqlalchemy.create_engine("sqlite://")
    session_maker = sqlalchemy.orm.sessionmaker(bind=engine)
    session = session_maker()
    Base.metadata.create_all(engine)
    return session


if __name__ == "__main__":
    main()

Result:

AssertionError: [<__main__.Address object at 0x10d95aeb8>, <__main__.Address object at 0x10d95aeb8>] != [<__main__.Address object at 0x10d95aeb8>]

Metadata

Metadata

Assignees

No one assigned

    Labels

    alchemy 2goes along with the 2.0 milestone to aid in searchingbugSomething isn't workingorm

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions