GAE:确定存储多少种类的最佳方法?

时间:2010-07-12 01:45:31

标签: python google-app-engine

确定应用数据存储区中某种型号的最佳方法是什么?文档说MyKind.all().count()只比检索所有数据略好,并且限制为1000.这没有用,因为我希望存储6000多个MyKind实例。 / p>

有更好的方法吗?如果我只拿到钥匙,算一下那会怎么样?

我正在使用Python。

4 个答案:

答案 0 :(得分:5)

如果近似计数足够好,您可以使用统计信息API:

http://code.google.com/appengine/docs/python/datastore/stats.html

答案 1 :(得分:3)

如果你只使用密钥,它应该非常快,因为这只需要读取索引并且实际上不会获取任何实体。使用游标和循环,直到count()返回小于1000。

答案 2 :(得分:2)

This SO question有一个答案(@jgeewax)几乎正确(错误的退出条件,正如我在那里评论的那样)。这是一个固定的......:

class MyModel(db.Expando):
    @classmethod
    def count_all(cls):
        """
        Count *all* of the rows (without maxing out at 1000)
        """
        count = 0
        query = cls.all().order('__key__')

        while True:
            current_count = query.count()
            if current_count == 0: return count
            count += current_count

            if current_count == 1000:
                last_key = query.fetch(1, 999)[0].key()
                query = query.filter('__key__ > ', last_key)

        return count

当然,性能问题是,对于你拥有的每1000个项目,这将对数据存储区使用一个实际查询 - 通过保持实际计数来非正规化,正如@Chris建议的那样,将使用查询次数减少。 (请务必使用sharded counter或其他形式的efficient counters作为App Engine Fan解释!)。

非规范化是非关系数据库生活中的一个事实,而且,如果操作正确,可能会对您的性能造成巨大差异。至于你表达对DRY的担忧,只需使用类方法或其他形式的函数来执行所有实体的放置和删除(即[[在类方法中除外]],从不直接在实体上调用.put()等方法,调用相应的类方法!),这些函数将是保持非规范化计数器最新的明显位置!

答案 3 :(得分:1)

将应用程序的计数器对象保存在数据库中,并在创建和删除对象时更新它。