# Flask-Cache
## 安裝
使用下面的命令行安裝 Flask-Cache:
```
$ easy_install Flask-Cache
```
或者可以用下面的命令行,如果安裝了 pip:
```
$ pip install Flask-Cache
```
## 使用
緩存(Cache)是通過使用一個 `Cache` 實例進行管理:
```
from flask import Flask
from flask.ext.cache import Cache
app = Flask(__name__)
# Check Configuring Flask-Cache section for more details
cache = Cache(app,config={'CACHE_TYPE': 'simple'})
```
你能夠用 **init_app** 方法在初始化 `Cache` 后設置它:
```
cache = Cache(config={'CACHE_TYPE': 'simple'})
app = Flask(__name__)
cache.init_app(app)
```
如果有多個 `Cache` 實例以及每一個實例都有不同后端的話(換句話說,就是每一個實例使用不用的緩存類型CACHE_TYPE),使用配置字典是十分有用的:
```
#: Method A: During instantiation of class
cache = Cache(config={'CACHE_TYPE': 'simple'})
#: Method B: During init_app call
cache.init_app(app, config={'CACHE_TYPE': 'simple'})
```
New in version 0.7.
## 緩存視圖函數
使用裝飾器 [`cached()`](#flask.ext.cache.Cache.cached "flask.ext.cache.Cache.cached") 能夠緩存視圖函數。它在默認情況下使用請求路徑(request.path)作為cache_key:
```
@cache.cached(timeout=50)
def index():
return render_template('index.html')
```
該裝飾器有一個可選的參數:`unless`,它允許一個可調用的、返回值是True或者False的函數。如果 `unless` 返回 `True`,將會完全忽略緩存機制(內置的緩存機制會完全不起作用)。
## 緩存其它函數
同樣地,使用 `@cached` 裝飾器也能夠緩存其它非視圖函數的結果。唯一的要求是需要指定 `key_prefix`,否則會使用請求路徑(request.path)作為cache_key:
```
@cache.cached(timeout=50, key_prefix='all_comments')
def get_all_comments():
comments = do_serious_dbio()
return [x.author for x in comments]
cached_comments = get_all_comments()
```
## Memoization(一種緩存技術)
請參看 [`memoize()`](#flask.ext.cache.Cache.memoize "flask.ext.cache.Cache.memoize")
在memoization中,函數參數同樣包含cache_key。
Note
如果函數不接受參數的話,[`cached()`](#flask.ext.cache.Cache.cached "flask.ext.cache.Cache.cached") 和 [`memoize()`](#flask.ext.cache.Cache.memoize "flask.ext.cache.Cache.memoize") 兩者的作用是一樣的。
Memoize同樣也為類成員函數而設計,因為它根據 [identity](http://docs.python.org/library/functions.html#id) 將 ‘self’ 或者 ‘cls’ 參數考慮進作為緩存鍵的一部分。
memoization背后的理論是:在一次請求中如果一個函數需要被調用多次,它只會計算第一次使用這些參數調用該函數。例如,存在一個決定用戶角色的 sqlalchemy對象,在一個請求中可能需要多次調用這個函數。為了避免每次都從數據庫獲取信息,你可以這樣做:
```
class Person(db.Model):
@cache.memoize(50)
def has_membership(self, role_id):
return Group.query.filter_by(user=self, role_id=role_id).count() >= 1
```
Warning
使用可變對象(例如類)作為緩存鍵的一部分是十分棘手的。建議最好不要讓一個對象的實例成為一個memoized函數。然而,memoize在處理參數的時候會執行repr(),因此如果一個對象有`__repr__`函數,并且返回一個唯一標識該對象的字符串,它將能夠作為緩存鍵的一部分。
例如,一個sqlalchemy person對象,它返回數據庫的ID作為唯一標識符的一部分:
```
class Person(db.Model):
def __repr__(self):
return "%s(%s)" % (self.__class__.__name__, self.id)
```
### 刪除memoize的緩存
New in version 0.2.
在每個函數的基礎上,您可能需要刪除緩存。使用上面的例子,讓我們來改變用戶權限,并將它們分配到一個角色,如果它們新擁有或者失去某些成員關系,現在你需要重新計算。你能夠用 [`delete_memoized()`](#flask.ext.cache.Cache.delete_memoized "flask.ext.cache.Cache.delete_memoized") 函數來達到目的:
```
cache.delete_memoized('user_has_membership')
```
Note
如果僅僅只有函數名作為參數,所有的memoized的版本將會無效的。然而,您可以刪除特定的緩存提供緩存時相同的參數值。在下面的例子中,只有 `user` 角色緩存被刪除:
```
user_has_membership('demo', 'admin')
user_has_membership('demo', 'user')
cache.delete_memoized('user_has_membership', 'demo', 'user')
```
## 緩存Jinja2片段
用法:
```
{% cache [timeout [,[key1, [key2, ...]]]] %}
...
{% endcache %}
```
默認情況下“模版文件路徑”+“片段開始的函數”用來作為緩存鍵。同樣鍵名是可以手動設置的。鍵名串聯成一個字符串,這樣能夠用于避免同樣的塊在不同模版被重復計算。
設置 timeout 為 None,并且使用了自定義的鍵:
```
{% cache None "key" %}...
```
為了刪除緩存值,為“del”設置超時時間:
```
{% cache 'del' %}...
```
如果提供鍵名,你可以很容易地產生模版的片段密鑰,從模板上下文外刪除它:
```
from flask.ext.cache import make_template_fragment_key
key = make_template_fragment_key("key1", vary_on=["key2", "key3"])
cache.delete(key)
```
例子:
```
Considering we have render_form_field and render_submit macroses.
{% cache 60*5 %}
<form>
{% render_form_field form.username %}
{% render_submit %}
</form>
{% endcache %}
```
## 清除緩存
請參看 [`clear()`](#flask.ext.cache.Cache.clear "flask.ext.cache.Cache.clear").
下面的例子是一個用來清空應用緩存的腳本:
```
from flask.ext.cache import Cache
from yourapp import app, your_cache_config
cache = Cache()
def main():
cache.init_app(app, config=your_cache_config)
with app.app_context():
cache.clear()
if __name__ == '__main__':
main()
```
Warning
某些緩存類型不支持完全清空緩存。同樣,如果你不使用鍵前綴,一些緩存類型將刷新整個數據庫。請確保你沒有任何其他數據存儲在緩存數據庫中。
## 配置Flask-Cache
Flask-Cache有下面一些配置項:
`CACHE_TYPE`
指定哪些類型的緩存對象來使用。 這是一個輸入字符串,將被導入并實例化。 它假設被導入的對象是一個依賴于werkzeug緩存API, 返回緩存對象的函數。
對于werkzeug.contrib.cache對象,不必給出完整的字符串, 只要是下列這些名稱之一。
內建緩存類型:
* **null**: NullCache (default)
* **simple**: SimpleCache
* **memcached**: MemcachedCache (pylibmc or memcache required)
* **gaememcached**: GAEMemcachedCache
* **redis**: RedisCache (Werkzeug 0.7 required)
* **filesystem**: FileSystemCache
* **saslmemcached**: SASLMemcachedCache (pylibmc required)
| | |
| --- | --- |
| `CACHE_NO_NULL_WARNING` | 當使用的緩存類型是’null’,不會拋出警告信息。 |
| `CACHE_ARGS` | 可選的列表,在緩存類實例化的時候會對該列表進行拆分以及傳遞(傳參)。 |
| `CACHE_OPTIONS` | 可選的字典,在緩存類實例化的時候會傳遞該字典(傳參)。 |
| `CACHE_DEFAULT_TIMEOUT` | 如果沒有設置延遲時間,默認的延時時間會被使用。單位為秒。 |
| `CACHE_THRESHOLD` | 最大的緩存條目數,超過該數會刪除一些緩存條目。僅僅用于SimpleCache和 FileSystemCache。 |
| `CACHE_KEY_PREFIX` | 所有鍵之前添加的前綴。 這使得它可以為不同的應用程序使用相同的memcached服務器。 僅僅用于RedisCache,MemcachedCache以及GAEMemcachedCache。 |
| `CACHE_MEMCACHED_SERVERS` | 服務器地址列表或元組。僅用于MemcachedCache。 |
| `CACHE_MEMCACHED_USERNAME` | SASL與memcached服務器認證的用戶名。 僅用于SASLMemcachedCache。 |
| `CACHE_MEMCACHED_PASSWORD` | SASL與memcached服務器認證的密碼。 僅用于SASLMemcachedCache。 |
| `CACHE_REDIS_HOST` | Redis服務器的主機。僅用于RedisCache。 |
| `CACHE_REDIS_PORT` | Redis服務器的端口。默認是6379。僅用于RedisCache。 |
| `CACHE_REDIS_PASSWORD` | 用于Redis服務器的密碼。僅用于RedisCache。 |
| `CACHE_REDIS_DB` | Redis的db庫 (基于零號索引)。默認是0。僅用于RedisCache。 |
| `CACHE_DIR` | 存儲緩存的目錄。僅用于FileSystemCache。 |
| `CACHE_REDIS_URL` | 連接到Redis服務器的URL。 例如:`redis://user:password@localhost:6379/2`。 僅用于RedisCache。 |
此外,如果標準的Flask配置項 `TESTING` 使用并且設置為True的話, **Flask-Cache** 將只會使用NullCache作為緩存類型。
## 內建的緩存類型
### NullCache – null
不緩存內容
* CACHE_ARGS
* CACHE_OPTIONS
### SimpleCache – simple
使用本地Python字典緩存。這不是真正的線程安全。
相關配置
* CACHE_DEFAULT_TIMEOUT
* CACHE_THRESHOLD
* CACHE_ARGS
* CACHE_OPTIONS
### FileSystemCache – filesystem
使用文件系統來存儲緩存值
* CACHE_DEFAULT_TIMEOUT
* CACHE_DIR
* CACHE_THRESHOLD
* CACHE_ARGS
* CACHE_OPTIONS
### MemcachedCache – memcached
使用memcached服務器作為后端。支持pylibmc或memcache或谷歌應用程序引擎的memcache庫。
相關配置項
* CACHE_DEFAULT_TIMEOUT
* CACHE_KEY_PREFIX
* CACHE_MEMCACHED_SERVERS
* CACHE_ARGS
* CACHE_OPTIONS
### GAEMemcachedCache – gaememcached
MemcachedCache一個不同的名稱
### SASLMemcachedCache – saslmemcached
使用memcached服務器作為后端。使用SASL建立與memcached服務器的連接。pylibmc是必須的,libmemcached必須支持SASL。
相關配置項
* CACHE_DEFAULT_TIMEOUT
* CACHE_KEY_PREFIX
* CACHE_MEMCACHED_SERVERS
* CACHE_MEMCACHED_USERNAME
* CACHE_MEMCACHED_PASSWORD
* CACHE_ARGS
* CACHE_OPTIONS
New in version 0.10.
### SpreadSASLMemcachedCache – spreadsaslmemcachedcache
與SASLMemcachedCache一樣,但是如果大于memcached的傳輸安全性,默認是1M,能夠跨不同的鍵名緩存值。使用pickle模塊。
New in version 0.11.
### RedisCache – redis
* CACHE_DEFAULT_TIMEOUT
* CACHE_KEY_PREFIX
* CACHE_REDIS_HOST
* CACHE_REDIS_PORT
* CACHE_REDIS_PASSWORD
* CACHE_REDIS_DB
* CACHE_ARGS
* CACHE_OPTIONS
* CACHE_REDIS_URL
## 定制緩存后端(后臺)
你能夠輕易地定制緩存后端,只需要導入一個能夠實例化以及返回緩存對象的函數。`CACHE_TYPE` 將是你自定義的函數名的字符串。 這個函數期望得到三個參數。
* `app`
* `args`
* `kwargs`
你自定義的緩存對象必須是 `werkzeug.contrib.cache.BaseCache` 的子類。確保 `threshold` 是包含在kwargs參數中,因為它是所有BaseCache類通用的。
Redis的緩存實現的一個例子:
```
#: the_app/custom.py
class RedisCache(BaseCache):
def __init__(self, servers, default_timeout=500):
pass
def redis(app, config, args, kwargs):
args.append(app.config['REDIS_SERVERS'])
return RedisCache(*args, **kwargs)
```
在這個例子中,`CACHE_TYPE` 可能就是 `the_app.custom.redis`。
PylibMC緩存實現的一個例子:
```
#: the_app/custom.py
def pylibmccache(app, config, args, kwargs):
return pylibmc.Client(servers=config['CACHE_MEMCACHED_SERVERS'],
username=config['CACHE_MEMCACHED_USERNAME'],
password=config['CACHE_MEMCACHED_PASSWORD'],
binary=True)
```
在這個例子中,`CACHE_TYPE` 可能就是 `the_app.custom.pylibmccache`。
## API
`class flask.ext.cache.Cache(app=None, with_jinja2_ext=True, config=None)`
This class is used to control the cache objects.
`add(*args, **kwargs)`
Proxy function for internal cache object.
`cached(timeout=None, key_prefix='view/%s', unless=None)`
Decorator. Use this to cache a function. By default the cache key is `view/request.path`. You are able to use this decorator with any function by changing the `key_prefix`. If the token `%s` is located within the `key_prefix` then it will replace that with `request.path`
Example:
```
# An example view function
@cache.cached(timeout=50)
def big_foo():
return big_bar_calc()
# An example misc function to cache.
@cache.cached(key_prefix='MyCachedList')
def get_list():
return [random.randrange(0, 1) for i in range(50000)]
my_list = get_list()
```
Note
You MUST have a request context to actually called any functions that are cached.
New in version 0.4: The returned decorated function now has three function attributes assigned to it. These attributes are readable/writable.
**uncached**
The original undecorated function
**cache_timeout**
The cache timeout value for this function. For a custom value to take affect, this must be set before the function is called.
**make_cache_key**
A function used in generating the cache_key used.
Parameters:
* **timeout** – Default None. If set to an integer, will cache for that amount of time. Unit of time is in seconds.
* **key_prefix** –
Default ‘view/%(request.path)s’. Beginning key to . use for the cache key.
New in version 0.3.4: Can optionally be a callable which takes no arguments but returns a string that will be used as the cache_key.
* **unless** – Default None. Cache will _always_ execute the caching facilities unless this callable is true. This will bypass the caching entirely.
`clear()`
Proxy function for internal cache object.
`delete(*args, **kwargs)`
Proxy function for internal cache object.
`delete_many(*args, **kwargs)`
Proxy function for internal cache object.
`delete_memoized(f, *args, **kwargs)`
Deletes the specified functions caches, based by given parameters. If parameters are given, only the functions that were memoized with them will be erased. Otherwise all versions of the caches will be forgotten.
Example:
```
@cache.memoize(50)
def random_func():
return random.randrange(1, 50)
@cache.memoize()
def param_func(a, b):
return a+b+random.randrange(1, 50)
```
```
>>> random_func()
43
>>> random_func()
43
>>> cache.delete_memoized('random_func')
>>> random_func()
16
>>> param_func(1, 2)
32
>>> param_func(1, 2)
32
>>> param_func(2, 2)
47
>>> cache.delete_memoized('param_func', 1, 2)
>>> param_func(1, 2)
13
>>> param_func(2, 2)
47
```
Delete memoized is also smart about instance methods vs class methods.
When passing a instancemethod, it will only clear the cache related to that instance of that object. (object uniqueness can be overridden
> When passing a classmethod, it will clear all caches related across all instances of that class.
Example:
```
class Adder(object):
@cache.memoize()
def add(self, b):
return b + random.random()
```
```
>>> adder1 = Adder()
>>> adder2 = Adder()
>>> adder1.add(3)
3.23214234
>>> adder2.add(3)
3.60898509
>>> cache.delete_memoized(adder.add)
>>> adder1.add(3)
3.01348673
>>> adder2.add(3)
3.60898509
>>> cache.delete_memoized(Adder.add)
>>> adder1.add(3)
3.53235667
>>> adder2.add(3)
3.72341788
```
Parameters:
* **fname** – Name of the memoized function, or a reference to the function.
* **\*args** – A list of positional parameters used with memoized function.
* **\*\*kwargs** – A dict of named parameters used with memoized function.
Note
Flask-Cache uses inspect to order kwargs into positional args when the function is memoized. If you pass a function reference into `fname` instead of the function name, Flask-Cache will be able to place the args/kwargs in the proper order, and delete the positional cache.
However, if `delete_memoized` is just called with the name of the function, be sure to pass in potential arguments in the same order as defined in your function as args only, otherwise Flask-Cache will not be able to compute the same cache key.
Note
Flask-Cache maintains an internal random version hash for the function. Using delete_memoized will only swap out the version hash, causing the memoize function to recompute results and put them into another key.
This leaves any computed caches for this memoized function within the caching backend.
It is recommended to use a very high timeout with memoize if using this function, so that when the version has is swapped, the old cached results would eventually be reclaimed by the caching backend.
`delete_memoized_verhash(f, *args)`
Delete the version hash associated with the function.
..warning:
```
Performing this operation could leave keys behind that have
been created with this version hash. It is up to the application
to make sure that all keys that may have been created with this
version hash at least have timeouts so they will not sit orphaned
in the cache backend.
```
`get(*args, **kwargs)`
Proxy function for internal cache object.
`get_many(*args, **kwargs)`
Proxy function for internal cache object.
`init_app(app, config=None)`
This is used to initialize cache with your app object
`memoize(timeout=None, make_name=None, unless=None)`
Use this to cache the result of a function, taking its arguments into account in the cache key.
Information on [Memoization](http://en.wikipedia.org/wiki/Memoization).
Example:
```
@cache.memoize(timeout=50)
def big_foo(a, b):
return a + b + random.randrange(0, 1000)
```
```
>>> big_foo(5, 2)
753
>>> big_foo(5, 3)
234
>>> big_foo(5, 2)
753
```
New in version 0.4: The returned decorated function now has three function attributes assigned to it.
**uncached**
The original undecorated function. readable only
**cache_timeout**
The cache timeout value for this function. For a custom value to take affect, this must be set before the function is called.
readable and writable
**make_cache_key**
A function used in generating the cache_key used.
readable and writable
Parameters:
* **timeout** – Default None. If set to an integer, will cache for that amount of time. Unit of time is in seconds.
* **make_name** – Default None. If set this is a function that accepts a single argument, the function name, and returns a new string to be used as the function name. If not set then the function name is used.
* **unless** – Default None. Cache will _always_ execute the caching facilities unelss this callable is true. This will bypass the caching entirely.
New in version 0.5: params `make_name`, `unless`
`set(*args, **kwargs)`
Proxy function for internal cache object.
`set_many(*args, **kwargs)`
Proxy function for internal cache object.
## Changelog
### Version 0.13 2014-04-21
* Port to Python >= 3.3 (requiring Python 2.6/2.7 for 2.x).
* Fixed bug with using per-memoize timeouts greater than the default timeout
* Added better support for per-instance memoization.
* Various bug fixes
### Version 0.12 2013-04-29
* Changes jinja2 cache templates to use stable predictable keys. Previously the key for a cache tag included the line number of the template, which made it difficult to predict what the key would be outside of the application.
* Adds config variable `CACHE_NO_NULL_WARNING` to silence warning messages when using ‘null’ cache as part of testing.
* Adds passthrough to clear entire cache backend.
### Version 0.11.1 2013-04-7
* Bugfix for using memoize on instance methods. The previous key was id(self), the new key is repr(self)
### Version 0.11 2013-03-23
* Fail gracefully in production if cache backend raises an exception.
* Support for redis DB number
* Jinja2 templatetag cache now concats all args together into a single key instead of treating each arg as a separate key name.
* Added delete memcache version hash function
* Support for multiple cache objects on a single app again.
* Added SpreadSASLMemcached, if a value is greater than the memcached threshold which defaults to 1MB, this splits the value across multiple keys.
* Added support to use URL to connect to redis.
### Version 0.10.1 2013-01-13
* Added warning message when using cache type of ‘null’
* Changed imports to relative instead of absolute for AppEngine compatibility
### Version 0.10.0 2013-01-05
* Added `saslmemcached` backend to support Memcached behind SASL authentication.
* Fixes a bug with memoize when the number of args != number of kwargs
### Version 0.9.2 2012-11-18
* Bugfix with default kwargs
### Version 0.9.1 2012-11-16
* Fixes broken memoized on functions that use default kwargs
### Version 0.9.0 2012-10-14
* Fixes memoization to work on methods.
### Version 0.8.0 2012-09-30
* Migrated to the new flask extension naming convention of flask_cache instead of flaskext.cache
* Removed unnecessary dependencies in setup.py file.
* Documentation updates
### Version 0.7.0 2012-08-25
* Allows multiple cache objects to be instantiated with different configuration values.
### Version 0.6.0 2012-08-12
* Memoization is now safer for multiple applications using the same backing store.
* Removed the explicit set of NullCache if the Flask app is set testing=True
* Swapped Conditional order for key_prefix
### Version 0.5.0 2012-02-03
* Deleting memoized functions now properly functions in production environments where multiple instances of the application are running.
* get_memoized_names and get_memoized_keys have been removed.
* Added `make_name` to memoize, make_name is an optional callable that can be passed to memoize to modify the cache_key that gets generated.
* Added `unless` to memoize, this is the same as the unless parameter in `cached`
* memoization now converts all kwargs to positional arguments, this is so that when a function is called multiple ways, it would evaluate to the same cache_key
### Version 0.4.0 2011-12-11
* Added attributes for uncached, make_cache_key, cache_timeout to the decorated functions.
### Version 0.3.4 2011-09-10
* UTF-8 encoding of cache key
* key_prefix argument of the cached decorator now supports callables.
### Version 0.3.3 2011-06-03
Uses base64 for memoize caching. This fixes rare issues where the cache_key was either a tuple or larger than the caching backend would be able to support.
Adds support for deleting memoized caches optionally based on function parameters.
Python 2.5 compatibility, plus bugfix with string.format.
Added the ability to retrieve memoized function names or cache keys.
### Version 0.3.2
Bugfix release. Fixes a bug that would cause an exception if no `CACHE_TYPE` was supplied.
### Version 0.3.1
Pypi egg fix.
### Version 0.3
* CACHE_TYPE changed. Now one of [‘null’, ‘simple’, ‘memcached’, ‘gaememcached’, ‘filesystem’], or an import string to a function that will instantiate a cache object. This allows Flask-Cache to be much more extensible and configurable.
### Version 0.2
* CACHE_TYPE now uses an import_string.
* Added CACHE_OPTIONS and CACHE_ARGS configuration values.
* Added delete_memoized
### Version 0.1
* Initial public release