【问题标题】:How to delete entities not found in feed on GAE如何删除 GAE 提要中未找到的实体
【发布时间】:2011-09-02 12:25:57
【问题描述】:

我正在更新和添加来自提要的项目(可能有大约 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 对于该提要项都是唯一的并且是一致的。

【问题讨论】:

  • 最简单的可能是比您开始的日期时间更早的时间,不是吗?或者,如果您不经常更新,实际上提前一点时间可能是谨慎的,以避免任何时钟偏差错误或类似错误。使用带有 auto_now=True 的 DateTimeProperty。
  • 并删除我开始之前更新的所有实体?
  • 是的。或者也许在某处设置一个“我不关心日期时间 X 之前的任何事情”值,并将其用作该实体类型的所有查询中的过滤器。如果您由于未能从提要中提取任何项目而没有清空数据库,那么将来可能会更容易处理出现问题。
  • 但这只是在浪费数据存储空间(成本很高),您不觉得吗?
  • 嗯,你当然可以最终删除它们,只是我之前编写过从提要更新数据库的代码,当提要提供者出现故障并为你提供空的时候有点烦人暂时喂食。完全取决于您“备份”的成本是否值得,以及是否认为这是一个小故障而不是真正的更新来说不再有任何项目是否有意义。

标签: python google-app-engine google-cloud-datastore feed


【解决方案1】:

如果你添加一个带有auto_now=True的DateTimeProperty,它将记录每个实体的最后修改时间。由于您更新了提要中的每个项目,因此当您完成时,它们都会在您开始之后有时间,因此任何日期在此之前的内容都不再出现在提要中。

Xavier 的生成计数器同样出色 - 我们所需要的只是保证在两次刷新之间增加,并且在刷新期间永远不会减少。

从文档中不确定,但我希望 DateTimeProperty 大于 IntegerProperty。后者是一个 64 位整数,因此它们可能大小相同,也可能是 DateTimeProperty 存储了多个整数。 A group post 建议可能是 10 个字节而不是 8 个字节。

但请记住,通过添加一个额外的属性来进行查询,无论如何您都在添加另一个索引,因此字段大小的差异被稀释为开销的一部分。此外,即使是 0.24 美元/G/月,40k 乘以几个字节也不算多。

使用生成或日期时间,您不必立即删除数据。您的其他查询可以过滤最近刷新的日期/生成,这意味着您不必立即删除数据。如果提要(或您对它的解析)变得有趣并且无法生成任何项目,或者只生成一些项目,那么将最后一次刷新作为备份可能会很有用。是否值得拥有完全取决于应用程序。

【讨论】:

    【解决方案2】:

    我会添加一个生成计数器

    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)
    

    【讨论】:

    • 什么是“世代标签”?你在 def updateFeed 忘记了一个逗号
    • 一代标签只是你在两次解析之间增加的一个int,它有助于区分哪个解析是当前的,哪个是旧的。事实上你只能使用两个 int 但我觉得增加更好
    • 这几乎和 Steve Jessop 的想法一样好,但是您依赖的提要在同一个更新周期没有给我相同的项目。在我的情况下有时确实会发生
    • 我不明白你说的提要在同一个更新周期没有给我相同的项目是什么意思。
    • 我在偏移量 0 处获取 100 个项目,然后更新提要并在该偏移量中添加一个项目,因此当我在偏移量 100 处获取 100 个项目时,第 100 个项目也会显示,因为它已向上移动.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    相关资源
    最近更新 更多