On Wed, Jan 10, 2018 at 1:03 PM, Matt Schmidt <slo...@gmail.com> wrote: > I have a small companion library that I wrote for model-to-dict > serialization. I just updated to 1.2.0 and one of my tests is failing -- > > https://gitlab.com/sloat/SerialAlchemy/blob/master/tests/test_to_dict.py#L193 > > In 1.1.x, it worked as expected, but in 1.2, the primary-key is added to the > serialized profile field. So the output is now: > > { > 'firstname': 'test', > 'profile': { > 'id': 3, > 'somefield': 'somevalue' > }, > } > > > I just wanted to make sure this is expected behavior from SQLAlchemy. It's > not a problem for me to update the test, it won't impact the actual > functionality of the library.
>From making a test (below) I can see this behavior changed within the 1.1 series, not in 1.2. Up through 1.1.13 it gets: {'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x7f8046c5df90>, 'data': u'a'} in 1.1.14 it becomes: {'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x7f1e0d217e50>, 'data': u'a', 'id': 1} A bisect brings us to: https://bitbucket.org/zzzeek/sqlalchemy/issues/4048 this shows there was a bug with undeferral as coming off of a joined eager load, where the keys to be "undeferred" weren't being acted upon properly. pdbing into the example shows that the "id" attribute is being loaded when load_only() is used, but the bug fixed in 4048 is preventing the attribute from being populated onto the object properly. This implies that the primary key attributes are loaded even when load_only() seems to exclude them, and that this is the normally established behavior, here not occurring due to a bug. This can be confirmed if we change the joinedload to lazyload: a1 = s.query(A).options(lazyload(A.bs).load_only('data')).one() print a1.bs[0].__dict__ in an early 1.1 version 1.1.5, we get "id": {'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x7fddb21cffd0>, 'data': u'a', 'id': 1} therefore the bug fixed in 4048, while it wasn't testing for this specific condition, is repairing the deferral rules for attributes coming off of a joinedload, and under that repair the primary key attributes are now being populated as would be the case when load_only() is used in other contexts. This is not to say that the primary key attributes being present under load_only() is a desirable feature, only that this is how it seems to have been working overall, and the change here is repairing a bug that was masking the attribute from completing its population. On your end I would recommend making your test not depend on the primary key attributes being there or not so that changes here won't break your tests. from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class A(Base): __tablename__ = 'a' id = Column(Integer, primary_key=True) bs = relationship("B") class B(Base): __tablename__ = 'b' id = Column(Integer, primary_key=True) a_id = Column(ForeignKey('a.id')) data = Column(String) e = create_engine("sqlite://", echo=True) Base.metadata.create_all(e) s = Session(e) s.add(A(bs=[B(data='a'), B(data='b')])) s.commit() a1 = s.query(A).options(joinedload(A.bs).load_only('data')).one() print a1.bs[0].__dict__ > > -Matt > > -- > 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. -- 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.