@@ -133,31 +133,73 @@ def convert_index_info_to_schema(index_info: Dict[str, Any]) -> Dict[str, Any]:
133133 Dict[str, Any]: Schema dictionary.
134134 """
135135 index_name = index_info ["index_name" ]
136- prefixes = index_info ["index_definition" ][3 ][0 ]
136+ prefixes = index_info ["index_definition" ][3 ]
137+ # Normalize single-element prefix lists to string for backward compatibility
138+ if isinstance (prefixes , list ) and len (prefixes ) == 1 :
139+ prefixes = prefixes [0 ]
137140 storage_type = index_info ["index_definition" ][1 ].lower ()
138141
139142 index_fields = index_info ["attributes" ]
140143
141144 def parse_vector_attrs (attrs ):
142145 # Parse vector attributes from Redis FT.INFO output
143- # Attributes start at position 6 as key-value pairs
146+ # Format varies significantly between Redis versions:
147+ # - Redis 6.2.6-v9: [... "VECTOR"] - no params returned by FT.INFO
148+ # - Redis 6.2.x: [... "VECTOR", "FLAT", "6", "TYPE", "FLOAT32", "DIM", "3", ...]
149+ # Position 6: algorithm value (e.g., "FLAT" or "HNSW")
150+ # Position 7: param count
151+ # Position 8+: key-value pairs
152+ # - Redis 7.x+: [... "VECTOR", "ALGORITHM", "FLAT", "TYPE", "FLOAT32", "DIM", "3", ...]
153+ # Position 6+: all key-value pairs
154+
155+ # Check if we have any attributes beyond the type declaration
156+ if len (attrs ) <= 6 :
157+ # Redis 6.2.6-v9 or similar: no vector params in FT.INFO
158+ # Return None to signal we can't parse this field properly
159+ return None
160+
144161 vector_attrs = {}
162+ start_pos = 6
163+
164+ # Detect format: if position 6 looks like an algorithm value (not a key),
165+ # we're dealing with the older format
166+ if len (attrs ) > 6 :
167+ pos6_str = str (attrs [6 ]).upper ()
168+ # Check if position 6 is an algorithm value (FLAT, HNSW) vs a key (ALGORITHM, TYPE, DIM)
169+ if pos6_str in ("FLAT" , "HNSW" ):
170+ # Old format (Redis 6.2.x): position 6 is algorithm value, position 7 is param count
171+ # Store the algorithm
172+ vector_attrs ["algorithm" ] = pos6_str
173+ # Skip to position 8 where key-value pairs start
174+ start_pos = 8
175+
145176 try :
146- for i in range (6 , len (attrs ), 2 ):
177+ for i in range (start_pos , len (attrs ), 2 ):
147178 if i + 1 < len (attrs ):
148179 key = str (attrs [i ]).lower ()
149180 vector_attrs [key ] = attrs [i + 1 ]
150181 except (IndexError , TypeError , ValueError ):
182+ # Silently continue - we'll validate required fields below
151183 pass
152184
153185 # Normalize to expected field names
154186 normalized = {}
155187
156- # Handle dims/dim field
188+ # Handle dims/dim field - REQUIRED for vector fields
157189 if "dim" in vector_attrs :
158190 normalized ["dims" ] = int (vector_attrs .pop ("dim" ))
159191 elif "dims" in vector_attrs :
160192 normalized ["dims" ] = int (vector_attrs ["dims" ])
193+ else :
194+ # If dims is missing from normal parsing, try scanning the raw attrs
195+ # This handles edge cases where the format is unexpected
196+ for i in range (6 , len (attrs ) - 1 ):
197+ if str (attrs [i ]).upper () in ("DIM" , "DIMS" ):
198+ try :
199+ normalized ["dims" ] = int (attrs [i + 1 ])
200+ break
201+ except (ValueError , IndexError ):
202+ pass
161203
162204 # Handle distance_metric field
163205 if "distance_metric" in vector_attrs :
@@ -178,10 +220,18 @@ def parse_vector_attrs(attrs):
178220 normalized ["datatype" ] = vector_attrs ["data_type" ].lower ()
179221 elif "datatype" in vector_attrs :
180222 normalized ["datatype" ] = vector_attrs ["datatype" ].lower ()
223+ elif "type" in vector_attrs :
224+ # Sometimes it's just "type" instead of "data_type"
225+ normalized ["datatype" ] = vector_attrs ["type" ].lower ()
181226 else :
182227 # Default to float32 if missing
183228 normalized ["datatype" ] = "float32"
184229
230+ # Validate that we have required dims
231+ if "dims" not in normalized :
232+ # Could not parse dims - this field is not properly supported
233+ return None
234+
185235 return normalized
186236
187237 def parse_attrs (attrs , field_type = None ):
@@ -234,7 +284,12 @@ def parse_attrs(attrs, field_type=None):
234284 field ["path" ] = field_attrs [1 ]
235285 # parse field attrs
236286 if field_attrs [5 ] == "VECTOR" :
237- field ["attrs" ] = parse_vector_attrs (field_attrs )
287+ attrs = parse_vector_attrs (field_attrs )
288+ if attrs is None :
289+ # Vector field attributes cannot be parsed on this Redis version
290+ # Skip this field - it cannot be properly reconstructed
291+ continue
292+ field ["attrs" ] = attrs
238293 else :
239294 field ["attrs" ] = parse_attrs (field_attrs , field_type = field_attrs [5 ])
240295 # append field
0 commit comments