The Session is not usable in the way you're using it inside of after_insert and 
after_delete - in particular the modifications made to the state of the object 
that was just inserted will be discarded, and the add() will have no effect as 
the flush plan cannot be changed in these events.

To modify the Session's flush plan within a flush event, use the before_flush() 
session event.


There are guidelines to this effect on before_insert() 
http://www.sqlalchemy.org/docs/orm/events.html?highlight=after_insert#sqlalchemy.orm.events.MapperEvents.before_insert
  but I'll need to add similar language to after_() also.  look for that soon.




On Aug 25, 2011, at 6:45 AM, Jaimy Azle wrote:

> Hi,
> 
> I found some weird case on using the mapper event, i setup the mapper
> to firing after_insert and after_delete event. However i find some
> issue, at least weird behaviour:
> 
> * after_insert and after_delete triggered only once on each committed
>  transaction.
> 
>  dt_1 = Detail(1, 1, 'This is detail')
>  dt_2 = Detail(1, 2, 'This is detail')
>  session.add(dt_1)
>  session.add(dt_2)
>  session.commit() # this only fire before insert only once
> 
> * no additional data manipulation inside each event could be
>  persisted.
> 
>  def model_after_insert(mapper, connection, target):
>    if target.__tablename__ == 'detail':
>        master = session.query(klass).filter_by(id = target.master).first()
>        if master:
>           master.total = master.total + 1
>           session.add(master)   # nothing would be persisted on this
> 
> Full example attached below, is there anything i had missed?
> 
> -- 
> Salam,
> 
> -Jaimy Azle
> 
> ------------ code snippet ---------
> from sqlalchemy import create_engine, event
> from sqlalchemy import Column, Integer, String
> from sqlalchemy.orm import sessionmaker, mapper
> from sqlalchemy.ext.declarative import declarative_base
> 
> Base = declarative_base()
> engine = create_engine('sqlite:///:memory:')
> Session = sessionmaker(bind=engine)
> 
> klass = None
> 
> def model_after_insert(mapper, connection, target):
>  if target.__tablename__ == 'detail':
>    master = session.query(klass).filter_by(id = target.master).first()
>    if master:
>      master.total = master.total + 1    
>      session.add(master)
>      print('after insert', master.total)
> 
> def model_after_delete(mapper, connection, target):
>  if target.__tablename__ == 'detail':
>    master = session.query(klass).filter_by(id = target.master).first()
>    if master:
>      master.total = master.total - 1      
>      session.add(master)
>      print('after delete', master.total)
> 
> 
> event.listen(mapper, 'after_insert', model_after_insert)
> event.listen(mapper, 'after_delete', model_after_delete)
> 
> class Master(Base):
>  __tablename__ = 'master'
>  id = Column(Integer, primary_key=True)
>  name = Column(String)
>  total = Column(Integer)
> 
>  def __init__(self, name):
>    self.name = name
>    self.total = 0
> 
> class Detail(Base):
>  __tablename__ = 'detail'  
>  id = Column(Integer, primary_key=True)  
>  master = Column(Integer, primary_key=True)
>  name = Column(String)
> 
>  def __init__(self, id, master, name):
>    self.id = id
>    self.name = name    
>    self.master = master      
> 
> klass = Master    
> 
> Base.metadata.create_all(engine)
> session = Session()
> 
> master = Master('hello world')  
> session.add(master)
> session.commit()
> 
> dt_1 = Detail(1, 1, 'This is detail')
> dt_2 = Detail(1, 2, 'This is detail')
> session.add(dt_1)
> session.add(dt_2)
> session.commit()
> 
> master = session.query(Master).filter_by(id = 1).first()
> print('total ', master.total)
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to sqlalchemy@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 sqlalchemy@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.

Reply via email to