如何从 GAE 数据存储中删除列(属性)?
Posted
技术标签:
【中文标题】如何从 GAE 数据存储中删除列(属性)?【英文标题】:How to delete a column (attribute) from a GAE datastore? 【发布时间】:2011-08-26 07:15:43 【问题描述】:我有一个存储在 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();
【问题讨论】:
【参考方案1】:我在这篇文章中找到了这个问题的答案: 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/
【讨论】:
【参考方案2】:如果您正在使用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()
或者您可以使用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)
【讨论】:
嘿,我认为“delete”应该是“del”,但这对我很有用,谢谢。 @RyanBavetta 谢谢,已修复!【参考方案3】:数据存储中没有“表”的概念。每个实体都可以具有不遵循通用模式的任意属性。唯一的“模式”在您的模型代码中,当您更改模型时,现有记录不会自动更改。
因此,要从现有记录中删除该属性,您需要遍历所有记录并在没有该属性的情况下重新保存它们。
【讨论】:
moraes - 感谢您的帮助。请参阅我的 OP 中的“迁移”代码。我的 UserLogin 类是持久类,不需要的字段已从中删除。但不知何故,我仍然在数据存储区的旧条目下看到<none
>。我错过了什么吗?
您需要调用 pm.makePersistentAll() 传递更改的实体,以保存它们并有效地排除不再存在的额外属性。
我将该调用添加到方法中,但没有区别。请参阅我的 OP 中的更新代码。对于已删除属性的值,我仍然看到 <none
>。谢谢。
顺便说一句,我认为不需要 pm.makePersistentAll() ,因为更改将通过 pm.close() 调用自动保存。不管怎样,结果都是一样的。【参考方案4】:
数据存储查看器从定期更新的数据存储统计信息中获取其列列表。如果您已从每个拥有该列的实体中删除该列,请等待一两天,数据存储查看器将停止显示它。
【讨论】:
以上是关于如何从 GAE 数据存储中删除列(属性)?的主要内容,如果未能解决你的问题,请参考以下文章
获取属性错误:类型对象“Level_2_Headings”没有属性“祖先”(GAE 数据存储)