This is a bit of an advanced question for the experts with regards to Keys, 
IDs, Models and the db.allocate_ids() functionality - those who can answer 
it won't need much more explanation, so apologies if it doesn't make much 
sense to everyone else (but you may want to file it away in case you ever 
need to do the same).

My one-page-webapp uses a datastore framework that gets a bit distraught 
when it has create new items and allocate temporary IDs which will later get 
replaced with "true" IDs from the datastore (I've been using the actual Key 
strings as ids), so I thought I'd have a look at pre-allocating IDs.

In the absence of cookbook examples, I've concluded

   - I can pre-allocate a range of IDs for a given class using 
   db.allocate_ids(), but as individual keys encode the id and the parent 
   instance (if any) then I can't convert these pre-allocated IDs into 
   pre-allocated Keys if I may be using parent objects.
   - So I should change the client to use IDs (or maybe "type+id" tuples), 
   and have queries to the GAE server return items with 'obj.key().id()' rather 
   than 'str(obj.key())' 
   - The client can be given a range of pre-allocated IDs that it can safely 
   assign to new records as it creates them, knowing they won't change when the 
   item is created in the datastore
   - For updating/deleting items on GAE, I'll replace calls to "db.get(key)" 
   (where the key came from the client, and yes I then check the object is 
   valid etc before I proceed) with "MyModel.get_by_id(ids)" (I know the types 
   of objects by this stage so it's not like I'm doing a heterogeneous fetch)
   - I'll still store references to other objects by db.ReferenceProperty 
   type (ie key) rather than simple id as it makes migration of data easier (ie 
   use of IDs rather than Keys is a client layer convenience only)
   - I'll implement a new model base class for all db.Model derived classes, 
   that defines a new optional "id" parameter and constructs the correct key 
   (my python knowledge of the constructs is bit green, so I think this does 
   what I expect - kind() is a reserved but undocumented instance method that 
   looks safer than using __name__ by looking at the SDK source)
   
class BaseModel(db.Model):
    def __init__(self, id=None, parent=None, **args):
        if id != None:
            args["key"] = db.Key.from_path(self.kind(), id, parent=parent)
        db.Model.__init__(self, parent=parent, **args)

The db.Model ctor docs say that "key" can't be used with parent or key_name, 
looking at the SDK source implies the last line of the above should be fine, 
but would I do better to omit the "parent=parent" parameter and rely on the 
fact that, if needed, the parent object is looked up form the key?

   - I can then make instances as before 'obj = MyModel(someproperty=97, 
   another="Hello world")' but I now have a special optional "id" property for 
   construction. I haven't changed parent or property semantics or the like.
   
Does the above look reasonable enough? I take it the efficiency is pretty 
much the same (ie there's no great added overhead such as extra database 
calls introduced by any of the above) but as I'm no great python expert, and 
the calls above are documented but not always explained, does the above look 
reasonable enough or am I laying myself open to a world of pain to come?

Cheers

--
Tim

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/google-appengine/-/EICnNig9mKkJ.
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.

Reply via email to