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 [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-appengine?hl=en.