I think that the "set" event is sufficient in most of my use-cases. Thanks!
On Friday, January 1, 2016 at 10:11:45 PM UTC+2, Michael Bayer wrote:
>
>
>
> On 01/01/2016 01:56 PM, Yegor Roganov wrote:
> > Is there an option to make sqlalchemy populate foreign key column(s)
> > when a relationship is set?
> > Basically I want the following:
> >
> > child.parent = parent
> > assert child.parent_id == parent.id
>
> just call session.flush() and this assertion will succeed.
>
> There is an event which is called when the "set" occurs, however calling
> session.flush() here wouldn't work because the event is fired before the
> actual set operation takes place.
>
> Automating this flush would require use of a @property so that the "set"
> event of "child.parent" can be intercepted and some code can be invoked
> after the actual set takes place. The attribute would then be mapped
> to an alternate name like "_parent".
>
> Alternatively, if the action here doesn't need to be generalized, just
> set the foreign key yourself with the "set" event and the flush wouldn't
> be needed:
>
> @event.listens_for(child.parent, "set")
> def _set_parent(target, value, oldvalue, initiator):
> target.parent_id = value.id
>
>
>
>
> >
> > Here is a full example you can run:
> > |
> > fromsqlalchemy.ext.declarative importdeclarative_base
> > fromsqlalchemy importColumn,ForeignKey,Integer,String
> > fromsqlalchemy importcreate_engine
> > fromsqlalchemy.orm importsessionmaker,relationship
> >
> >
> > Base=declarative_base()
> >
> >
> > classParent(Base):
> > __tablename__ ='parent'
> > id =Column(Integer,primary_key=True)
> >
> >
> > classChild(Base):
> > __tablename__ ='child'
> > id =Column(Integer,primary_key=True)
> > parent_id =Column(ForeignKey(Parent.id),nullable=False)
> >
> > parent =relationship(Parent,backref='children')
> >
> >
> > engine =create_engine('sqlite:///:memory:',echo=True)
> > Session=sessionmaker(bind=engine)
> >
> >
> > defrun():
> > Base.metadata.create_all(engine)
> > session =Session()
> > parent1 =Parent(id=1)
> > session.add(parent1)
> > session.commit()
> >
> >
> > child =Child(parent=parent1)
> > printchild.parent_id,": None, but I'd like it to be 1"
> > session.add(child)
> > session.commit()
> >
> >
> > parent2 =Parent(id=2)
> > session.add(parent2)
> > session.commit()
> > child.parent =parent2
> > t =child.parent_id,child.parent.id
> > printt,": child.parent_id is stale!"
> >
> >
> >
> >
> > if__name__ =='__main__':
> > run()
> > |
> >
> >
> > --
> > 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 [email protected] <javascript:>
> > <mailto:[email protected] <javascript:>>.
> > To post to this group, send email to [email protected]
> <javascript:>
> > <mailto:[email protected] <javascript:>>.
> > Visit this group at https://groups.google.com/group/sqlalchemy.
> > For more options, visit https://groups.google.com/d/optout.
>
--
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.