Python Django——代理模型上的缓存模型计数失败

Python Django——代理模型上的缓存模型计数失败,python,django,caching,django-queryset,Python,Django,Caching,Django Queryset,我发现了一个关于缓存模型queryset计数()的很好的教程。它在大多数方面都是有效的,但在代理模型的情况下,它抛出了一个奇怪的错误 class CachedCountProxy(object): ''' This allows us to monkey-patch count() on QuerySets so we can cache it and speed things up. ''' def __init__(self, queryset, expires=600):

我发现了一个关于缓存模型queryset计数()的很好的教程。它在大多数方面都是有效的,但在代理模型的情况下,它抛出了一个奇怪的错误

class CachedCountProxy(object):
       ''' This allows us to monkey-patch count() on QuerySets so we can cache it and speed things up.
'''

def __init__(self, queryset, expires=600):
    self._queryset = queryset
    self._queryset._original_count = self._queryset.count
    self._sql = self._queryset.query.get_compiler(self._queryset.db).as_sql()
    self._sql = self._sql[0] % self._sql[1]
    self.expires = expires

def __call__(self):
    ''' 1. Check cache
        2. Return cache if it's set
        3. If it's not set, call super and get the count
        4. Cache that for X minutes
    '''
    key = "count_%s" % hashlib.sha224(self._sql).hexdigest()
    count = cache.get(key)
    if count is None:
        count = self._queryset._original_count()
        model_name = self._queryset.model._meta.app_label
        expiration = self.expires
        cache.set(key, count, expiration)
        model_cache_list = cache.get(model_name) or []
        model_cache_list.append(key)
        cache.set(model_name, model_cache_list, expiration)
    return count
然后,我继续对Django Queryset类进行子类化,并以以下方式将上述类作为方法添加

class GenericQuerySet(QuerySet):

    def get_cached_count(self, time=None):
       cached_count = CachedCountProxy(self, expires=time)
       return cached_count()
现在,当我尝试在所有非代理模型查询集上调用get_cached_count时,它成功了。但是,当我在代理模型queryset上调用它时,它会生成以下SQL

 {'time': '0.000', 'sql': u'SELECT COUNT(*) FROM WHERE NOT (`table`.`city_id` IS NULL)'}
注意FROM子句中缺少一个表?这太奇怪了,尤其是因为同一代理模型上的原始count()方法生成了正确的SQL。在绑定_original_count()方法或将queryset作为一个整体绑定到_queryset的过程中发生了一些奇怪的事情


有什么想法吗?

这方面的用例场景是什么?我想不出一个好的理由来自动缓存SQL计数的结果。如果在一段代码中需要多次计数,请将其保存到变量中。随着数据库的变化,这似乎是开始获取不正确计数的一个好方法,但缓存计数却没有。我有几个昂贵的MySQL计数查询,它们在多个线程(每个请求)中被调用。就数据完整性而言,您可以在模型保存/删除/更新或递增/递减计数时使缓存无效。在我的特殊情况下,MySQL的工作负载非常非常倾向于读而不是写,并且可以接受(出于业务目的)显示不是100%最新的计数。因此,为了回答你的问题,我有很多很好的理由来缓存结果。