On Wed, Nov 29, 2017 at 3:32 PM, Jonathan Vanasco <jonat...@findmeon.com> wrote: > I have a potential relationship between Foo and Bar that is defined as > follows, and has usually been read-only from legacy data. > > All the code works, I just want to make sure I'm handling this case in a > clear and concise way. > > I've (over)simplified the case down to this: > > class Foo(Base): > __tablename__ = 'foo' > id = Column(Integer, primary_key=True) > name = Column(Unicode(6), nullable=False) > > bar = relationship("Bar", > primaryjoin="Foo.id==Bar.id__foo", > uselist=False, > back_populates='foo', > ) > > class Bar(Base): > __tablename__ = 'bar' > id = Column(Integer, primary_key=True) > name = Column(Unicode(6), nullable=False) > id__foo = Column(Integer, ForeignKey("foo.id"), nullable=True, ) > > foo = relationship("Foo", > primaryjoin="Bar.id__foo==Foo.id", > uselist=False, > back_populates='bar', > ) > > > In a current feature ticket, I'm in a situation where I need to upgrade an > instance of Foo with an instance Bar and dealing with some get/create > functions that do their own flushes. That block of code basically looks > like this: > > def getcreate_bar(bar_name, foo=None): > b = s.query(Bar).filter(Bar.name==bar_name).first() > if not b: > b = Bar() > b.name = bar_name > b.id__foo = foo.id if foo else None > s.add(b) > s.flush(objects=[b, ]) > return b > > foo = s.query(Foo).get(1) > if not foo.bar: > bar = getcreate_bar(bar_name, foo) > foo.bar = bar # attribute needed for additional work > s.flush(objects=[foo, ]) # flush only needed if bar isn't new > > > my question covers where I create the `bar` and make it instantly available > as a foo attribute. Is there a better way to handle this or make it more > readable?
One way would be to make a @property or hybrid that generates it, but maybe you want to try this new event: http://docs.sqlalchemy.org/en/latest/orm/events.html?highlight=init_scalar#sqlalchemy.orm.events.AttributeEvents.init_scalar it's probably only tested for scalar values but in theory should work for objects too. But you'd be testing that that actually works b.c. I'm not sure. If I create a new foo, the flush of `foo` doesn't emit SQL after > sqlalchemy decides it doesn't have to. I do need that flush if I already > had bar, but it wasn't associated to foo. > > > > -- > 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.