Google App Engine: изменить тысячи сущностей одновременно?

По сути, я хотел бы обновить около 10 000 сущностей одновременно, добавив новое свойство и значение для каждой сущности.

Учитывая этот класс:

Post(ndb.Model):
    title = ndb.StringProperty()
    created_date = ndb.DateTimeProperty()

Я хотел бы запустить какую-то операцию, которая создала бы это новое свойство created_date_string в моих существующих объектах Post и заняла бы поле строковой версией даты.

Post(ndb.Model):
    title = ndb.StringProperty()
    created_date = ndb.DateTimeProperty()
    created_date_string = ndb.StringProperty(required=True)

Как мне справиться с этим?

Лучше всего использовать очереди задач для обновления каждой сущности; мы бы поставили в очередь 10 000 задач. Есть ли лучший подход?


person puoygae    schedule 23.07.2018    source источник


Ответы (2)


Вы можете сделать это в одной задаче, где эта задача выполняет итерацию по сущностям, чтобы обновить их. Вы захотите группировать свои действия, чтобы сделать их более эффективными. Задачи выполняются до 10 минут, и я уверен, что это займет меньше минуты.

Вы уверены, что вам нужна эта новая недвижимость? Вы можете сделать это:

Post(ndb.Model):
    title = ndb.StringProperty()
    created_date = ndb.DateTimeProperty()

    @property
    def created_date_string(self):
        return str(self.created_date)

ОБНОВИТЬ:

Я должен был объяснить запутанную терминологию. Здесь есть два совершенно разных употребления слова «собственность». Свойство в моем ответе относится к Python и не имеет ничего общего с GAE. @property в Python делает функцию похожей на переменную, поэтому она может выполнять x.created_date_string вместо x.created_date_string()

Вместо того, что я написал выше, вы можете сделать:

Post(ndb.Model):
    title = ndb.StringProperty()
    created_date = ndb.DateTimeProperty()

    def created_date_string(self):
        return str(self.created_date)

Это в основном то же самое.

Свойство Python отличается от вычисляемого свойства GAE, которое является фактическим свойством в хранилище данных. Вы также можете использовать это, но зачем хранить избыточные данные, если вам это не нужно.

person gaefan    schedule 23.07.2018
comment
Это похоже на концепцию вычисляемого свойства? Будет ли это вычисляться каждый раз при доступе к этому свойству, и будет ли это стоить? - person puoygae; 24.07.2018

Вы сохраняете String версию свойства created_date в created_date_string. Есть два варианта использования, которые я могу придумать для этого.

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

  2. Отправьте created_date_string в ответе API: если вы отправляете это свойство через API и используете его на стороне клиента (веб-приложение и т. д.). Тогда лучше всего использовать ComputedProperty Google App Engine, как показано ниже.

    created_date_string = ndb.ComputedProperty (лямбда self: str (self.created_date))

    таким образом, ваше свойство created_date_string всегда будет соответствовать created_date и будет автоматически создаваться и сохраняться в DataStore.

Дополнительную информацию о ComputedProperty можно найти здесь

Возвращаясь к вашему первоначальному вопросу о том, как обновить 10 000 объектов. Поскольку это одно задание, я бы рекомендовал использовать deffered. Он также использует очередь задач, но сравнительно прост в использовании. Как указано в определении:

Библиотека deferred позволяет обойти всю работу по настройке выделенных обработчиков задач и сериализации и десериализации ваших параметров, предоставляя простую функцию deferred.defer()

Документацию можно найти здесь. Приведенный пример сам по себе является синонимом того, что вы просите, то есть для запуска пакетных обновлений.

Вот как бы я это сделал.

  1. Напишите специальный обработчик (пример: /runbatchupdate), который запустит обновление с использованием отложенного

  2. Нажмите на обработчик извне или сделайте запись в cron.yaml, чтобы запустить этот обработчик.

Если вам нужен пример кода, прокомментируйте ниже, и я напишу для вас пример обработчика. Надеюсь это поможет

person cheekujha    schedule 24.07.2018
comment
Спасибо, что предложили написать пример кода. Я был бы признателен за обучение на примере! - person puoygae; 29.07.2018