如何从GAE数据存储中删除列(属性)?

8

我有一个存储在GAE数据存储中的持久类。我已经从类中删除了一个属性。这个表中的新记录显示已删除属性的值为<none>。但是,有没有办法完全从表中删除这个列?

谢谢。

根据moraes的建议,添加了以下“迁移”代码,但并未实现期望的结果:

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 obj = (UserLogin) iter.next();
        obj.setLoginDate(obj.getLoginDate());
    }

    pm.makePersistentAll(list); 

} finally {
    pm.close();
}
4个回答

7

我在这篇文章中找到了解决这个问题的答案: http://code.google.com/appengine/articles/update_schema.html

"从数据存储中删除已删除的属性

如果您从模型中删除一个属性,您会发现现有实体仍然具有该属性。它仍然显示在管理员控制台中并且仍然存在于数据存储中。要真正清理旧数据,您需要循环遍历实体并从每个实体中删除数据。

  • 确保您已从模型定义中删除了属性。

  • 如果您的模型类继承自 db.Model,请暂时将其改为继承自 db.Expando。(db.Model 实例无法动态修改,这是我们需要在下一步中执行的操作。)

  • 循环遍历现有实体(就像上面所描述的那样)。对于每个实体,使用 delattr 删除过时的属性,然后保存实体。

  • 如果您的模型最初继承自 db.Model,请不要忘记在更新所有数据后将其改回。

这里有一个带有代码示例的示例: http://sandrylogan.wordpress.com/2010/12/08/delattr/


7
如果你正在使用 ndb (并且你可能应该这样做),你可以通过从 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()

你可以使用异步查询映射来加快速度:

@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)

嘿,我觉得“delete”应该改成“del”,但是这个方法对我很有效,谢谢。 - Ryan Bavetta

5

在Datastore中没有“表”这个概念。每个实体可以具有不符合公共模式的任意属性。唯一的“模式”存在于您的模型代码中,并且当您更改模型时,现有记录不会自动更改。

因此,要从现有记录中删除属性,您需要迭代所有记录,并在不包括该属性的情况下重新保存它们。


moraes - 感谢您的帮助。请参考我在原始帖子中的“迁移”代码。我的UserLogin类是持久化类,不需要的字段已经从中删除。但是在数据存储中旧条目下仍然看到<none>。我错过了什么吗? - DFB
你需要调用pm.makePersistentAll(),将更改后的实体传递进去,以保存它们并有效地排除不再存在的额外属性。 - moraes
我已经将该调用添加到方法中,但没有任何区别。请查看我的原始帖子中的更新代码。我仍然看到已删除属性值的<none>。谢谢。 - DFB
顺便说一句,我认为不需要使用pm.makePersistentAll(),因为更改会在pm.close()调用时自动保存。无论如何,结果都是相同的。 - DFB

4
数据存储查看器从数据存储统计信息中获取其列列表,这些信息会定期更新。如果您已从具有该列的每个实体中删除该列,请等待一两天,数据存储查看器将停止显示它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接