Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sqlalchemy event on column update

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"})

option A

Every things works fine, but I have some update method using many fields to sqlalchemy.

option B

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?

like image 778
chao787 Avatar asked Apr 18 '14 10:04

chao787


1 Answers

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".

like image 170
zzzeek Avatar answered Sep 21 '22 15:09

zzzeek