adding columns is a no-op. just add them in the model and viola.
keep in mind that if there is no data in the columns for existing records
they will not be returned in queries that filter on those columns.
to rename the column (and pretty similarly to add data to a new column):
- create a model that has both the old column and the new column name
- create a controller that iterates over every row in the table. copy data
from the first column to the new column with the new name
- if you have more than say 100 rows you will need to run as a taskqueue or
backend task. more than say 1000 rows and you might have to split taskqueue
tasks
- remember that ID's are not strictly increasing, so if the app is live and
writes may happen to this table during the migration don't sort by ID.
- if you care to delete the old column, create a true google model as a
expando class with the old field not defined, query the rows, delete the old
field and put.
here is a sample method that clears fields from a table (i'm certain that
this does not properly iterate over more than 1000 rows, but i can't find
the fixed version in my source control):
#remove recording to and from fields
def clear_recording_to_from():
remove the device_id and device_token fields from end_user
from google.appengine.ext import db as gdb
from google.appengine.api.datastore_types import Key
from google.appengine.api import taskqueue
class recording(gdb.Expando):
title = gdb.StringProperty(required=False)
#use a random (but invalid) string to make sure we find all objects,
# even those with explicit NULL
rows = recording.gql(WHERE title != 'asegsebob').fetch(limit=1000)
for r in rows:
del r['to']
del r['from']
gdb.put(rows)
if len(rows) == 1000:
#there are probably more to process
taskqueue.add(url=URL(r=request))
return dict(message=Updating recordings)