From dec3731aaa101c137c7efa0bce72e3f11c484e90 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Sat, 21 Nov 2020 20:01:09 -0500 Subject: [PATCH 1/2] Document the restore(replace) option. --- redis/client.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/redis/client.py b/redis/client.py index 08b03145c5..0a9e437fae 100755 --- a/redis/client.py +++ b/redis/client.py @@ -1815,6 +1815,9 @@ def restore(self, name, ttl, value, replace=False): """ Create a key using the provided serialized value, previously obtained using DUMP. + + ``replace`` allows an existing key on ``name`` to be overridden. If + it's not specified an error is raised on collision. """ params = [name, ttl, value] if replace: From 5abe08afeaf3442fbcd51ce52246ff2cad2df1b9 Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Sat, 21 Nov 2020 20:11:28 -0500 Subject: [PATCH 2/2] Add support for the ABSTTL option of the RESTORE command. --- CHANGES | 2 ++ redis/client.py | 8 +++++++- tests/test_commands.py | 13 +++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index dfae2a10bc..f4974b8299 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,8 @@ @aparcar #1353/#1354 * Added support for the ACL LOG command available in Redis 6. Thanks @2014BDuck. #1307 + * Added support for ABSTTL option of the RESTORE command available in + Redis 5.0. Thanks @charettes. #1423 * 3.5.3 (June 1, 2020) * Restore try/except clauses to __del__ methods. These will be removed in 4.0 when more explicit resource management if enforced. #1339 diff --git a/redis/client.py b/redis/client.py index 0a9e437fae..18553b96ec 100755 --- a/redis/client.py +++ b/redis/client.py @@ -1811,17 +1811,23 @@ def renamenx(self, src, dst): "Rename key ``src`` to ``dst`` if ``dst`` doesn't already exist" return self.execute_command('RENAMENX', src, dst) - def restore(self, name, ttl, value, replace=False): + def restore(self, name, ttl, value, replace=False, absttl=False): """ Create a key using the provided serialized value, previously obtained using DUMP. ``replace`` allows an existing key on ``name`` to be overridden. If it's not specified an error is raised on collision. + + ``absttl`` if True, specified ``ttl`` should represent an absolute Unix + timestamp in milliseconds in which the key will expire. (Redis 5.0 or + greater). """ params = [name, ttl, value] if replace: params.append('REPLACE') + if absttl: + params.append('ABSTTL') return self.execute_command('RESTORE', *params) def set(self, name, value, diff --git a/tests/test_commands.py b/tests/test_commands.py index 211307859a..d1f85b7306 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -642,6 +642,19 @@ def test_dump_and_restore_and_replace(self, r): r.restore('a', 0, dumped, replace=True) assert r['a'] == b'bar' + @skip_if_server_version_lt('5.0.0') + def test_dump_and_restore_absttl(self, r): + r['a'] = 'foo' + dumped = r.dump('a') + del r['a'] + ttl = int( + (redis_server_time(r) + datetime.timedelta(minutes=1)).timestamp() + * 1000 + ) + r.restore('a', ttl, dumped, absttl=True) + assert r['a'] == b'foo' + assert 0 < r.ttl('a') <= 61 + def test_exists(self, r): assert r.exists('a') == 0 r['a'] = 'foo'