On Oct 12, 2013, at 11:54 AM, Marc Van Olmen <marcvanol...@gmail.com> wrote:
> hi, > > Just wanted to quickly report this issue, didn't had time to write unit test > for corning the case: > Was upgrading an 0.4.8 legacy project to 0.8.2 > > Got an SAWarning: This collection has been invalidated in the following case: > > Original 0.4.8 code: > > self._serials.append(MetaSerial(value=u')) > > And failed to add it to the collection. > > The fix needed to get rid of the above warning: > > a_serial = MetaSerial(value=u'') > self._serials.append(a_serial) there's nothing in the mapping or sample code illustrated here that by itself would emit this warning. The warning itself is not a bug, but instead refers to a bug in the calling code, where it is erroneously appending to a collection that is no longer valid, due to expiration. Expiration on session commit was introduced as a default behavior in 0.5 and the collection mechanics also changed significantly from 0.5 on forward. The code example you have suggests a premature garbage collection of some resource due to the way MetaSerial is not assigned to a variable in one case vs. the other, but that's not really possible with a straight append to a mapped collection as above, and that also doesn't have any direct path to causing this very specific collection-oriented warning from being emitted. So either this code isn't the primary cause of the issue, or there's something more complex going on in the actual classes and/or mappings that produces this. To produce the warning, you have to do something equivalent to the sample code below: 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() a1.bs = [B()] # hold onto the collection collection = a1.bs sess.add(a1) # "collection" is now no longer associated with a1 sess.commit() # emits the warning collection.append(B())
signature.asc
Description: Message signed with OpenPGP using GPGMail