在Google Colab中使用redis-om JsonModel无法连接Redis Cloud的问题
问题
在Google Colab中使用redis-om的JsonModel将数据以JSON格式持久化到Redis Cloud时,出现连接错误。错误提示尝试连接localhost:6379,但实际Redis Cloud端口并非6379。
错误栈
OSError Traceback (most recent call last) /usr/local/lib/python3.10/dist-packages/redis/connection.py in connect(self) 706 try: ---> 707 sock = self.retry.call_with_retry( 708 lambda: self._connect(), lambda error: self.disconnect(error) 10 frames /usr/local/lib/python3.10/dist-packages/redis/retry.py in call_with_retry(self, do, fail) 45 try: ---> 46 return do() 47 except self._supported_errors as error: /usr/local/lib/python3.10/dist-packages/redis/connection.py in <lambda>() 707 sock = self.retry.call_with_retry( ---> 708 lambda: self._connect(), lambda error: self.disconnect(error) 709 ) /usr/local/lib/python3.10/dist-packages/redis/connection.py in _connect(self) 1005 if err is not None: ---> 1006 raise err 1007 raise OSError("socket.getaddrinfo returned an empty list") /usr/local/lib/python3.10/dist-packages/redis/connection.py in _connect(self) 993 # connect ---> 994 sock.connect(socket_address) 995 OSError: [Errno 99] Cannot assign requested address During handling of the above exception, another exception occurred: ConnectionError Traceback (most recent call last) <ipython-input-27-4ee06a3d036c> in <cell line: 24>() 22 23 # Create an instance of the model class with some data ---> 24 person = Person(name="Alice", age=25, email="alice@example.com") 25 26 # Save the instance to Redis as a JSON document /usr/local/lib/python3.10/dist-packages/redis_om/model/model.py in __init__(self, *args, **kwargs) 1676 1677 def __init__(self, *args, **kwargs): ---> 1678 if not has_redis_json(self.db()): 1679 log.error( 1680 "Your Redis instance does not have the RedisJson module " /usr/local/lib/python3.10/dist-packages/redis_om/checks.py in has_redis_json(conn) 15 if conn is None: 16 conn = get_redis_connection() ---> 17 command_exists = check_for_command(conn, "json.set") 18 return command_exists 19 /usr/local/lib/python3.10/dist-packages/redis_om/checks.py in check_for_command(conn, cmd) 7 @lru_cache(maxsize=None) 8 def check_for_command(conn, cmd): ----> 9 cmd_info = conn.execute_command("command", "info", cmd) 10 return None not in cmd_info 11 /usr/local/lib/python3.10/dist-packages/redis/client.py in execute_command(self, *args, **options) 1264 pool = self.connection_pool 1265 command_name = args[0] ---> 1266 conn = self.connection or pool.get_connection(command_name, **options) 1267 1268 try: /usr/local/lib/python3.10/dist-packages/redis/connection.py in get_connection(self, command_name, *keys, **options) 1459 try: 1460 # ensure this connection is connected to Redis ---> 1461 connection.connect() 1462 # connections that the pool provides should be ready to send 1463 # a command. if not, the connection was either returned to the /usr/local/lib/python3.10/dist-packages/redis/connection.py in connect(self) 711 raise TimeoutError("Timeout connecting to server") 712 except OSError as e: ---> 713 raise ConnectionError(self._error_message(e)) 714 715 self._sock = sock ConnectionError: Error 99 connecting to localhost:6379. Cannot assign requested address.
备注
- Redis Cloud端口不是6379,不清楚脚本为何尝试连接localhost
- Redis Cloud已配置Redis Stack模块
- 使用相同凭证可正常读写流数据,凭证无误
- Redis文档显示JsonModel可用于Redis Cloud
使用的脚本
!pip install redis !pip install redis-om import redis import redis_om from redis_om import JsonModel, Field server_ip = "my correct redis cloud server_ip" port = "my correct redis cloud port" password = "my correct redis cloud password" # Connect to the Redis instance client = redis.Redis(host=server_ip, port=port, password=password) # Define a custom model class using JsonModel class Person(JsonModel): name: str = Field(index=True) age: int email: str # Create an instance of the model class with some data person = Person(name="Alice", age=25, email="alice@example.com") # Save the instance to Redis as a JSON document person.save() # Print the ID and the JSON representation of the instance print(person.id) print(person.to_json())
解决方案
问题核心是JsonModel没有使用你手动创建的Redis连接,而是默认尝试连接本地Redis。以下两种方法可解决:
方法1:设置全局Redis连接
在定义模型前,调用redis_om.set_redis_connection()将你的远程连接设为全局默认:
# ... 原有连接代码 ... client = redis.Redis(host=server_ip, port=port, password=password) # 设置全局连接 redis_om.set_redis_connection(client) # 再定义模型 class Person(JsonModel): name: str = Field(index=True) age: int email: str
方法2:在模型中指定连接
通过模型的Meta类直接绑定你的Redis连接:
# ... 原有连接代码 ... client = redis.Redis(host=server_ip, port=port, password=password) class Person(JsonModel): name: str = Field(index=True) age: int email: str class Meta: database = client
修改后的完整验证脚本
!pip install redis !pip install redis-om import redis import redis_om from redis_om import JsonModel, Field server_ip = "my correct redis cloud server_ip" port = "my correct redis cloud port" password = "my correct redis cloud password" # Connect to the Redis instance client = redis.Redis(host=server_ip, port=port, password=password) # 设置全局连接(或用Meta类方式) redis_om.set_redis_connection(client) # Define a custom model class using JsonModel class Person(JsonModel): name: str = Field(index=True) age: int email: str # Create an instance of the model class with some data person = Person(name="Alice", age=25, email="alice@example.com") # Save the instance to Redis as a JSON document person.save() # Print the ID and the JSON representation of the instance print(person.id) print(person.to_json())
原理说明
JsonModel默认通过get_redis_connection()获取连接,该方法未配置全局连接时会自动尝试连接localhost:6379。通过上述两种方式绑定你配置的Redis Cloud连接,即可解决错误。
内容的提问来源于stack exchange,提问作者a2z Tests
相关产品推荐
相关产品推荐

