Redis возвращает функцию возврата None

Я работаю над фляжным приложением, которое взаимодействует с Redis. Это приложение развернуто на героку с надстройкой Redis.

Когда я провожу тестирование с взаимодействием, я не могу получить пару ключ-значение, которую я только что установил. Вместо этого я всегда получаю None в качестве возвращаемого типа. Вот пример:

   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')

Как показано выше, тестовый маршрут напечатает None, что означает, что значение не установлено. Я сбит с толку. Когда я тестирую сервер в своем локальном браузере, он работает, и когда я пытался взаимодействовать с Redis с помощью оболочки heroku python, он тоже работает.

тестирование с оболочкой python:

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

Я сейчас в замешательстве. Как мне правильно взаимодействовать с Redis с помощью Flask?


person Jerry Zhang    schedule 21.11.2016    source источник


Ответы (2)


Redis-py по умолчанию создает клиент ConnectionPool, и, вероятно, это то, что делает вспомогательная функция from_url. Хотя сам Redis является однопоточным, команды из пула соединений не имеют гарантированного порядка выполнения. Для одного клиента создайте redis.StrictRedis клиента напрямую или передайте через параметр connection_pool=none. Это предпочтительнее для простых команд с небольшим количеством, так как меньше накладных расходов на управление соединением. В качестве альтернативы вы можете использовать конвейер в контексте пула соединений для сериализации пакетной операции.

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

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

person nnog    schedule 22.11.2016

Я провел больше экспериментов по этому поводу. Кажется, есть проблема, связанная с задержкой. приведенная ниже модификация заставит его работать:

  @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"

Я прочитал документацию по Redis, Redis кажется однопоточным. Поэтому я не уверен, почему он будет выполнять вызов функции get до того, как будет выполнена функция set. Кто-то с большим опытом, пожалуйста, опубликуйте объяснение.

person Jerry Zhang    schedule 21.11.2016