ok, many thx fma
Le 26 août 2010 à 17:03, Michael Bayer a écrit : > > On Aug 26, 2010, at 8:49 AM, Martin-Leon Francois wrote: > >> hi, >> >> The problem seems to be a little bit more general, I have a unique class >> (doing nothing) mapped to a unique table. >> After opening a session, I create an instance, add it to the session, flush, >> commit. >> Everything is ok. --> a row in the table, instance in the identity_map of >> the session >> >> Always in the same session, I delete the instance from the session., flush, >> commit. >> Everything is ok. --> no row in the table, no instance in the identity_map >> of the session >> >> Always the same session, I add again the python instance to the session, >> flush, commit. >> ??? --> no row in the table, instance in the identity_map of the session >> >> Could you have a look to the code below and help me figure out what I doing >> wrong? >> fma >> >> #If I uncomment the following line (workaround) instance is written down to >> #the database as I would expect >> #o1._sa_instance_state = o1._sa_class_manager._create_instance_state(o1) >> >> s.add(o1) >> s.add_all([o1]) >> s.flush() >> s.commit() >> print list(s.query(One)), s.identity_map >> s.close() > > OK this is a little strange. o1 has been deleted. You've found one > particular operation that doesn't immediately raise (add()), but anything > else you did with o1 would, for example: > > print o1.name > > you will get this (since o1 is expired and will refresh, then fail): > > sqlalchemy.orm.exc.ObjectDeletedError: Instance '<One at 0x1288c70>' > has been deleted. > > as you've already figured out, o1 has state on it that tells SQLAlchemy that > this object is already persistent - no INSERT will be executed again for the > object. The strange part here is that the object is beyond persistent and > is in the deleted state, and we don't have an in-memory flag that would > signal this, though perhaps that is called for here, I've never seen anyone > trying to perform such an operation before. > > Anyway to convert from persistent back to transient, use make_transient: > > from sqlalchemy.orm import make_transient > make_transient(o1) > > then the "key" is removed and the object is as though you just created it. > > I want to check if there's some foolproof way we can block on add(). > > Also, the add()/add_all() calls are redundant as is the flush() right before > the commit(). > > >> >> Le 26 août 2010 à 08:42, fma a écrit : >> >>> Any suggestion helping solving this? >>> >>> On 25 août, 13:02, Martin-Leon Francois <francois....@gmail.com> >>> wrote: >>>> Hi, >>>> >>>> I am trying in the same session to detach an instance from a collection ( >>>> one to many) >>>> flush and commit everything (all is ok) and then attach the removed >>>> instance again. unsuccessfully. >>>> >>>> in below code, last "assert" fails. >>>> I don't understand why I am not able to append m2 to o1.to_many collection >>>> once removed. >>>> >>>> Any idea? ( I use sa 0.5.6) >>>> >>>> thanx, Francois >>>> >>>> meta = MetaData() >>>> tb_one = Table("one", meta, >>>> Column('name',String(50)), >>>> Column('id',Integer, primary_key=True)) >>>> >>>> tb_many = Table("many", meta, >>>> Column('name',String(50)), >>>> Column('id',Integer, primary_key=True), >>>> Column('one_id', Integer, >>>> ForeignKey(tb_one.c.id,ondelete='CASCADE'), nullable=False),) >>>> >>>> class One(object): >>>> def __init__(self, name): >>>> self.name = name >>>> >>>> class Many(object): >>>> def __init__(self, name): >>>> self.name = name >>>> >>>> mapper_one = mapper(One,tb_one) >>>> mapper_many = mapper(Many, tb_many, >>>> properties = dict( >>>> to_one = relation(One,uselist=False, >>>> backref=backref('to_many', cascade="save-update, merge, delete, >>>> delete-orphan"),))) >>>> >>>> engine = create_engine(....) >>>> Session = orm.sessionmaker(autoflush=True, autocommit=False, bind=engine) >>>> >>>> meta.bind = engine >>>> meta.drop_all(checkfirst=True) >>>> meta.create_all(checkfirst=True) >>>> >>>> s = Session() >>>> m1 = Many("M1") >>>> m2 = Many("M2") >>>> o1 = One("One") >>>> o1.to_many.append(m1) >>>> o1.to_many.append(m2) >>>> >>>> s.add_all([m1,m2,o1]) >>>> s.flush() >>>> s.commit() >>>> assert(len(o1.to_many) == 2) >>>> >>>> o1.to_many.remove(m2) >>>> assert(len(o1.to_many) == 1) >>>> s.flush() >>>> s.commit() >>>> assert(len(o1.to_many) == 1) >>>> >>>> o1.to_many.append(m2) >>>> assert(len(o1.to_many) == 2) >>>> s.flush() >>>> s.commit() >>>> assert(len(o1.to_many) == 2) #this assert fails why? >>>> >>>> s.close() >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "sqlalchemy" group. >>> To post to this group, send email to sqlalch...@googlegroups.com. >>> To unsubscribe from this group, send email to >>> sqlalchemy+unsubscr...@googlegroups.com. >>> For more options, visit this group at >>> http://groups.google.com/group/sqlalchemy?hl=en. >>> >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "sqlalchemy" group. >> To post to this group, send email to sqlalch...@googlegroups.com. >> To unsubscribe from this group, send email to >> sqlalchemy+unsubscr...@googlegroups.com. >> For more options, visit this group at >> http://groups.google.com/group/sqlalchemy?hl=en. > > > -- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To post to this group, send email to sqlalch...@googlegroups.com. > To unsubscribe from this group, send email to > sqlalchemy+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/sqlalchemy?hl=en. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalch...@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.