[google-appengine] Re: synthentic keys - performance implications?
On Mon, Aug 24, 2009 at 6:44 PM, Jeff Enderwick jeff.enderw...@gmail.comwrote: thanks - I got bit by those __init__ nuances over the weekend. I ended up passing an optional flag to the __init__ to say this is really a new() vs a datastore reconstitution. I del the optional flag from kwargs before calling the super __init__. In the datastore reconstitution case, I do nothing but call the super __init__. Does that cover the __init__ gotchas, or am I digging my own grave by not converting to a distinct create function? I don't know the gotchas well enough to say. I still think a factory function is your best bet. :) -Nick Johnson On Mon, Aug 24, 2009 at 3:56 AM, Nick Johnson (Google)nick.john...@google.com wrote: Hi Jeff, On Sat, Aug 22, 2009 at 7:24 PM, Jeff Enderwick jeff.enderw...@gmail.com wrote: Currently, one must put() in order to have obj.key() be valid. In some flows, I find my self having to put() object twice for this reason. If I make a synthetic key, it appears that I can avoid this: class Joker(db.Model): unused = db.StringProperty() def __init__(self): m = hashlib.sha1() m.update(str(time.time())) name = base64.b64encode(m.digest()) logging.debug(name=+name) db.Model.__init__(self, key_name=name) 1) GOOG folks - are there any performance downsides to taking this approach? Not really, no. 2) If no, are there any other environmental factors that might be fodder for the hash (user, etc)? I would recommend using uuid.uuid4().hex instead of a straight SHA1 sum. UUIDs are guaranteed to be unique. I would also recommend defining a class method called something like 'create' that generates the key name and calls __init__. There are subtle-use cases around __init__ and reconstructing entities from the datastore, and it's difficult to get right - much more straightforward to define a class method to construct new entities. -Nick Johnson Thanks, Jeff -- Nick Johnson, Developer Programs Engineer, App Engine -- Nick Johnson, Developer Programs Engineer, App Engine --~--~-~--~~~---~--~~ 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-appengine@googlegroups.com To unsubscribe from this group, send email to google-appengine+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en -~--~~~~--~~--~--~---
[google-appengine] Re: synthentic keys - performance implications?
For posterity, one such gotcha is a case where Model instances work fine, but Expando instances can loose their additive attributes coming back out of the datastore. Switched to factory @staticmethod, and all is good now... On Tue, Aug 25, 2009 at 6:32 AM, Nick Johnson (Google)nick.john...@google.com wrote: On Mon, Aug 24, 2009 at 6:44 PM, Jeff Enderwick jeff.enderw...@gmail.com wrote: thanks - I got bit by those __init__ nuances over the weekend. I ended up passing an optional flag to the __init__ to say this is really a new() vs a datastore reconstitution. I del the optional flag from kwargs before calling the super __init__. In the datastore reconstitution case, I do nothing but call the super __init__. Does that cover the __init__ gotchas, or am I digging my own grave by not converting to a distinct create function? I don't know the gotchas well enough to say. I still think a factory function is your best bet. :) -Nick Johnson On Mon, Aug 24, 2009 at 3:56 AM, Nick Johnson (Google)nick.john...@google.com wrote: Hi Jeff, On Sat, Aug 22, 2009 at 7:24 PM, Jeff Enderwick jeff.enderw...@gmail.com wrote: Currently, one must put() in order to have obj.key() be valid. In some flows, I find my self having to put() object twice for this reason. If I make a synthetic key, it appears that I can avoid this: class Joker(db.Model): unused = db.StringProperty() def __init__(self): m = hashlib.sha1() m.update(str(time.time())) name = base64.b64encode(m.digest()) logging.debug(name=+name) db.Model.__init__(self, key_name=name) 1) GOOG folks - are there any performance downsides to taking this approach? Not really, no. 2) If no, are there any other environmental factors that might be fodder for the hash (user, etc)? I would recommend using uuid.uuid4().hex instead of a straight SHA1 sum. UUIDs are guaranteed to be unique. I would also recommend defining a class method called something like 'create' that generates the key name and calls __init__. There are subtle-use cases around __init__ and reconstructing entities from the datastore, and it's difficult to get right - much more straightforward to define a class method to construct new entities. -Nick Johnson Thanks, Jeff -- Nick Johnson, Developer Programs Engineer, App Engine -- Nick Johnson, Developer Programs Engineer, App Engine --~--~-~--~~~---~--~~ 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-appengine@googlegroups.com To unsubscribe from this group, send email to google-appengine+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en -~--~~~~--~~--~--~---
[google-appengine] Re: synthentic keys - performance implications?
do not forget to add a prefix to the key_name (ie : 'k:',...) Else if your key_name starts with a number it will raise an error On 24 août, 12:56, Nick Johnson (Google) nick.john...@google.com wrote: Hi Jeff, On Sat, Aug 22, 2009 at 7:24 PM, Jeff Enderwick jeff.enderw...@gmail.comwrote: Currently, one must put() in order to have obj.key() be valid. In some flows, I find my self having to put() object twice for this reason. If I make a synthetic key, it appears that I can avoid this: class Joker(db.Model): unused = db.StringProperty() def __init__(self): m = hashlib.sha1() m.update(str(time.time())) name = base64.b64encode(m.digest()) logging.debug(name=+name) db.Model.__init__(self, key_name=name) 1) GOOG folks - are there any performance downsides to taking this approach? Not really, no. 2) If no, are there any other environmental factors that might be fodder for the hash (user, etc)? I would recommend using uuid.uuid4().hex instead of a straight SHA1 sum. UUIDs are guaranteed to be unique. I would also recommend defining a class method called something like 'create' that generates the key name and calls __init__. There are subtle-use cases around __init__ and reconstructing entities from the datastore, and it's difficult to get right - much more straightforward to define a class method to construct new entities. -Nick Johnson Thanks, Jeff -- Nick Johnson, Developer Programs Engineer, App Engine --~--~-~--~~~---~--~~ 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-appengine@googlegroups.com To unsubscribe from this group, send email to google-appengine+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en -~--~~~~--~~--~--~---
[google-appengine] Re: synthentic keys - performance implications?
thanks - I got bit by those __init__ nuances over the weekend. I ended up passing an optional flag to the __init__ to say this is really a new() vs a datastore reconstitution. I del the optional flag from kwargs before calling the super __init__. In the datastore reconstitution case, I do nothing but call the super __init__. Does that cover the __init__ gotchas, or am I digging my own grave by not converting to a distinct create function? On Mon, Aug 24, 2009 at 3:56 AM, Nick Johnson (Google)nick.john...@google.com wrote: Hi Jeff, On Sat, Aug 22, 2009 at 7:24 PM, Jeff Enderwick jeff.enderw...@gmail.com wrote: Currently, one must put() in order to have obj.key() be valid. In some flows, I find my self having to put() object twice for this reason. If I make a synthetic key, it appears that I can avoid this: class Joker(db.Model): unused = db.StringProperty() def __init__(self): m = hashlib.sha1() m.update(str(time.time())) name = base64.b64encode(m.digest()) logging.debug(name=+name) db.Model.__init__(self, key_name=name) 1) GOOG folks - are there any performance downsides to taking this approach? Not really, no. 2) If no, are there any other environmental factors that might be fodder for the hash (user, etc)? I would recommend using uuid.uuid4().hex instead of a straight SHA1 sum. UUIDs are guaranteed to be unique. I would also recommend defining a class method called something like 'create' that generates the key name and calls __init__. There are subtle-use cases around __init__ and reconstructing entities from the datastore, and it's difficult to get right - much more straightforward to define a class method to construct new entities. -Nick Johnson Thanks, Jeff -- Nick Johnson, Developer Programs Engineer, App Engine --~--~-~--~~~---~--~~ 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-appengine@googlegroups.com To unsubscribe from this group, send email to google-appengine+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en -~--~~~~--~~--~--~---