jonmiddleton
jonmiddleton

Reputation: 1128

Migrating an App to High-Replication Datastore - now ancestor issues

Following these instructions: http://neogregious.blogspot.com/2011/04/migrating-app-to-high-replication.html

I have managed to migrate to the high replication datastore however I am now getting the following exception:

datastore_errors.BadArgumentError('ancestor argument should match app ("%r" != "%r")' %
        (ancestor.app(), app))

The model data looks something like this:

class base_business(polymodel.PolyModel):
  created = db.DateTimeProperty(auto_now_add=True)

class business(base_business):
  some_data = db.StringProperty()
  etc..

class business_image(db.Model):
  image = db.BlobProperty(default=None)
  mimetype = db.StringProperty()
  comment = db.StringProperty(required=False)

# the image is associated like so
image_item = business_image(parent = business_item, etc... )
image_item.put()  

The new app name has not been assigned to the ancestor model data. At the moment the data is returned however the logs are being populated with this exception message.

The actual stack trace using logging.exception:

2011-11-03 16:45:40.211 ======= get_business_image exception [ancestor argument should match app ("'oldappname'" != "'s~newappname'")] ======= Traceback (most recent call last): File "/base/data/home/apps/s~newappname/3.354412961756003398/oldappname/entities/views.py", line 82, in get_business_image business_img = business_image.gql("WHERE ANCESTOR IS :ref_business and is_primary = True", ref_business = db.Key(business_key)).get() File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py", line 2049, in get results = self.fetch(1, config=config) File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py", line 2102, in fetch raw = raw_query.Get(limit, offset, config=config) File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 1668, in Get config=config, limit=limit, offset=offset, prefetch_size=limit)) File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 1600, in GetBatcher return self.GetQuery().run(_GetConnection(), query_options) File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 1507, in GetQuery order=self.GetOrder()) File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 93, in positional_wrapper return wrapped(*args, **kwds) File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_query.py", line 1722, in init ancestor=ancestor) File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 93, in positional_wrapper return wrapped(*args, **kwds) File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_query.py", line 1561, in init (ancestor.app(), app)) BadArgumentError: ancestor argument should match app ("'oldappname'" != "'s~newappname'")

Is there a way to manually set the app on the model data? Could I do something like this to resolve this?

if( ancestor.app() != app )
  set_app('my_app')
  put()

Before I do this or apply any other HACK is there something I should have done as part of the data migration?

Upvotes: 1

Views: 662

Answers (1)

Nick Johnson
Nick Johnson

Reputation: 101149

This sort of error usually occurs because you're using fully qualified keys somewhere that have been stored in the datastore as strings (instead of ReferenceProperty), or outside the datastore, such as in URLs. You should be able to work around this by reconstructing any keys from external sources such that you ignore the App ID, something like this:

my_key = db.Key.from_path(*db.Key(my_key).to_path())

Upvotes: 3

Related Questions