Fixed #27318 -- Made cache.set_many() return the list of failed keys.
This commit is contained in:
parent
407c1249c9
commit
a027447f56
1
AUTHORS
1
AUTHORS
|
@ -609,6 +609,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
Oliver Beattie <oliver@obeattie.com>
|
Oliver Beattie <oliver@obeattie.com>
|
||||||
Oliver Rutherfurd <http://rutherfurd.net/>
|
Oliver Rutherfurd <http://rutherfurd.net/>
|
||||||
Olivier Sels <olivier.sels@gmail.com>
|
Olivier Sels <olivier.sels@gmail.com>
|
||||||
|
Olivier Tabone <olivier.tabone@ripplemotion.fr>
|
||||||
Orestis Markou <orestis@orestis.gr>
|
Orestis Markou <orestis@orestis.gr>
|
||||||
Orne Brocaar <http://brocaar.com/>
|
Orne Brocaar <http://brocaar.com/>
|
||||||
Oscar Ramirez <tuxskar@gmail.com>
|
Oscar Ramirez <tuxskar@gmail.com>
|
||||||
|
|
|
@ -206,9 +206,13 @@ class BaseCache:
|
||||||
|
|
||||||
If timeout is given, use that timeout for the key; otherwise use the
|
If timeout is given, use that timeout for the key; otherwise use the
|
||||||
default cache timeout.
|
default cache timeout.
|
||||||
|
|
||||||
|
On backends that support it, return a list of keys that failed
|
||||||
|
insertion, or an empty list if all keys were inserted successfully.
|
||||||
"""
|
"""
|
||||||
for key, value in data.items():
|
for key, value in data.items():
|
||||||
self.set(key, value, timeout=timeout, version=version)
|
self.set(key, value, timeout=timeout, version=version)
|
||||||
|
return []
|
||||||
|
|
||||||
def delete_many(self, keys, version=None):
|
def delete_many(self, keys, version=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -134,11 +134,14 @@ class BaseMemcachedCache(BaseCache):
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def set_many(self, data, timeout=DEFAULT_TIMEOUT, version=None):
|
def set_many(self, data, timeout=DEFAULT_TIMEOUT, version=None):
|
||||||
safe_data = {
|
safe_data = {}
|
||||||
self.make_key(key, version=version): value
|
original_keys = {}
|
||||||
for key, value in data.items()
|
for key, value in data.items():
|
||||||
}
|
safe_key = self.make_key(key, version=version)
|
||||||
self._cache.set_multi(safe_data, self.get_backend_timeout(timeout))
|
safe_data[safe_key] = value
|
||||||
|
original_keys[safe_key] = key
|
||||||
|
failed_keys = self._cache.set_multi(safe_data, self.get_backend_timeout(timeout))
|
||||||
|
return [original_keys[k] for k in failed_keys]
|
||||||
|
|
||||||
def delete_many(self, keys, version=None):
|
def delete_many(self, keys, version=None):
|
||||||
self._cache.delete_multi(self.make_key(key, version=version) for key in keys)
|
self._cache.delete_multi(self.make_key(key, version=version) for key in keys)
|
||||||
|
|
|
@ -157,7 +157,8 @@ Minor features
|
||||||
Cache
|
Cache
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
* ...
|
* On memcached, ``cache.set_many()`` returns a list of keys that failed to be
|
||||||
|
inserted.
|
||||||
|
|
||||||
CSRF
|
CSRF
|
||||||
~~~~
|
~~~~
|
||||||
|
|
|
@ -881,6 +881,13 @@ of key-value pairs::
|
||||||
|
|
||||||
Like ``cache.set()``, ``set_many()`` takes an optional ``timeout`` parameter.
|
Like ``cache.set()``, ``set_many()`` takes an optional ``timeout`` parameter.
|
||||||
|
|
||||||
|
On supported backends (memcached), ``set_many()`` returns a list of keys that
|
||||||
|
failed to be inserted.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
|
||||||
|
The return value containing list of failing keys was added.
|
||||||
|
|
||||||
You can delete keys explicitly with ``delete()``. This is an easy way of
|
You can delete keys explicitly with ``delete()``. This is an easy way of
|
||||||
clearing the cache for a particular object::
|
clearing the cache for a particular object::
|
||||||
|
|
||||||
|
|
|
@ -470,6 +470,11 @@ class BaseCacheTests:
|
||||||
self.assertEqual(cache.get("key1"), "spam")
|
self.assertEqual(cache.get("key1"), "spam")
|
||||||
self.assertEqual(cache.get("key2"), "eggs")
|
self.assertEqual(cache.get("key2"), "eggs")
|
||||||
|
|
||||||
|
def test_set_many_returns_empty_list_on_success(self):
|
||||||
|
"""set_many() returns an empty list when all keys are inserted."""
|
||||||
|
failing_keys = cache.set_many({'key1': 'spam', 'key2': 'eggs'})
|
||||||
|
self.assertEqual(failing_keys, [])
|
||||||
|
|
||||||
def test_set_many_expiration(self):
|
def test_set_many_expiration(self):
|
||||||
# set_many takes a second ``timeout`` parameter
|
# set_many takes a second ``timeout`` parameter
|
||||||
cache.set_many({"key1": "spam", "key2": "eggs"}, 1)
|
cache.set_many({"key1": "spam", "key2": "eggs"}, 1)
|
||||||
|
@ -1239,6 +1244,13 @@ class BaseMemcachedTests(BaseCacheTests):
|
||||||
finally:
|
finally:
|
||||||
signals.request_finished.connect(close_old_connections)
|
signals.request_finished.connect(close_old_connections)
|
||||||
|
|
||||||
|
def test_set_many_returns_failing_keys(self):
|
||||||
|
def fail_set_multi(mapping, *args, **kwargs):
|
||||||
|
return mapping.keys()
|
||||||
|
with mock.patch('%s.Client.set_multi' % self.client_library_name, side_effect=fail_set_multi):
|
||||||
|
failing_keys = cache.set_many({'key': 'value'})
|
||||||
|
self.assertEqual(failing_keys, ['key'])
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(MemcachedCache_params, "MemcachedCache backend not configured")
|
@unittest.skipUnless(MemcachedCache_params, "MemcachedCache backend not configured")
|
||||||
@override_settings(CACHES=caches_setting_for_tests(
|
@override_settings(CACHES=caches_setting_for_tests(
|
||||||
|
@ -1247,6 +1259,7 @@ class BaseMemcachedTests(BaseCacheTests):
|
||||||
))
|
))
|
||||||
class MemcachedCacheTests(BaseMemcachedTests, TestCase):
|
class MemcachedCacheTests(BaseMemcachedTests, TestCase):
|
||||||
base_params = MemcachedCache_params
|
base_params = MemcachedCache_params
|
||||||
|
client_library_name = 'memcache'
|
||||||
|
|
||||||
def test_memcached_uses_highest_pickle_version(self):
|
def test_memcached_uses_highest_pickle_version(self):
|
||||||
# Regression test for #19810
|
# Regression test for #19810
|
||||||
|
@ -1270,6 +1283,7 @@ class MemcachedCacheTests(BaseMemcachedTests, TestCase):
|
||||||
))
|
))
|
||||||
class PyLibMCCacheTests(BaseMemcachedTests, TestCase):
|
class PyLibMCCacheTests(BaseMemcachedTests, TestCase):
|
||||||
base_params = PyLibMCCache_params
|
base_params = PyLibMCCache_params
|
||||||
|
client_library_name = 'pylibmc'
|
||||||
# libmemcached manages its own connections.
|
# libmemcached manages its own connections.
|
||||||
should_disconnect_on_close = False
|
should_disconnect_on_close = False
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue