[sqlalchemy] Re: one to many relation, removing and adding list issue
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.
Re: [sqlalchemy] Re: one to many relation, removing and adding list issue
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 from sqlalchemy import __version__, MetaData, Table, Column, Integer, String, create_engine, orm #...@unresolvedimport from sqlalchemy.orm import mapper #...@unresolvedimport from sqlalchemy.orm import backref #...@unresolvedimport @UnusedImport print __version__ meta = MetaData() tb_one = Table(one, meta, Column('name',String(50)), Column('id',Integer, primary_key=True)) class One(object): def __init__(self, name): self.name = name def __repr__(self): return self.name mapper_one = mapper(One,tb_one) engine = create_engine('postgres://fma:fma6...@localhost:5432/postgres', convert_unicode=True) Session = orm.sessionmaker(autoflush=True, autocommit=False, bind=engine) meta.bind = engine meta.drop_all(checkfirst=True) meta.create_all(checkfirst=True) s = Session() o1 = One(One) s.add(o1) s.add_all([o1]) s.flush() s.commit() print list(s.query(One)), s.identity_map s.delete(o1) s.flush() s.commit() print list(s.query(One)), s.identity_map #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() 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.
[sqlalchemy] Re: one to many relation, removing and adding list issue
Sorry if you receive this twice, I am not sure if it had been correctly posted. On 26 août, 14:49, Martin-Leon Francois francois@gmail.com 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 from sqlalchemy import __version__, MetaData, Table, Column, Integer, String, create_engine, orm #...@unresolvedimport from sqlalchemy.orm import mapper #...@unresolvedimport from sqlalchemy.orm import backref #...@unresolvedimport @UnusedImport print __version__ meta = MetaData() tb_one = Table(one, meta, Column('name',String(50)), Column('id',Integer, primary_key=True)) class One(object): def __init__(self, name): self.name = name def __repr__(self): return self.name mapper_one = mapper(One,tb_one) engine = create_engine('postgres://fma:fma6...@localhost:5432/postgres', convert_unicode=True) Session = orm.sessionmaker(autoflush=True, autocommit=False, bind=engine) meta.bind = engine meta.drop_all(checkfirst=True) meta.create_all(checkfirst=True) s = Session() o1 = One(One) s.add(o1) s.add_all([o1]) s.flush() s.commit() print list(s.query(One)), s.identity_map s.delete(o1) s.flush() s.commit() print list(s.query(One)), s.identity_map #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() 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 athttp://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.
Re: [sqlalchemy] Re: one to many relation, removing and adding list issue
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
Re: [sqlalchemy] Re: one to many relation, removing and adding list issue
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,