【问题标题】:Possible interaction issue between Django 1.7.4 and django-cacheops 2.2.1Django 1.7.4 和 django-cacheops 2.2.1 之间可能的交互问题
【发布时间】:2015-02-03 18:08:43
【问题描述】:

我正在将 django 应用程序从 1.6 升级到 1.7。该应用程序使用django-cacheops 来存储查询结果。切换到 Django 1.7 后,除第一个请求外,所有请求都会引发以下错误:

Traceback (most recent call last):
  File "/data/virtualenv/default/lib/python2.7/site-packages/django/core/handlers/base.py", line 204, in get_response
    response = middleware_method(request, response)
  File "/data/virtualenv/default/lib/python2.7/site-packages/tracking/middleware.py", line 131, in process_response
    visitor = self._refresh_visitor(user, request, now)
  File "/data/virtualenv/default/lib/python2.7/site-packages/tracking/middleware.py", line 60, in _refresh_visitor
    visitor = Visitor.objects.get(pk=session_key)
  File "/data/virtualenv/default/lib/python2.7/site-packages/cacheops/query.py", line 398, in get
    return self.get_queryset().inplace().get(*args, **kwargs)
  File "/data/virtualenv/default/lib/python2.7/site-packages/cacheops/query.py", line 295, in get
    return qs._no_monkey.get(qs, *args, **kwargs)
  File "/data/virtualenv/default/lib/python2.7/site-packages/django/db/models/query.py", line 353, in get
    return clone._result_cache[0]
AttributeError: 'list' object has no attribute '_result_cache'

当AttributeError 被提出时,clone 是一个包含单个项目的列表,但它是django.db.models.query the attribute _result_cache to be that list。

在django-cacheops method that calls that functionself的类型是CacheQuerySet。

我怀疑这个问题的根源是django 代码需要一个QuerySet 对象,而鸭子CacheQuerySet 与QuerySet 的预期不太匹配。

也有可能配置不正确。以下是相关设置:

CACHEOPS_REDIS = {
    'host': 'localhost',
    'port': 6379,
    'db': 10,
    'socket_timeout': 3,
}

CACHEOPS = {
    'core.vantageuser': {'ops':'count', 'timeout':60*2},
    'core.banditarm': {'ops':'all', 'timeout':60*2},
    'core.armmembership': {'ops':'all', 'timeout':60*60*2},
}

CACHEOPS_FAKE = False
CACHEOPS_DEGRADE_ON_FAILURE = True

这是一个应该报告给django-cacheops 的真实问题吗?任何人有任何想法绕过这个问题(设置CACHEOPS_FAKE=True除外)?

[编辑]:

My friend was able to replicate the issue with a bare minimum repo。问题似乎源于django-tracking2 包。

尚无解决方案,但正在努力。

【问题讨论】:

  • 解决办法是停止使用django-tracking2,它坏了。无论如何,它复制了 cacheops 所做的事情。

标签: python django django-1.7 django-cache


【解决方案1】:

你的配置中确实有一个错误'ops':'count' 应该拼写为'ops':['count'](无论如何人们都会这样做,所以下一个版本的 cacheops 会理解这一点)。但是,这不应导致您收到错误。

您的问题很可能来自另一个包,除了 cacheops 与 QuerySet 混淆。因此,请检查是否有任何猴子修补或子类化它。如果__getitem__() 被篡改,请特别注意。

如果您无法确定这是从哪里来的,我建议您对您的项目进行“糟糕透顶”的拆解:删除第三方应用和您的代码,直到一切开始工作,然后注意最后一步。如果它仍然不起作用,那么您可以在 github 上创建一个问题并将您的项目的剩余内容附在此处。

【讨论】:

  • 感谢您的回复!我使用django-cacheops 和django-tracking2 创建了一个新的最小django 项目,并且能够复制该问题。我怀疑我found the culprit。如果我找到解决方案,我会更新。
  • 同样,README of django-cacheops 有一些'ops': 'all' 的示例(例如第71 行)。
  • 'all' 不是缓存操作,它是['fetch', 'get', 'count', 'exists'] 的快捷方式。我知道这很令人困惑。
  • 在tracking2,这绝对是它。它填充查询集内部存储,然后切片使clone 成为一个列表,因此您会收到属性错误。实际上,即使缓存操作被禁用,这也会出错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
  • 2014-11-07
  • 2019-09-21
相关资源
最近更新 更多