Как удалить сущности, не найденные в ленте в GAE - PullRequest
0 голосов
/ 02 сентября 2011

Я обновляю и добавляю элементы из канала (который может содержать около 40000 элементов) в хранилище данных по 200 элементов за раз, проблема в том, что канал может измениться, и некоторые элементы могут быть удалены из канала. У меня есть этот код:

class FeedEntry(db.Model):
    name = db.StringProperty(required=True)

def updateFeed(offset, number=200):
    response = fetchFeed(offset, number)
    feedItems = parseFeed(response)
    feedEntriesToAdd = []
    for item in feedItems:
        feedEntriesToAdd.append(
            FeedEntry(key_name=item.id, name=item.name)
        )
    db.put(feedEntriesToAdd)

Как узнать, каких элементов не было в ленте, и удалить их из хранилища данных? Я подумал о создании списка элементов (в хранилище данных) и просто удалил оттуда все элементы, которые я обновил, и те, которые остались, будут удалять. - но это кажется довольно медленным.

PS: все item.id уникальны для этого элемента фида и соответствуют.

Ответы [ 2 ]

2 голосов
/ 02 сентября 2011

Если вы добавите DateTimeProperty с auto_now=True, он будет записывать время последнего изменения каждой сущности.Поскольку вы обновляете каждый элемент в ленте, к тому времени, как вы закончите, у всех будет время после того, как вы начали, поэтому все, что с датой до этого, больше не будет в ленте.

КсавьеСчетчик генерации также хорош - все, что нам нужно, это что-то, что гарантированно увеличивается между обновлениями и никогда не уменьшается во время обновления.

Не уверен из документов, но я ожидаю, что DateTimeProperty больше, чем IntegerProperty.Последнее представляет собой 64-разрядное целое число, поэтому они могут быть одинакового размера, или DateTimeProperty может хранить несколько целых чисел. Групповое сообщение предполагает, что, возможно, это 10 байт, а не 8.

Но помните, что, добавляя дополнительное свойство, к которому вы выполняете запросы, вы все равно добавляете другой индекс, поэтому разницапо размеру поля разбавляется как пропорция накладных расходов.Кроме того, 40 тыс. Раз несколько байтов - это немного, даже при цене 0,24 долл. США / г / месяц.

При использовании поколения или даты-времени необязательно удалять данные немедленно.Другие ваши запросы могут фильтровать по дате / генерации самого последнего обновления, что означает, что вам не нужно удалять данные немедленно.Если канал (или ваш анализ) выглядит смешно и не может производить какие-либо элементы или производит только несколько, может быть полезно оставить последнее обновление в качестве резервной копии.От приложения полностью зависит, стоит ли оно иметь.

1 голос
/ 02 сентября 2011

Я бы добавил счетчик генерации

class FeedEntry(db.Model):
    name = db.StringProperty(required=True)
    generation = db.IntegerProperty(required=True)
def updateFeed(offset, generation, number=200):
    response = fetchFeed(offset, number)
    feedItems = parseFeed(response)
    feedEntriesToAdd = []
    for item in feedItems:
        feedEntriesToAdd.append(
            FeedEntry(key_name=item.id, name=item.name,generation=generation)
        )
    db.put(feedEntriesToAdd)
def deleteOld(generation):
    q = db.GqlQuery("SELECT * FROM FeedEntry " +
            "WHERE generation != :1" ,generation )
    db.delete(generation)
...