在数据存储区中向实体添加新属性?

时间:2012-01-19 03:13:42

标签: google-app-engine jdo

我的应用引擎数据存储区中有一个实体。实际上只有这个实体的一个实例。我可以在管理控制台中看到它。是否可以通过管理控制台向实体添加新属性(或许使用gql)?

现在看起来像是:

Entity: Foo
Attributes:  mName,  mAge,  mScore

我想为这个实体添加一个新的布尔属性,比如“mGraduated”或类似的东西。

在最糟糕的情况下,我可以编写一些代码来删除实体,然后保存一个新实体,但是只是想知道。

由于

--------更新---------

尝试将新属性添加到我的类(使用java),从数据存储区加载后,我得到以下内容:

java.lang.NullPointerException: 
  Datastore entity with kind Foo and key Foo(\"Foo\") has a null property named mGraduated.  
  This property is mapped to com.me.types.Foo.mGraduated, which cannot accept null values.

这是我的实体类的样子,我刚刚添加了新属性(mGraduated),然后进行了部署,然后尝试从数据存储区加载单个实体(产生了上述异常):

@PersistenceCapable
public class Foo
{   
  @PrimaryKey
  private String k;

  /** Some old attributes, look like the following. */
  @Persistent
  @Extension(vendorName = "datanucleus", key = "gae.unindexed", value="true")
  private String mName;

  ... 

  /** Tried adding the new one. */
  @Persistent
  @Extension(vendorName = "datanucleus", key = "gae.unindexed", value="true")
  private boolean mGraduated;

3 个答案:

答案 0 :(得分:2)

实现此目的的唯一方法是使用Boolean作为新属性的类型..

比在set方法中,你可以接受布尔值,这没有问题。

如果你想让get方法也返回boolean ..你也可以,但一定要检查该值是否为null,如果是这样..返回默认值(例如true)

所以

private Boolean newProp = null; // can also assing default value .. e.g. true;

public void setNewProp(boolean val)
{
    this.newProp = val;
}

public boolean getNewProp()
{
    if(this.newProp == null)
        return true; // Default value if not set

    return this.newProp.booleanValue();

}

我建议您不要在这种情况下迁移数据 - 这可能非常昂贵并且可能会轻易耗尽您的配额(读取旧数据,为数据存储中的每个条目创建新的,删除旧= 3操作)

答案 1 :(得分:1)

您无法通过管理控制台执行此操作,但您不必删除该实体。而只是更新它 - 数据存储区不会为Kinds强制执行模式。 例如,如果Foo是db.Model(Python)的子类,则更改模型子类以包含新属性;获取模型实例(例如,通过其键),更新实例,包括设置新字段的值;并保存修改后的实例。由于你只有一个实例,这很容易。有许多此类实例需要更新,您可能希望通过任务队列任务或mapreduce工作来执行此操作。

答案 2 :(得分:0)

您已使用基元类型boolean声明了新的mGraduated字段,该字段不能为null。现有实体无法加载到模型类中,因为它没有此属性。一种选择是使用Boolean类声明此属性,该类可以接受空值。

管理控制台仅了解现有实体中的属性。您无法直接使用管理控制台创建名称未被任何现有实体使用的新属性。 (这只是控制台的限制。应用程序代码可以轻松完成此任务。)