Добавить новый атрибут для объекта в хранилище данных? - PullRequest
4 голосов
/ 19 января 2012

В моем хранилище данных движка приложений есть сущность.На самом деле есть только один экземпляр этой сущности.Я вижу это в моей консоли администратора.Можно ли добавить новый атрибут к сущности через консоль администратора (возможно, используя 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 ]

2 голосов
/ 21 июня 2012

Единственный способ реализовать это - использовать Boolean в качестве типа для нового свойства.

Чем в методе set вы можете принять логическое значение, это не проблема.

Если выхотите, чтобы метод get также возвращал логическое значение .. вы также можете, но не забудьте проверить, является ли значение нулевым, и если да, вернуть значение по умолчанию (например, true)

so

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 голос
/ 19 января 2012

Вы не можете сделать это через консоль администратора, но вам не нужно удалять объект.Вместо этого просто обновите его - хранилище данных не применяет схемы для видов.Например, если Foo является подклассом db.Model (Python), измените подкласс модели, чтобы включить новое свойство;извлечь экземпляр модели (например, по его ключу), обновить экземпляр, включая установку значения нового поля;и сохраните измененный экземпляр.Поскольку у вас есть только один экземпляр, это легко.Со многими такими экземплярами для обновления вы, вероятно, захотите сделать это с помощью задач очереди задач или с помощью задания mapreduce.

0 голосов
/ 19 января 2012

Вы объявили новое поле mGraduated, используя логический тип примитива, который не может быть нулевым. Существующая сущность не может быть загружена в класс модели, потому что у нее нет этого свойства. Один из вариантов - объявить это свойство с помощью логического класса, который может принимать нулевое значение.

Консоль администратора знает только о свойствах существующих объектов. Вы не можете напрямую использовать консоль администратора для создания нового свойства с именем, которое не используется никакими существующими объектами. (Это всего лишь ограничение консоли. Код приложения может сделать это легко.)

...