I registered an event at updating User.name
for apply some rules after or just before update.
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy import event
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///:memory:', echo=True)
Session = sessionmaker(bind=engine) # engine part
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)
rule = Column(String)
Base.metadata.create_all(engine)
session = Session()
u1 = User(id=1, name="hello world", fullname="hello kitty")
u2 = User(id=2, name="hello world2", fullname="hello kitty2")
session.add(u1)
session.add(u2)
@event.listens_for(User, 'before_update')
def User_before_update(target, value, initiator):
print ":::::received before insert event for target"
@event.listens_for(User.name, 'set')
def name_set(target, value, old_value, initiator):
print ":::::set before insert event for target"
### option A
user = session.query(User).get(2)
user.name = u"wawamsma"
session.merge(user)
### option B
session.query(User).filter(User.id == 2).update({User.name: u"eenimenee"})
Every things works fine, but I have some update method using many fields to sqlalchemy.
Updated, but do not trigger both print func.
So I wonder, is this the Wrong way to register event or wrong way to do the update?
To receive events when using the query.update() method, you need to use the after_bulk_update event. As this operation does not deal with individual objects and instead emits an UPDATE statement directly, the actual objects in memory which may have been affected here are not locally available; you may need to query for them. The context will have a matched_objects
attribute if "synchronize_session" is set to "evaluate".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With