Hi folks,

The book describes DAL's _after_insert() callback 
<http://www.web2py.com/books/default/chapter/29/06/the-database-abstraction-layer#callbacks-on-record-insert--delete-and-update>
 
as:

The caveat is that depending on the functionality, the callback has 
> different signature.
> This is best explained via some examples.
> >>> db.define_table('person',Field('name'))
> >>> def pprint(*args): print args
> >>> db.person._before_insert.append(lambda f: pprint(f))
> >>> db.person._after_insert.append(lambda f,id: pprint(f,id))   # WRONG 
> SIGNATURE?
> >>> db.person._before_update.append(lambda s,f: pprint(s,f))
> >>> db.person._after_update.append(lambda s,f: pprint(s,f))
> >>> db.person._before_delete.append(lambda s: pprint(s))
> >>> db.person._after_delete.append(lambda s: pprint(s))
> Here f is a dict of fields passed to insert or update, id is the id of 
> the newly inserted record, s is the Set object used for update or delete.
> >>> db.person.insert(name='John')
> ({'name': 'John'},)
> ({'name': 'John'}, 1)    # WRONG EXAMPLE?


However, I believe (at least in web2py 2.9.12) the first parameter in 
_after_insert() is NOT a dict, but a Row object. Because, my web2py app 
uses the following code in db.py, trying to send out a validation email to 
new registrated user:

def customized_email_verification(row, row_id):
>
    db(db.auth_user.id==row_id).update(registration_key="a random string") 
>  # I need this because my users are not registered from web UI 

    db.commit()  # commit BEFORE the time consuming email action, otherwise 
> a parallel requests could cause duplicated record in DB?!

    auth.settings.mailer.send(to=row["email"], subject="Hi", 
*message=customized_message 
> % row*)
> db.auth_user._after_insert.append(customized_email_verification)


and it ends up with a very confusing error as:

TypeError: format requires a mapping


Finally I located that line and changed it into:

    ... customized_message % row.as_dict()


and then it works.

So I am asking for your confirmation and suggest to fix the book 
accordingly.


A followup question. The reason I need my clumsy 
customized_email_verification() in the first place, is because I seemingly 
have to do db.commit() BEFORE the time consuming email sending job. 
Otherwise I saw some randomly duplicated records in my auth_user table. I 
don't know the exact reason but my guess is, the tools.py's define_tables() 
uses IS_NOT_IN_DB() validators which only work in web2py level, but does 
NOT define any "unique=True" in the DB level. Is this considered as a 
defect? Think about this sequence.

Now: the first user creation request is validated but by default not yet 
committed, and now sending email which will likely take 2 seconds
Now + 1 second: Somehow the client could resent same request. This request 
also passes validation, because there is no duplication in DB so far.
Now + 2 second: The email for request #1 has been sent. And record #1 is 
committed into DB.
Now + 3 second: The email for request #2 has been sent. And duplicated 
record #2 is committed into DB.

How can I improve such pattern? Thanks!

Regards,
Ray

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to