Jerry Zhang
Jerry Zhang

Reputation: 75

redis get function return None

I am working on a flask application that interacts with redis. This applciation is deployed on heroku, with a redis add on.

When I am doing some testing with the interaction, I am not able to get the key value pair that I just set. Instead, I always get None as a return type. Here is the example:

   import Flask
   import redis


   app = Flask(__name__)
   redis_url = os.getenv('REDISTOGO_URL', 'redis://localhost:6379')
   redis = redis.from_url(redis_url)

   @app.route('/test')
   def test():
      redis.set("test", "{test1: test}")
      print redis.get("test")   # print None here
      return "what the freak"


  if __name__ == "__main__":
       app.run(host='0.0.0.0')

As shown above, the test route will print None, means the value is not set. I am confused. When I test the server on my local browser it works, and when I tried interacting with redis using heroku python shell it works too.

testing with python shell:

heroku run python
from server import redis
redis.set('test', 'i am here')  # return True
redis.get('test') # return i am here

I am confused now. How should I properly interact with redis using Flask?

Upvotes: 0

Views: 6888

Answers (2)

nnog
nnog

Reputation: 1682

Redis-py by default constructs a ConnectionPool client, and this is probably what the from_url helper function is doing. While Redis itself is single threaded, the commands from the connection pool have no guaranteed order of execution. For a single client, construct a redis.StrictRedis client directly, or pass through the param connection_pool=none. This is preferable for simple commands, low in number, as there is less connection management overhead. You can alternatively use a pipeline in the context of a connection pool to serialise a batch operation.

https://redis-py.readthedocs.io/en/latest/#redis.ConnectionPool

https://redis-py.readthedocs.io/en/latest/#redis.Redis.pipeline

Upvotes: 1

Jerry Zhang
Jerry Zhang

Reputation: 75

I did more experiments on this. It seems there is an issue related to the delay. the below modification will make it work:

  @app.route('/test')
  def test():
      redis.set("test", "{test1: test}")
      time.sleep(5) # add the delay needed to the let the set finish
      print redis.get("test")   # print "{test1: test}" here
      return "now it works"

I read the documentation on redis, redis seems to be single threaded. So I am not sure why it will execute the get function call before the set function is done. Someone with more experience please post an explanation.

Upvotes: 0

Related Questions