Before update and After update callbacks are giving the same results on updating table

33 views
Skip to first unread message

Sarbjit

unread,
Jul 9, 2014, 1:54:56 AM7/9/14
to web...@googlegroups.com
Hi All,

I want to detect if there is a change in auth_user table for registeration_key field. I have implemented the following code :-

Models :

db.auth_user._before_update.append(lambda s,f: before_trigger_auth(s,f))
db.auth_user._after_update.append(lambda s,f: after_trigger_auth(s,f))

Modules :

def before_trigger_auth(*args):
    print args
    print "before"
    f = args[1]
    rkey = f['registration_key']
    current.session.before_rkey = rkey
   
def after_trigger_auth(*args):
    print args
    print "after"
    f = args[1]
    rkey = f['registration_key']
    if current.session.before_rkey:
        if current.session.before_rkey == "pending" and rkey == "":
            del current.session.before_rkey
            ruseremail = f['email']
            print "Trigger an email update"


Now when I am editing the db.auth_user table record (using appadmin) to delete the pending word from registeration_key, I have noticed that the results from both and after callbacks were same i.e. registeration_key was empty.

If I add the "pending" word in registration_key, then also I get the same results from both the after and before callbacks.


Anthony

unread,
Jul 9, 2014, 10:47:01 AM7/9/14
to web...@googlegroups.com

db.auth_user._before_update.append(lambda s,f: before_trigger_auth(s,f))
db.auth_user._after_update.append(lambda s,f: after_trigger_auth(s,f))

First, note that if your callback is just an existing function that takes the parameters as they will be passed, there is no need to wrap it in a lambda -- just do:

db.auth_user._before_update(before_trigger_auth)

def before_trigger_auth(*args):
    print args
    print "before"
    f = args[1]
    rkey = f['registration_key']
    current.session.before_rkey = rkey

The "f" argument passed to the callback is a dictionary of the values that will be inserted into the record, not the existing values in the record (in fact, because an update can apply to multiple records, it would not generally be possible to have a single dictionary of existing values).

Note that updates do not involve retrieving the records from the database, so the DAL does not know the existing values of records to be updated. If you need the existing values, you will have to do a select query to retrieve the records, which you can do using the "s" argument passed to the callback (that argument is the DAL Set object used to identify the records to be updated). If you know there is only a single record to be updated, you could do:

def before_trigger_auth(s, f):
    current
.session.before_rkey = s.select().first().registration_key
   
def after_trigger_auth(s, f):
    rkey
= f['registration_key']

   
if current.session.before_rkey == "pending" and rkey == "":
       
del current.session.before_rkey
        ruseremail
= f['email']
       
print "Trigger an email update"

In the above, also note that there is no reason to use *args rather than just explicitly defining the "s" and "f" arguments, and no reason to first test for current.session.before_rkey, as the check for "pending" will simply be false in case there is no before_rkey (because the session is a Storage object, attempts to access non-existent keys do not result in an exception but instead simply return None).

Anthony
 

Sarbjit

unread,
Jul 10, 2014, 1:03:24 AM7/10/14
to web...@googlegroups.com
Thanks Anthony :)

Reply all
Reply to author
Forward
0 new messages