2020from select_ai .errors import ProfileNotFoundError , VectorIndexNotFoundError
2121from select_ai .profile import Profile
2222from select_ai .sql import (
23+ GET_USER_VECTOR_INDEX ,
2324 GET_USER_VECTOR_INDEX_ATTRIBUTES ,
2425 LIST_USER_VECTOR_INDEXES ,
2526)
2627
27- UNMODIFIABLE_VECTOR_INDEX_ATTRIBUTES = (
28- "location" ,
29- "chunk_size" ,
30- "chunk_overlap" ,
31- "pipeline_name" ,
32- "vector_dimension" ,
33- "vector_table_name" ,
34- "vector_distance_metric" ,
35- )
36-
3728
3829class VectorDBProvider (StrEnum ):
3930 ORACLE = "oracle"
@@ -161,7 +152,7 @@ def _get_attributes(index_name: str) -> VectorIndexAttributes:
161152 :return: select_ai.VectorIndexAttributes
162153 :raises: VectorIndexNotFoundError
163154 """
164- if index_name is None :
155+ if not index_name :
165156 raise AttributeError ("'index_name' is required" )
166157 with cursor () as cr :
167158 cr .execute (
@@ -181,6 +172,27 @@ def _get_attributes(index_name: str) -> VectorIndexAttributes:
181172 else :
182173 raise VectorIndexNotFoundError (index_name = index_name )
183174
175+ @staticmethod
176+ def _get_description (index_name ) -> Union [str , None ]:
177+ """Get description of the Vector Index from USER_CLOUD_VECTOR_INDEXES
178+
179+ :param str index_name: The name of the vector index
180+ :return: Union[str, None] profile description
181+ :raises: ProfileNotFoundError
182+ """
183+ if not index_name :
184+ raise AttributeError ("'index_name' is required" )
185+ with cursor () as cr :
186+ cr .execute (GET_USER_VECTOR_INDEX , index_name = index_name .upper ())
187+ index = cr .fetchone ()
188+ if index :
189+ if index [1 ] is not None :
190+ return index [1 ].read ()
191+ else :
192+ return None
193+ else :
194+ raise VectorIndexNotFoundError (index_name = index_name )
195+
184196 def create (self , replace : Optional [bool ] = False ):
185197 """Create a vector index in the database and populates the index
186198 with data from an object store bucket using an async scheduler job
@@ -292,6 +304,28 @@ def disable(self):
292304 else :
293305 raise
294306
307+ @classmethod
308+ def fetch (cls , index_name : str ) -> "VectorIndex" :
309+ """
310+ Fetches vector index attributes from the
311+ database and builds a proxy object for the
312+ passed index_name
313+
314+ :param str index_name: The name of the vector index
315+ """
316+ description = cls ._get_description (index_name )
317+ attributes = cls ._get_attributes (index_name )
318+ try :
319+ profile = Profile (profile_name = attributes .profile_name )
320+ except ProfileNotFoundError :
321+ profile = None
322+ return cls (
323+ description = description ,
324+ attributes = attributes ,
325+ profile = profile ,
326+ index_name = index_name ,
327+ )
328+
295329 def set_attribute (
296330 self ,
297331 attribute_name : str ,
@@ -377,21 +411,7 @@ def list(cls, index_name_pattern: str = ".*") -> Iterator["VectorIndex"]:
377411 )
378412 for row in cr .fetchall ():
379413 index_name = row [0 ]
380- if row [1 ]:
381- description = row [1 ].read () # Oracle.LOB
382- else :
383- description = None
384- attributes = cls ._get_attributes (index_name = index_name )
385- try :
386- profile = Profile (profile_name = attributes .profile_name )
387- except ProfileNotFoundError :
388- profile = None
389- yield cls (
390- index_name = index_name ,
391- description = description ,
392- attributes = attributes ,
393- profile = profile ,
394- )
414+ yield cls .fetch (index_name = index_name )
395415
396416
397417class AsyncVectorIndex (_BaseVectorIndex ):
@@ -412,6 +432,8 @@ async def _get_attributes(index_name: str) -> VectorIndexAttributes:
412432 :return: select_ai.VectorIndexAttributes
413433 :raises: VectorIndexNotFoundError
414434 """
435+ if not index_name :
436+ raise AttributeError ("'index_name' is required" )
415437 async with async_cursor () as cr :
416438 await cr .execute (
417439 GET_USER_VECTOR_INDEX_ATTRIBUTES , index_name = index_name .upper ()
@@ -430,6 +452,29 @@ async def _get_attributes(index_name: str) -> VectorIndexAttributes:
430452 else :
431453 raise VectorIndexNotFoundError (index_name = index_name )
432454
455+ @staticmethod
456+ async def _get_description (index_name ) -> Union [str , None ]:
457+ """Get description of the Vector Index from USER_CLOUD_VECTOR_INDEXES
458+
459+ :param str index_name: The name of the vector index
460+ :return: Union[str, None] profile description
461+ :raises: ProfileNotFoundError
462+ """
463+ if not index_name :
464+ raise AttributeError ("'index_name' is required" )
465+ async with async_cursor () as cr :
466+ await cr .execute (
467+ GET_USER_VECTOR_INDEX , index_name = index_name .upper ()
468+ )
469+ index = await cr .fetchone ()
470+ if index :
471+ if index [1 ] is not None :
472+ return await index [1 ].read ()
473+ else :
474+ return None
475+ else :
476+ raise VectorIndexNotFoundError (index_name = index_name )
477+
433478 async def create (self , replace : Optional [bool ] = False ) -> None :
434479 """Create a vector index in the database and populates it with data
435480 from an object store bucket using an async scheduler job
@@ -539,6 +584,28 @@ async def disable(self) -> None:
539584 else :
540585 raise
541586
587+ @classmethod
588+ async def fetch (cls , index_name : str ) -> "AsyncVectorIndex" :
589+ """
590+ Fetches vector index attributes from the
591+ database and builds a proxy object for the
592+ passed index_name
593+
594+ :param str index_name: The name of the vector index
595+ """
596+ description = await cls ._get_description (index_name )
597+ attributes = await cls ._get_attributes (index_name )
598+ try :
599+ profile = await AsyncProfile (profile_name = attributes .profile_name )
600+ except ProfileNotFoundError :
601+ profile = None
602+ return cls (
603+ description = description ,
604+ attributes = attributes ,
605+ profile = profile ,
606+ index_name = index_name ,
607+ )
608+
542609 async def set_attribute (
543610 self , attribute_name : str , attribute_value : Union [str , int , float ]
544611 ) -> None :
@@ -605,7 +672,7 @@ async def get_profile(self) -> AsyncProfile:
605672 @classmethod
606673 async def list (
607674 cls , index_name_pattern : str = ".*"
608- ) -> AsyncGenerator [VectorIndex , None ]:
675+ ) -> AsyncGenerator ["AsyncVectorIndex" , None ]:
609676 """List Vector Indexes.
610677
611678 :param str index_name_pattern: Regular expressions can be used
@@ -623,20 +690,5 @@ async def list(
623690 rows = await cr .fetchall ()
624691 for row in rows :
625692 index_name = row [0 ]
626- if row [1 ]:
627- description = await row [1 ].read () # AsyncLOB
628- else :
629- description = None
630- attributes = await cls ._get_attributes (index_name = index_name )
631- try :
632- profile = await AsyncProfile (
633- profile_name = attributes .profile_name ,
634- )
635- except ProfileNotFoundError :
636- profile = None
637- yield VectorIndex (
638- index_name = index_name ,
639- description = description ,
640- attributes = attributes ,
641- profile = profile ,
642- )
693+ index = await cls .fetch (index_name = index_name )
694+ yield index
0 commit comments