Dear Michael and SQLAlchemy users, I have what may be a minor bug report, and a feature request.
The possible bug is that creating an instance of a mapped association object<https://docs.sqlalchemy.org/en/latest/orm/basic_relationships.html#association-object> adds it to an attribute-mapped collection, but using the wrong key. In the following example, although the key is a date which is initialised, the key used is None instead. The feature request is for some way to use an association_proxy on such a collection to return the instances of the collection (as though it was a relationship to the target table), instead of a dictionary from keys to target instances. I think it might be possible by supplying a proxy_factory and a getset_factory, but I can't find any examples, and it's quite difficult to set up in any case. Here is the sample code illustrating both: from datetime import date from sqlalchemy import Column, Date, ForeignKey, Integer, Text, create_engine from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship, sessionmaker from sqlalchemy.orm.collections import attribute_mapped_collection Base = declarative_base() class Pet(Base): __tablename__ = 'pet' id = Column(Integer, primary_key=True) name = Column(Text) class HousePet(Base): __tablename__ = 'house_pet' id_pet = Column(Integer, ForeignKey(Pet.id), primary_key=True) id_house = Column(Integer, ForeignKey("house.id"), primary_key=True) date_moved_in = Column(Date) pet = relationship(Pet) # house backref created by House.date_to_new_pet, not here: # house = relationship("House") class House(Base): __tablename__ = 'house' id = Column(Integer, primary_key=True) address = Column(Text) date_to_new_pet = relationship(HousePet, cascade='all, delete-orphan', collection_class=attribute_mapped_collection("date_moved_in"), backref=__tablename__) pets = association_proxy('date_to_new_pet', 'pet') engine = create_engine('sqlite://') Base.metadata.create_all(engine) DBSession = sessionmaker(bind=engine) session = DBSession(autocommit=True) downing = House(address="10 Downing Street") larry = Pet(name="Larry the Cat") larry_at_home = HousePet(pet=larry, house=downing, date_moved_in=date(2007, 1, 1)) # This should pass, but does not because the collection key was not set: try: assert downing.date_to_new_pet == {larry_at_home.date_moved_in: larry}, str(downing.date_to_new_pet) except AssertionError as exc: print(exc) # How can we make House.pets be a list-like collection instead of dict-like? try: assert downing.pets == [larry], str(downing.pets) except AssertionError as exc: print(exc) # It would be nice to be able to update this collection as well: downing.pets = [] assert downing.date_to_new_pet == {}, str(downing.date_to_new_pet) downing.pets = [larry] assert downing.date_to_new_pet == {larry_at_home.date_moved_in: larry}, str(downing.date_to_new_pet) I would like the latter to work because the documentation for association objects<https://docs.sqlalchemy.org/en/latest/orm/basic_relationships.html#association-object> warns about the dangers of unsynchronised collections, and suggests using an association_proxy instead of a relationship with a secondary table, which works fine for normal relationship collections, but is very unnatural for attribute-mapped ones. Thanks in advance for your consideration. Cheers, Chris. This email is confidential. If you are not the intended recipient, please advise us immediately and delete this message. The registered name of Cantab- part of GAM Systematic is Cantab Capital Partners LLP. See - http://www.gam.com/en/Legal/Email+disclosures+EU for further information on confidentiality, the risks of non-secure electronic communication, and certain disclosures which we are required to make in accordance with applicable legislation and regulations. If you cannot access this link, please notify us by reply message and we will send the contents to you. GAM Holding AG and its subsidiaries (Cantab – GAM Systematic) will collect and use information about you in the course of your interactions with us. Full details about the data types we collect and what we use this for and your related rights is set out in our online privacy policy at https://www.gam.com/en/legal/privacy-policy. Please familiarise yourself with this policy and check it from time to time for updates as it supplements this notice. -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.