Running some code immediately before a Datastore put()?

88 views
Skip to first unread message

Nickolas Daskalou

unread,
Jan 14, 2010, 4:34:46 AM1/14/10
to google-a...@googlegroups.com
I have a property of a Model that is a hash of another property of the same Model, eg:

class MyModel(db.Model):
  something = db.StringProperty()
  something_hash = db.StringProperty()
  def generate_hash(self):
    self.something_hash = sha1(self.something)

I want generate_hash() to be automatically called just before the entity is put() into the Datastore, without the developer having to explicitly call entity.generate_hash().

I know I can create a put() method that makes such a call and then calls put() on the superclass, but (a) is that the best way to do it, and (b) if the put() is part of a batch put (eg. via db.put(entities)), will the put() method of each model instance still be called?

Nick

Eric Ka Ka Ng

unread,
Jan 14, 2010, 4:51:43 AM1/14/10
to google-a...@googlegroups.com
would a PreCallHook works for your case?

http://code.google.com/appengine/articles/hooks.html

- eric

2010/1/14 Nickolas Daskalou <ni...@daskalou.com>:

> --
> You received this message because you are subscribed to the Google Groups
> "Google App Engine" group.
> To post to this group, send email to google-a...@googlegroups.com.
> To unsubscribe from this group, send email to
> google-appengi...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/google-appengine?hl=en.
>
>

Devel63

unread,
Jan 14, 2010, 2:48:19 PM1/14/10
to Google App Engine
Nick,

I've been faced with your exact situation. I have to say I don't
understand PreCallHook, and maybe that would be the best approach, but
here's what I do know.

Overriding "put" is a bad idea, and as you point out, the override
will not be called in a batch put.

I found that the most elegant solution was to derive a new type of
db.Property, and override its get_value_for_datastore. Then GAE will
automatically do what you want regardless of how the entity is being
put.


On Jan 14, 1:51 am, Eric Ka Ka Ng <ngk...@gmail.com> wrote:
> would a PreCallHook works for your case?
>
> http://code.google.com/appengine/articles/hooks.html
>
> - eric
>

> 2010/1/14 Nickolas Daskalou <n...@daskalou.com>:

Nickolas Daskalou

unread,
Jan 14, 2010, 8:58:22 PM1/14/10
to google-a...@googlegroups.com
Thanks guys, both great suggestions.

I'll try and get PreCallHook working because that would allow me to add a "pre_put()" method to my Models, and then using these PreCallHooks I can call pre_put() for each of the entities being put into the Datastore.

Failing that, I'll create a new derived property for my Model and do as Devel63 said.


2010/1/15 Devel63 <danst...@gmail.com>

Nickolas Daskalou

unread,
Jan 14, 2010, 9:16:39 PM1/14/10
to google-a...@googlegroups.com
I'm pretty sure the code on the GAE Hooks article (http://code.google.com/appengine/articles/hooks.html) is wrong.

4th code snippet, shouldn't the very first line:

def path_appengine():

be moved to the bottom, just above this line:

    apiproxy_stub_map.apiproxy.GetPreCallHooks().Append(....)

?


2010/1/15 Nickolas Daskalou <ni...@daskalou.com>

风笑雪

unread,
Jan 15, 2010, 12:58:07 AM1/15/10
to google-a...@googlegroups.com
You can use aetycoon, example:
http://blog.notdot.net/2009/12/Most-popular-metrics-in-App-Engine

2010/1/15 Nickolas Daskalou <ni...@daskalou.com>:

Eric Feng

unread,
Nov 17, 2011, 5:36:37 AM11/17/11
to google-a...@googlegroups.com
I also found Nick Johnson's (google guy) post on this to be very useful.  Honestly, his whole blog is useful - App Engine tips from a guy on the inside.

Reply all
Reply to author
Forward
0 new messages