【问题标题】:Add a new attribute to entity in datastore?向数据存储中的实体添加新属性?
【发布时间】:2012-02-13 18:58:39
【问题描述】:

我的应用引擎数据存储中有一个实体。这个实体实际上只有一个实例。我可以在我的管理控制台中看到它。是否可以通过管理控制台向实体添加新属性(可能使用 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;

【问题讨论】:

    标签: google-app-engine jdo


    【解决方案1】:

    实现这一点的唯一方法是使用 Boolean 作为新属性的类型。

    比set方法可以接受布尔值,没问题。

    如果您希望 get 方法也返回布尔值。您也可以,但请务必检查该值是否为空,如果是,则返回默认值(例如 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 次操作)

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 嗨,是的,我想我记得过去做过一次,但现在当我用新定义加载它时,它似乎给我抛出了一个异常。用更多细节更新了上面的问题,看起来还可以吗?谢谢
      【解决方案3】:

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

      管理控制台只知道现有实体中的属性。您不能直接使用管理控制台来创建名称未被任何现有实体使用的新属性。 (这只是控制台的一个限制。应用代码可以轻松做到这一点。)

      【讨论】:

      • Dan,这很有道理——但是如果我真的想添加一个原始布尔类型,那么过程是什么?是不是不可能,我们必须使用盒装的布尔类型来代替?谢谢
      • 如果可以存在没有属性集的实体,则必须使用 boxed 类型。 JDO/JPA 没有办法表示“未设置”,所以将值填写为null,不能分配给原始类型。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-17
      • 2013-01-25
      • 1970-01-01
      • 2013-01-06
      • 2010-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多