Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jzerbe
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jzerbe/2615b891e35159d00a67 to your computer and use it in GitHub Desktop.
Save jzerbe/2615b891e35159d00a67 to your computer and use it in GitHub Desktop.
alter PolyModel inheritance tree
from logging import debug as log_debug
from google.appengine.ext import deferred
from google.appengine.ext import ndb
from model2 import Child # this works for query purposes!
# deserialize bigtable data into object will yield
# just GrandParent fields prior to migration running
BATCH_SIZE = 20
PARENT_CLASS_NAME = u'Parent'
# based on code found here:
# https://cloud.google.com/appengine/articles/update_schema
def add_parent_class(cursor=None, num_updated=0):
# call this method to convert from model1 to model2
query = Child.all() # get all existing entities to migrate
if cursor:
query.with_cursor(cursor)
to_put = []
for entity in query.fetch(limit=BATCH_SIZE):
# class_ field mutation allowed, assignment is not
entity.class_.insert(1, PARENT_CLASS_NAME)
to_put.append(entity)
if to_put:
ndb.put_multi(to_put) # fewer RPCs this way
num_updated += len(to_put)
log_debug('updated %d entities. for a total of %d',
len(to_put), num_updated)
deferred.defer(add_parent_class,
cursor=query.cursor(), num_updated=num_updated)
else:
log_debug('add_parent_class complete with %d updates',
num_updated)
def remove_parent_class(cursor=None, num_updated=0):
# call this method to convert from model2 to model1
query = Child.all() # get all existing entities to migrate
if cursor:
query.with_cursor(cursor)
to_put = []
for entity in query.fetch(limit=BATCH_SIZE):
# class_ field mutation allowed, assignment is not
entity.class_.remove(PARENT_CLASS_NAME)
to_put.append(entity)
if to_put:
ndb.put_multi(to_put) # fewer RPCs this way
num_updated += len(to_put)
log_debug('updated %d entities. for a total of %d',
len(to_put), num_updated)
deferred.defer(add_parent_class,
cursor=query.cursor(), num_updated=num_updated)
else:
log_debug('remove_parent_class complete with %d updates',
num_updated)
from google.appengine.ext import ndb
from google.appengine.ext.ndb import polymodel
class GrandParent(polymodel.PolyModel):
field1 = ndb.StringProperty()
class Child(GrandParent):
field2 = ndb.StringProperty()
from google.appengine.ext import ndb
from google.appengine.ext.ndb import polymodel
class GrandParent(polymodel.PolyModel):
field1 = ndb.StringProperty()
class Parent(GrandParent):
field3 = ndb.StringProperty()
class Child(Parent):
field2 = ndb.StringProperty()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment