bulk update/delete entities of different kind in db.run_in_transaction
- by Ray Yun
Here goes pseudo code of bulk update/delete entities of different kind in single transaction. Note that Album and Song entities have AlbumGroup as root entity.
class AlbumGroup:
pass
class Album:
group = db.ReferenceProperty(reference_class=AlbumGroup,collection_name="albums")
class Song:
album = db.ReferenceProperty(reference_class=Album,collection_name="songs")
def bulk_update_album_group(album_group):
updated = [album_group]
deleted = []
for album in album_group.albums:
updated.append(album)
for song in album.songs:
if song.is_updated:
updated.append(song)
if song.is_deleted:
deleted.append(song)
db.put(updated)
db.delete(deleted)
a = AlbumGroup.all().filter("...").get()
# bulk update/delete album group. for simplicity, album cannot be deleted.
db.run_in_transaction(bulk_update_album_group,a)
But I met a famous "Only Ancestor Queries in Transactions" error at the iterating reference properties like album.songs or album_group.albums. I guess ancestor() filter does not help because those entities are modified in memory.
Should I not to iterate reference property in transaction function and always provide them as function parameters like def bulk_update_album_group(updated,deleted): ???
Is there any good coding pattern for this situation?