来自 Django 缓存的 TypeError
TypeError from Django Cache
更新:见下文"Even Better Solution"。
这个让我难住了。当我调用 Django REST Framework 生成的 HTML 页面时,它起作用了。当我第二次、第三次、第四次调用它时,我得到:
[26/Oct/2015 15:14:42]"GET /api/rest/v3/dockets/ HTTP/1.1" 500 92424
Internal Server Error: /api/rest/v3/dockets/
Traceback (most recent call last):
File "/home/mlissner/.virtualenvs/courtlistener/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 108, in get_response
response = middleware_method(request)
File "/home/mlissner/.virtualenvs/courtlistener/local/lib/python2.7/site-packages/django/middleware/cache.py", line 134, in process_request
response = self.cache.get(cache_key, None)
File "/home/mlissner/.virtualenvs/courtlistener/local/lib/python2.7/site-packages/django/core/cache/backends/locmem.py", line 54, in get
return pickle.loads(pickled)
TypeError: __new__() takes exactly 3 arguments (2 given)
与我从 Django 获得的 99% 的堆栈跟踪不同,这个堆栈跟踪根本没有提到我的代码,而且似乎只是来自 Django 本身的代码。
我正在使用开发服务器 Django 1.8.7、Django REST Framework 3.2.3 和 Python 2.7。
我的中间件设置是:
MIDDLEWARE_CLASSES = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]
我只在查看 Django REST Framework 页面时看到了这一点。有什么想法吗?
我尝试过的事情
- 正在升级 Django、djangorestframework 和 djangorestframework-filters。
- 正在更改我的
CACHE
设置,使其使用 Redis 而不是 LocMemCache
。我认为这可能会有所帮助,因为评论中有人说将其更改为 FileBasedCache
有帮助。对 redis 的更改本身并没有帮助,尽管将其设置为 DummyCache
确实有效。
解决方案
django-redis-cache
allows you to set different versions of pickle so I've tinkered with that, given that one link hinted at the pickle version being related. At first, this seemed to have no effect, but I filed a bug in django-redis
("PICKLE_VERSION doesn't seem to work"),他们很快就修复了。修复后,我将 PICKLE_VERSION 设置为 1,问题就解决了。
我也 filed a bug in DRF 看看是否有更好的方法来查明这个问题。但是,我不确定这个错误是存在于我的代码中,还是存在于 Django 本身中。
更好的解决方案
看来我是变通大师。但好消息是,这是一个 bug in Django Rest Framework, which has been fixed,并将在 3.3.2 中发布(希望如此)。
很容易理解为什么你的问题只发生在第二次访问该页面时。那是因为当你第一次加载页面时,数据是从数据源(数据库?)中获取的,并写入缓存中。之后,每次页面加载都会直接命中缓存。
看来问题与缓存的数据类型有关。 pickle
模块中引发异常,当从字符串加载缓存数据时,unpickler 错误地检测到数据类型,并调用 class 的 __new__
方法。这就是错误发生的地方。
有些帖子说的是 pickle 卸载错误,看看有没有帮助:
pickle 元组时看起来有问题,您应用中缓存的数据是否包含元组?
This was a bug in Django Rest Framework,已修复,3.3.2发布
更新:见下文"Even Better Solution"。
这个让我难住了。当我调用 Django REST Framework 生成的 HTML 页面时,它起作用了。当我第二次、第三次、第四次调用它时,我得到:
[26/Oct/2015 15:14:42]"GET /api/rest/v3/dockets/ HTTP/1.1" 500 92424
Internal Server Error: /api/rest/v3/dockets/
Traceback (most recent call last):
File "/home/mlissner/.virtualenvs/courtlistener/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 108, in get_response
response = middleware_method(request)
File "/home/mlissner/.virtualenvs/courtlistener/local/lib/python2.7/site-packages/django/middleware/cache.py", line 134, in process_request
response = self.cache.get(cache_key, None)
File "/home/mlissner/.virtualenvs/courtlistener/local/lib/python2.7/site-packages/django/core/cache/backends/locmem.py", line 54, in get
return pickle.loads(pickled)
TypeError: __new__() takes exactly 3 arguments (2 given)
与我从 Django 获得的 99% 的堆栈跟踪不同,这个堆栈跟踪根本没有提到我的代码,而且似乎只是来自 Django 本身的代码。
我正在使用开发服务器 Django 1.8.7、Django REST Framework 3.2.3 和 Python 2.7。
我的中间件设置是:
MIDDLEWARE_CLASSES = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]
我只在查看 Django REST Framework 页面时看到了这一点。有什么想法吗?
我尝试过的事情
- 正在升级 Django、djangorestframework 和 djangorestframework-filters。
- 正在更改我的
CACHE
设置,使其使用 Redis 而不是LocMemCache
。我认为这可能会有所帮助,因为评论中有人说将其更改为FileBasedCache
有帮助。对 redis 的更改本身并没有帮助,尽管将其设置为DummyCache
确实有效。
解决方案
django-redis-cache
allows you to set different versions of pickle so I've tinkered with that, given that one link hinted at the pickle version being related. At first, this seemed to have no effect, but I filed a bug in django-redis
("PICKLE_VERSION doesn't seem to work"),他们很快就修复了。修复后,我将 PICKLE_VERSION 设置为 1,问题就解决了。
我也 filed a bug in DRF 看看是否有更好的方法来查明这个问题。但是,我不确定这个错误是存在于我的代码中,还是存在于 Django 本身中。
更好的解决方案
看来我是变通大师。但好消息是,这是一个 bug in Django Rest Framework, which has been fixed,并将在 3.3.2 中发布(希望如此)。
很容易理解为什么你的问题只发生在第二次访问该页面时。那是因为当你第一次加载页面时,数据是从数据源(数据库?)中获取的,并写入缓存中。之后,每次页面加载都会直接命中缓存。
看来问题与缓存的数据类型有关。 pickle
模块中引发异常,当从字符串加载缓存数据时,unpickler 错误地检测到数据类型,并调用 class 的 __new__
方法。这就是错误发生的地方。
有些帖子说的是 pickle 卸载错误,看看有没有帮助:
pickle 元组时看起来有问题,您应用中缓存的数据是否包含元组?
This was a bug in Django Rest Framework,已修复,3.3.2发布