开发者

How to delete a column (attribute) from a GAE datastore?

I have a persistent class stored in a GAE datastore. I have removed one of the attributes from the class. The new records in this table show a value <none> for the removed attribute. But is there a way I can completely drop this column off the table?

Thanks.

Added the following 'migration' code according to moraes' suggestion, but it isn't achieving the desired result:

PersistenceManager pm = PMF.get().getPersistenceManager();
try {
    Query q = pm.newQuery(UserLogin.class);
    Collection<UserLogin> list = (Collection<UserLogin>) q.execute();

    Iterator<UserLogin> iter = list.iterator();
    while (iter.hasNext()) {
        UserLogin开发者_JS百科 obj = (UserLogin) iter.next();
        obj.setLoginDate(obj.getLoginDate());
    }

    pm.makePersistentAll(list); 

} finally {
    pm.close();
}


I found the answer to this problem in this Article: http://code.google.com/appengine/articles/update_schema.html

"Removing Deleted Properties from the Datastore

If you remove a property from your model, you will find that existing entities still have the property. It will still be shown in the admin console and will still be present in the datastore. To really clean out the old data, you need to cycle through your entities and remove the data from each one.

  • Make sure you have removed the properties from the model definition.

  • If your model class inherits from db.Model, temporarily switch it to inherit from db.Expando. (db.Model instances can't be modified dynamically, which is what we need to do in the next step.)

  • Cycle through existing entities (like described above). For each entity, use delattr to delete the obsolete property and then save the entity.

  • If your model originally inherited from db.Model, don't forget to change it back after updating all the data."

And here is an example with code: http://sandrylogan.wordpress.com/2010/12/08/delattr/


If you are using ndb (and you probably should), you can easily delete properties by deleting them from entity._properties:

for entity in MyModel.query():
    if 'old_property' in entity._values:
        del entity._properties['old_property']
        del entity._values['old_property']
        entity.put()

Or you could make it faster by using an asynchronous query map:

@ndb.tasklet
def cleanup(entity):
    if 'old_property' in entity._values:
        del entity._properties['old_property']
        del entity._values['old_property']
        yield entity.put_async()

MyModel.query().map(cleanup)


There is no concept of "table" in datastore. Each entity can have arbitrary properties that don't follow a common schema. The only "schema" is in your model code, and existing records don't change automatically when you change your models.

So, to delete the property from existing records, you need to iterate over all records and re-save them without the property.


The datastore viewer gets its list of columns from the datastore stats, which are updated on a regular basis. If you've removed that column from every entity that had it, wait a day or two and the datastore viewer will stop showing it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