2016-08-26 12 views
2

現在、PythonとRedisで作業しています。私はFlaskをフレームワークとして持ち、Blueprintに取り組んでいます。Redis get decoratorを設定します

は私のAPIのRedisのでキャッシュを実装するにみると、私はフラスコ-キャッシュRedisの-シンプルキャッシュを試してみました。 弱点Flask-Cacheは、関数のパラメータを変更しても関数を保存します。関数ごとに1回だけ保存します。 redis-simple-cacheによると、私の最後にはお勧めしないSimpleCache-<key name>としてそのキーを保存します。

私の質問は、特定のキーに存在するキーが存在するかどうかを確認したり、検索したり、チェックするデコレータを作成する方法です。 私はセーブデコレータが可能であることを知っています。しかし、検索またはチェックデコレータは可能ですか?私が間違っていれば私を修正してください。ありがとうございました。

答えて

0

あなたは非常にFlask-Cache documentationを読んだことがないように見えますキャッシングはではなく、のパラメータを無視し、キャッシュキーをカスタマイズすることができます。プロジェクトが提供するデコレータは既に、あなたが求める機能を提供します。

から

このデコレータはcache_keyに対してデフォルトでrequest.pathを使用します。

のでデフォルトキャッシュキーはrequest.pathですが、別のキーを指定することができます。 Flask ビュー関数はpath要素から引数を取得するので、デフォルトのrequest.pathが大きな鍵となります。 @cached() decorator documentationから

cached(timeout=None, key_prefix='view/%s', unless=None)

デフォルトでは、キャッシュキーはビュー/ request.pathです。 のkey_prefixを変更することで、このデコレータを任意の機能で使用することができます。トークン%sのkey_prefixにある場合は、それをrequest.pathに置き換えます。 のkey_prefixを変更することで、このデコレータを任意の機能で使用することができます。

key_prefixから[...]は、必要に応じて引数を取りませんが、cache_keyとして使用される文字列を返す呼び出し可能できます。

したがって、key_prefixを関数に設定すると、(引数なしで)呼び出され、キーが生成されます。

また:

返さ飾ら機能は今それに割り当てられた3つの機能の属性があります。

[...]

make_cache_key
使用cache_keyを生成する際に使用される機能:これらの属性は、読み出し/書き込み可能です。

この関数には、view関数が渡されるのと同じ引数が渡されます。これにより、必要なキャッシュキーを作成することができます。 key_prefixを使用し、requestまたはgまたはその他の情報源から詳細を引き出すか、view_function.make_cache_keyに割り当てて、ビュー関数が受け取るのと同じ引数にアクセスします。

はその後@memoize() decoratorがあります:

memoize(timeout=None, make_name=None, unless=None)

は、キャッシュキーで考慮に引数を取り、関数の結果をキャッシュするために使用します。

このデコレータキャッシュは、関数に渡された引数に基づいて純粋に戻り値をキャッシュします。それもmake_cache_key機能をサポートしています。

私は、Google App Engine Flaskのプロジェクト規模をCMSバックアップサイトの1か月あたりのビュー数を2桁にして、Google memcached構造に結果を格納するために両方のデコレータを使用しました。 Redisでこれを行うには、設定オプションの設定が必要です。

0

