Hi Michael, It really works like magic! I mean the refreshing part. What exactly happens when refreshing a1.bs? Does it actually replace the old b1 inside the collection with a newer one? I can't wrap my mind around it. And more importantly, does it mean I should *refresh* every attributes before close a session, in order to carry their attribute over to the next session? What is the reason not making such *refreshing* automatic by default???
Sorry for bringing up another question here. On Sun, Mar 16, 2014 at 10:58 AM, Michael Bayer <[email protected]>wrote: > > On Mar 15, 2014, at 7:41 PM, Bao Niu <[email protected]> wrote: > > Thanks a lot Michael! Just a trivial question here, I noticed in your > first reply you used: > # refresh a1.bs > > Why do we need to refresh it? I tried it in my terminal and it doesn't > emit any sql. Is this one if those secret techniques that differentiate a > sqlalchemy ninja and a newbie?;) > > > it should emit SQL, because the sess.commit() call above has expired the > collection. in my script it fails down on "a1.bs.remove()" if i don't call > that first. > > > > > On Mar 15, 2014 8:31 AM, "Michael Bayer" <[email protected]> wrote: > >> you have every reason to be confused by that paragraph, which is using >> way too much terminology to express what's important there. at some >> point, we had to add a behavior which I thought would be confusing to >> people, so that paragraph tries badly to explain what it is. I should >> replace it with just a simple sentence and an example. Here's the example: >> >> 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(Integer, ForeignKey('a.id')) >> >> e = create_engine("sqlite://", echo=True) >> Base.metadata.create_all(e) >> >> sess = Session(e) >> a1 = A() >> b1 = B() >> >> a1.bs = [b1] >> >> sess.add(a1) >> sess.commit() >> >> a1.bs # refresh a1.bs >> sess.close() # close out - sess is no longer associated with a1, b1 >> >> # all new session >> sess2 = Session(e) >> >> a1.bs.remove(b1) >> >> sess2.add(a1) >> >> # b1 was removed from a1.bs, but >> # is in sess2 anyway! surprising! >> assert b1 in sess2 >> >> # because we need it for the flush, it's still here: >> from sqlalchemy import inspect >> print inspect(a1).attrs.bs.history.deleted >> >> >> >> >> >> >> On Mar 15, 2014, at 5:26 AM, Bao Niu <[email protected]> wrote: >> >> I've read this paragraph ( >> http://docs.sqlalchemy.org/en/latest/orm/session.html#unitofwork-cascades) >> many many times and still can't think of a practical example of what is >> being discussed. >> >> save-update cascade also cascades the *pending history* of the target >>> attribute, meaning that objects which were removed from a scalar or >>> collection attribute whose changes have not yet been flushed are also >>> placed into the target session. This is because they may have foreign key >>> attributes present which will need to be updated to no longer refer to the >>> parent. >> >> >> I don't think my English is the main stumbling block here because I >> understand the meaning of each word, but as soon as I'm putting them >> together I'm completely lost. Could someone give a simple example here to >> illustrate the main point in this paragraph please? Highly appreciated. >> Thanks. >> >> -- >> 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 http://groups.google.com/group/sqlalchemy. >> For more options, visit https://groups.google.com/d/optout. >> >> >> >> -- >> You received this message because you are subscribed to a topic in the >> Google Groups "sqlalchemy" group. >> To unsubscribe from this topic, visit >> https://groups.google.com/d/topic/sqlalchemy/MSiBcFB3cFI/unsubscribe. >> To unsubscribe from this group and all its topics, send an email to >> [email protected]. >> To post to this group, send email to [email protected]. >> Visit this group at http://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 http://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. > > > -- > You received this message because you are subscribed to a topic in the > Google Groups "sqlalchemy" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/sqlalchemy/MSiBcFB3cFI/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://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 http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.
