Reputation: 141
I had a root entity kind that I wanted to refactor to have a parent entity.
These entities all had auto-allocated ids.
I cloned all the existing entities, creating the clone's key from the parent entity and the id of the old entity. Then I deleted the old entities.
Any new entities that get created get auto-allocated ids from the Datastore.
The Datastore's automatic ID allocator never assigns a key belonging to an existing entity to a new entity.
...but I'm not sure if that only applies in the context of pre-allocated ids.
Could my new entities that get created overwrite existing entities? Or will the Datastore still recognize those ids as already used, despite the parent difference?
Do I have to I pre-allocate all of my existing entity ids to prevent my entities being overwritten by new entities?
Edit:
My old entities had keys like this:
datastore_types.Key.from_path(u'MyKind', 123456789, _app=u's~my-app')
My new cloned entities have keys like this (reusing the old id):
datastore_types.Key.from_path(u'ParentKind', 28882914L, u'MyKind', 123456789, _app=u's~my-app')
So will the Datastore still think that this id has been used for this kind, despite the fact that the parents are different?
Upvotes: 1
Views: 662
Reputation: 3626
The Datastore will not think that the id has been used. When the Datastore allocates ids, it allocates from a sequence which is determined by the Kind and the parent (see the model argument here). Since your new models have a different parent, they will allocate from their own id sequence, which may collide with your manually set id.
Automatically created ids are only guaranteed to not collide with other ids that have been created automatically (using either a put
with no id set or using the allocate_ids
method).
Upvotes: 1
Reputation: 141
Judging from the descriptions of the various possible return values of allocate_id_range
, it seems safe to say that the datastore will never overwrite an existing entity with a new entity when using the automatic ID allocator.
KEY_RANGE_EMPTY = "Empty"
"""Indicates the given key range is empty and the datastore's
automatic ID allocator will not assign keys in this range to new
entities.
"""
KEY_RANGE_CONTENTION = "Contention"
"""Indicates the given key range is empty but the datastore's
automatic ID allocator may assign new entities keys in this range.
However it is safe to manually assign keys in this range
if either of the following is true:
- No other request will insert entities with the same kind and parent
as the given key range until all entities with manually assigned
keys from this range have been written.
- Overwriting entities written by other requests with the same kind
and parent as the given key range is acceptable.
The datastore's automatic ID allocator will not assign a key to a new
entity that will overwrite an existing entity, so once the range is
populated there will no longer be any contention.
"""
KEY_RANGE_COLLISION = "Collision"
"""Indicates that entities with keys inside the given key range
already exist and writing to this range will overwrite those entities.
Additionally the implications of KEY_RANGE_COLLISION apply. If
overwriting entities that exist in this range is acceptable it is safe
to use the given range.
The datastore's automatic ID allocator will never assign a key to
a new entity that will overwrite an existing entity so entities
written by the user to this range will never be overwritten by
an entity with an automatically assigned key.
"""
This other StackOverflow answer agrees: AppEngine allocateIdRange : clarification about CONTENTION state
Upvotes: 0
Reputation: 179
If I got it right, the old entities will have the previous ID + the parent ID, correct? And the new entities will also have the parent Id. In this case, Datastore won't overwrite any entity because it never assigns a duplicated key.
Upvotes: 0