Redis - SET overwriting other types

12.7k views Asked by At

The following code example will be done/written via a Python REPL and the redis-cli.

Redis server v=2.8.4

Background: Storing a long-running key (hash) in a redis key-value store, then attempting to store another key (with the same name, but different type - string) in the same key-value store.

Code will come first, then question(s):

>>> import redis

>>> db = redis.Redis(
...     host='127.0.0.1',
...     port=6379, 
...     password='',
...     db=3)

>>> db.hset("123456", "field1", True)
1

>>> db.type("123456")
b'hash'

>>> db.hgetall("123456")
{b'field1': b'True'}

>>> db.set("123456", "new-value")
True

>>> db.type("123456")
b'string'

>>> db.get("123456")
b'new-value'

You will first notice that the SET option overwrites the HSET. Now when I try to overwrite the SET with:

>>> db.lset("123456", "list1",  "list1value")
Traceback (most recent call last):
  ...
redis.exceptions.ResponseError: WRONGTYPE Operation against a key holding the wrong kind of value
WRONGTYPE Operation against a key holding the wrong kind of value

OR replacing SET with the same HSET:

>>> db.hset("123456", "field1", True)
Traceback (most recent call last):
  ...
redis.exceptions.ResponseError: WRONGTYPE Operation against a key holding the wrong kind of value
WRONGTYPE Operation against a key holding the wrong kind of value

In order to make sure this isn't a redis-py flaw, I tested in the redis-cli:

127.0.0.1:6379> HSET 12345 "field" "value1"
(integer) 0
127.0.0.1:6379> TYPE 12345
hash
127.0.0.1:6379> SET 12345 "newvalue"
OK
127.0.0.1:6379> TYPE 12345
string
127.0.0.1:6379> HSET 12345 "field" "value1"
(error) WRONGTYPE Operation against a key holding the wrong kind of value

Questions:

1) Is this a flaw in Redis or is this actually how it is supposed to work?

2) If this is "how it is supposed to work", why can I not overwrite the SET type with others?

** Edit: As the person answering the question did not understand 3) .. I am editing it

3) Which other type, besides SET, can I use for storing a STRING in the structure (KEY, VALUE) where I can also have a HASH as (KEY, FIELD, VALUE) - where the key is same but of different TYPE(s)?

Eg. I want to do:

127.0.0.1:6379> HSET 12345 "field" "value1"
(integer) 0
127.0.0.1:6379> TYPE 12345
hash
127.0.0.1:6379> SOME-COMMAND 12345 "newvalue"
OK

So that I have 1 hash and 1 "other" type of the same "key" 12345

1

There are 1 answers

2
Itamar Haber On BEST ANSWER
  1. This is the designed behavior, the second sentence in SET's documentation is.

If key already holds a value, it is overwritten, regardless of its type.

  1. No, only SET has that power, other commands will error when presented with the wrong type of value.

  2. Sorry, not following you.