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.

Reply via email to