如何缓存Google App Engine查询 - 如何获取查询字符串/哈希和受影响的表?

时间:2013-06-01 12:28:29

标签: google-app-engine google-cloud-datastore app-engine-ndb

我想在memcache中缓存查询以加快阅读速度。为此我需要一些函数为查询创建一些id。

class DeleteMe(db.Model)
    pass

query = DeleteMe.all()

# how to get query string/hash form query?
# how to get kind name from query?

我想做类似这样的事情(getQueryKey是总是为同一个查询提供相同值的函数):

memcache.set(getQueryKey(query), list(query))

请帮帮我,可以是db或ndb。

3 个答案:

答案 0 :(得分:4)

有类似的问题;这是我的代码:

    def keyFromQuery( query ):
            """
                    Derives a unique Key from a given query.
                    This Key is stable regardless in which order the filter have been applied
                    @param query: Query to derive key from
                    @type query: DB.Query
                    @returns: string
            """
            origFilter = [ (x, y) for x, y in query._get_query().items() ]
            for k, v in query._Query__orderings:
                    origFilter.append( ("__%s ="%k, v) )
            origFilter.append( ("____kind", query._model_class().kind() ) )
            origFilter.sort( key=lambda x: x[0] )
            filterKey = "".join( ["%s%s" % (x, y) for x, y in origFilter ] )
            return( sha256( filterKey ).hexdigest() )

答案 1 :(得分:1)

这没有多大意义。查询不值得缓存:它只是一个无状态对象,可以在一行代码中轻松重新创建。缓存用于实际数据,从数据存储区获取这些数据非常昂贵。

如果您需要轻松引用一系列查询,更好的解决方案可能是将它们简单地存储在字典中,无论是在模块级别还是作为相关模型的类属性。

答案 2 :(得分:1)

使用ndb和memcache查询结果(keys_only)。

def myquery_cached(flush_cache=False):
    key = 'My Query Key'    # make this unique to this query
    ctx = ndb.get_context()
    # if flush_cache is True, skip the cache and run the query
    myclass_keys = None if flush_cache else ctx.memcache_get(key).get_result()
    if not myclass_keys:
        myclass_keys = MyClass.query(...).fetch(keys_only=true)  # the actual query
        ctx.memcache_set(key, myclass_keys)    # store the keys
    return ndb.get_multi(myclass_keys)         # this uses ndb's caching

在调用此代码一次以填充缓存之后,每次后续都会进行两次memcache查询以检索所有结果。

如果要刷新缓存,请调用myquery_cached(True)