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.

Reply via email to