これはcache decoratorを使用できます。作成するキャッシュオブジェクトは、djangoの代わりにフラスコキャッシュオブジェクトにする必要があります。つまり、cache.getメソッドとcache.setメソッドをサポートする必要があります。これは作成方法に応じてかなり柔軟ですキャッシュキー、すなわち/結果にmy_methodため がkwarg順序が変更されても

  • 使用同じキャッシュ、すなわち、同じキャッシュをキャッシュしないキャッシュにどのような場合に方法
  • に渡されたパラメータ内容に基づいて

    • (a = 1、b = 2)とmy_method(b = 2、a = 1)の呼び出しを行います。

    __author__ = 'Dhruv Pathak' 
    
    
    import cPickle 
    import logging 
    import time 
    from functools import wraps 
    from django.conf import settings 
    import traceback 
    
    """following imports are from datautils.py in this repo, datautils 
    also contains many other useful data utility methods/classes 
    """ 
    from datautils import mDict, mList, get_nested_ordered_dict, nested_path_get 
    
    """following import is specific to django framework, and can be altered 
    based on what type of caching library your code uses""" 
    from django.core.cache import cache, caches 
    
    
    logger = logging.getLogger(__name__) 
    
    def cache_result(cache_key=None, cache_kwarg_keys=None, seconds=900, cache_filter=lambda x: True, cache_setup = "default"): 
        def set_cache(f): 
         @wraps(f) 
         def x(*args, **kwargs): 
          if settings.USE_CACHE is not True: 
           result = f(*args, **kwargs) 
           return result 
          try: 
           # cache_conn should be a cache object supporting get,set methods 
           # can be from python-memcached, pylibmc, django, django-redis-cache, django-redis etc 
           cache_conn = caches[cache_setup] 
          except Exception, e: 
           result = f(*args, **kwargs) 
           return result 
          final_cache_key = generate_cache_key_for_method(f, kwargs, args, cache_kwarg_keys, cache_key) 
          try: 
           result = cache_conn.get(final_cache_key) 
          except Exception, e: 
           result = None 
           if settings.DEBUG is True: 
            raise 
           else: 
            logger.exception("Cache get failed,k::{0},ex::{1},ex::{2}".format(final_cache_key, str(e), traceback.format_exc())) 
    
          if result is not None and cache_filter(result) is False: 
           result = None 
           logger.debug("Cache had invalid result:{0},not returned".format(result)) 
    
          if result is None: # result not in cache 
           result = f(*args, **kwargs) 
           if isinstance(result, (mDict, mList)): 
            result.ot = int(time.time()) 
           if cache_filter(result) is True: 
            try: 
             cache_conn.set(final_cache_key, result, seconds) 
            except Exception, e: 
             if settings.DEBUG is True: 
              raise 
             else: 
              logger.exception("Cache set failed,k::{0},ex::{1},ex::{2},dt::{3}".format(final_cache_key, str(e), traceback.format_exc(), str(result)[0:100],)) 
           #else: 
           # logger.debug("Result :{0} failed,not cached".format(result)) 
    
          else: # result was from cache 
           if isinstance(result, (mDict, mList)): 
            result.src = "CACHE_{0}".format(cache_setup) 
          return result 
         return x 
        return set_cache 
    
    
    def generate_cache_key_for_method(method, method_kwargs, method_args, cache_kwarg_keys=None, cache_key=None): 
        if cache_key is None: 
         if cache_kwarg_keys is not None and len(cache_kwarg_keys) > 0: 
          if len(method_args) > 0: 
           raise Exception("cache_kwarg_keys mode needs set kwargs,args should be empty") 
    
          method_kwargs = get_nested_ordered_dict(method_kwargs) 
          cache_kwarg_values = [nested_path_get(method_kwargs, path_str=kwarg_key, strict=False) for kwarg_key in cache_kwarg_keys] 
          if any([kwarg_value is not None for kwarg_value in cache_kwarg_values]) is False: 
           raise Exception("all cache kwarg keys values are not set") 
    
          final_cache_key = "{0}::{1}::{2}".format(str(method.__module__), str(method.__name__), hash(cPickle.dumps(cache_kwarg_values))) 
         else: 
          final_cache_key = "{0}::{1}".format(str(method.__module__), str(method.__name__)) 
          final_cache_key += "::{0}".format(str(hash(cPickle.dumps(method_args, 0)))) if len(method_args) > 0 else '' 
          final_cache_key += "::{0}".format(str(hash(cPickle.dumps(method_kwargs, 0)))) if len(method_kwargs) > 0 else '' 
        else: 
         final_cache_key = "{0}::{1}::{2}".format(method.__module__, method.__name__, cache_key) 
    
        return final_cache_key 
    

    2-3ユーティリティメソッドが同じレポでこのfileから輸入されて、あなただけの同じファイルでそれらを置くことができます。

  • 関連する問題