2017-04-05 262 views
0

我對這個包的工作有疑問。它如何寫入redis db?Django-redis-cache無法從redis獲取數據

這是我對Redis的設置 -

CACHES = { 
    'default': { 
    'BACKEND': 'redis_cache.RedisCache', 
    'LOCATION': '/var/run/redis/redis.sock', 
    'OPTIONS': { 
     'DB': 2, 
    }, 
}, 
} 

這是我的意見文件,

def postview(request): 
    print("Working") 
    #post_list = Post.objects.all() 
    if cache.get("posts") == None: 
      post_list = Post.objects.all() 
      print("going to be cached") 
      a = cache.get("aman") 
      print("aman ", a) 
      cache.set("posts", post_list, timeout=60*100*10) 
      print("cached") 
    else : 
      post_list = cache.get("posts") 
      aman = cache.get("aman") 
      print(aman, " aman's job") 
      print("already present in cache") 
    context = {"post_list" : post_list} 
    print("Problem") 
    return render(request, 'post_list.html', context) 

@cache_page(60*15*10, key_prefix="cache_redis") 
def testview(request): 
    post_list = cache.get("posts") 
    print("post_list is", post_list) 
    return render(request, 'post_list.html', {"post_list":post_list}) 

@cache_page(60*25*10, key_prefix="cache_test") 
def new(request): 
    print("Hey") 
    print("cache_page is working") 
    return HttpResponse("Hello, I am Mohammed") 

這是我的Redis -cli,

[email protected]:~/test_venv_wrapper/test_redis/cache_redis$ redis-cli 
127.0.0.1:6379> select 2 
OK 
127.0.0.1:6379[2]> set "a" "aman" 
OK 
127.0.0.1:6379[2]> set ":1:a" "theman" 
OK 
127.0.0.1:6379[2]> keys * 
1) "a" 
2)":1:views.decorators.cache.cache_page..GET.ad00468064711919773512f81be0dbc4.d41d8cd98f00b204e9800998ecf8427e.en-us.UTC" 
3) ":1:posts" 
4) ":1:a" 
5) ":1:aman" 
6) ":1:views.decorators.cache.cache_header.cache_test.ad00468064711919773512f81be0dbc4.en-us.UTC" 
7) ":1:views.decorators.cache.cache_header..ad00468064711919773512f81be0dbc4.en-us.UTC" 
8) ":1:b" 
9)":1:views.decorators.cache.cache_page.cache_test.GET.ad00468064711919773512f81be0dbc4.d41d8cd98f00b204e9800998ecf8427e.en-us.UTC" 
10) "aman" 
127.0.0.1:6379[2]> get ":1:a" 
"theman" 
127.0.0.1:6379[2]> get "a" 
"aman" 

這是對應的Redis -cli顯示器

[email protected]:~/test_venv_wrapper/test_redis/cache_redis$ redis-cli monitor 
OK 
1491412249.001149 [0 unix:/var/run/redis/redis.sock] "INFO" 
1491412249.086196 [0 127.0.0.1:44984] "select" "2" 
1491412250.001249 [0 unix:/var/run/redis/redis.sock] "INFO" 
1491412257.001426 [0 unix:/var/run/redis/redis.sock] "INFO" 
1491412257.423536 [2 127.0.0.1:44984] "set" "a" "aman" 
1491412258.001311 [0 unix:/var/run/redis/redis.sock] "INFO" 
1491412269.001211 [0 unix:/var/run/redis/redis.sock] "INFO" 
1491412269.820886 [2 127.0.0.1:44984] "set" ":1:a" "theman" 
1491412270.000741 [0 unix:/var/run/redis/redis.sock] "INFO" 
1491412272.955386 [2 127.0.0.1:44984] "keys" "*" 
1491412273.001121 [0 unix:/var/run/redis/redis.sock] "INFO" 
1491412340.991928 [2 127.0.0.1:44984] "get" ":1:a" 
1491412341.002001 [0 unix:/var/run/redis/redis.sock] "INFO" 
1491412344.106985 [2 127.0.0.1:44984] "get" "a" 
1491412345.001677 [0 unix:/var/run/redis/redis.sock] "INFO" 

這意味着我手動插入數據庫2的數據可用,我可以通過redis-cli獲取。

