Как удалить столбец (атрибут) из хранилища данных GAE?

У меня есть постоянный класс, хранящийся в хранилище данных GAE. Я удалил один из атрибутов из класса. Новые записи в этой таблице показывают значение <none> для удаленного атрибута. Но есть ли способ полностью исключить этот столбец из таблицы?

Спасибо.

Добавлен следующий код «миграции» в соответствии с предложением Мораеса, но он не дает желаемого результата:

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();
}

person DFB    schedule 16.05.2011    source источник


Ответы (4)


Я нашел ответ на эту проблему в этой статье: 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/

person Ryan Bavetta    schedule 12.03.2012

Если вы используете 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)
person Attila O.    schedule 27.02.2013
comment
эй, я думаю, что вместо удаления должно быть dels, но это отлично сработало для меня, спасибо. - person Ryan Bavetta; 22.10.2013
comment
@RyanBavetta Спасибо, исправлено! - person Attila O.; 22.10.2013

В хранилище данных нет понятия "таблица". Каждая сущность может иметь произвольные свойства, не соответствующие общей схеме. Единственная «схема» находится в коде вашей модели, и существующие записи не изменяются автоматически, когда вы меняете свои модели.

Итак, чтобы удалить свойство из существующих записей, вам нужно перебрать все записи и повторно сохранить их без свойства.

person moraes    schedule 16.05.2011
comment
Мораес - спасибо за помощь. Пожалуйста, обратитесь к коду «миграции» в моем OP. Мой класс UserLogin является постоянным классом, и нежелательное поле было удалено из него. Но почему-то я все еще вижу <none› под старыми записями в хранилище данных. Я что-то пропустил? - person DFB; 16.05.2011
comment
Вам нужно вызвать pm.makePersistentAll(), передав измененные объекты, чтобы сохранить их и эффективно исключить дополнительное свойство, которого больше не существует. - person moraes; 16.05.2011
comment
Я добавил этот вызов в метод, но разницы не было. Смотрите обновленный код в моем OP. Я все еще вижу <none› для значений удаленного свойства. Спасибо. - person DFB; 16.05.2011
comment
Кстати, я думал, что pm.makePersistentAll() не потребуется, так как изменения будут автоматически сохранены при вызове pm.close(). В любом случае результат один. - person DFB; 16.05.2011

Средство просмотра хранилища данных получает список столбцов из статистики хранилища данных, которая регулярно обновляется. Если вы удалили этот столбец из всех объектов, у которых он был, подождите день или два, и средство просмотра хранилища данных перестанет его показывать.

person Nick Johnson    schedule 16.05.2011