但是,當我試圖從Django的應用蟒蛇殼取這個手動輸入的數據,出現這種情況,

>>> from django.core.cache import cache 
>>> cache.get("a") 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/usr/local/lib/python2.7/dist-packages/redis_cache/backends/base.py", line 33, in wrapped 
    return method(self, client, key, *args, **kwargs) 
    File "/usr/local/lib/python2.7/dist-packages/redis_cache/backends/base.py", line 259, in get 
    value = self.get_value(value) 
    File "/usr/local/lib/python2.7/dist-packages/redis_cache/backends/base.py", line 210, in get_value 
    value = self.deserialize(value) 
    File "/usr/local/lib/python2.7/dist-packages/redis_cache/backends/base.py", line 197, in deserialize 
    return self.serializer.deserialize(value) 
    File "/usr/local/lib/python2.7/dist-packages/redis_cache/serializers.py", line 42, in deserialize 
    return pickle.loads(force_bytes(value)) 
UnpicklingError: could not find MARK 

下面是與之對應Redis的-CLI顯示器,

OK 
1491413058.004167 [0 unix:/var/run/redis/redis.sock] "INFO" 
1491413059.002746 [0 unix:/var/run/redis/redis.sock] "INFO" 
1491413060.663292 [2 unix:/var/run/redis/redis.sock] "GET" ":1:a" 
1491413061.001167 [0 unix:/var/run/redis/redis.sock] "INFO" 

爲什麼我無法訪問手動寫入的數據?我知道它爲通過django寫入的數據添加了一個前綴。前綴是":1:key_name"。這就是爲什麼我添加了2個鍵,即「a」和「:1:a」。所以當我嘗試訪問「a」時,它會調用「:1:a」。

但是這個錯誤出現了。所以,它肯定可能會以其他方式將數據寫入redis。請告訴我有關錯誤的信息,並告訴我它寫入數據的方式。

回答

1

您正在獲取的錯誤不是數據恢復錯誤,數據正在被恢復,但它的格式不正確。

  • 當您手動設置數據時,它將以字節格式設置,而不是醃製格式。
  • 當您通過django-redis設置數據時,您的數據首先使用cPickle進行序列化,然後作爲pickled字符串存儲到redis中。

  • 當您通過django-redis檢索存儲的數據時,會將其作爲pickle序列化的字符串進行檢索,然後反序列化爲相應的python數據類型。

  • 您手動輸入的數據是字符串類型,但不是正確的pickle格式,因此雖然它被回收,但不能轉換爲相應的python類型,並且會出現酸洗錯誤。
  • 解決方案是在django shell或您的代碼中使用django-redis本身來存儲和檢索數據,手動輸入數據會破壞序列化合同。

實施例:

>>> from django.core.cache import cache 
>>> cache.set("THE_KEY","aman") 
True 
>>> cache.get("THE_KEY") 
'aman' 
>>> 
[email protected]:~$ redis-cli 
127.0.0.1:6379> keys * 
1) ":1:THE_KEY" 
127.0.0.1:6379> get ":1:THE_KEY" 
"\x80\x02U\x04amanq\x01." 
127.0.0.1:6379> set "THE_MANUAL_KEY" "aman" 
OK 
127.0.0.1:6379> get "THE_MANUAL_KEY" 
"aman" 
+1

那就是!!!很好的解釋!我只是爲了瞭解這些步驟而在github上放了一個問題。我不知道數據在被緩存之前(通過cache_page修飾器)被序列化。這解釋了我的每一個疑問。謝謝dhruv bhai – Luv33preet

+0

我現在做了,'a =「aman」'; '進口cPickle'; '一個= cPickle.dumps(一)';這是一個現在'S'aman後端'\ np1 \ n的價值。「我複製了這個並在redis-cli'set」key_name「」value「'中做了這個。該值是a(來自python代碼)的複製值。現在在shell中,我試圖找回它。這個錯誤發生了。 'django.core.exceptions.ImproperlyConfigured:請求設置CACHES,但設置未配置。在訪問設置之前,您必須定義環境變量DJANGO_SETTINGS_MODULE或調用settings.configure()。 '我不能複製完整的痕跡,因爲它很長。 – Luv33preet