pyobvector 0.2.12__py3-none-any.whl → 0.2.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -89,6 +89,13 @@ class ObVecClient:
89
89
  message=ExceptionsMessage.ClusterVersionIsLow,
90
90
  )
91
91
 
92
+ def refresh_metadata(self, tables: Optional[list[str]] = None):
93
+ """Reload metadata from the database."""
94
+ if tables is None:
95
+ self.metadata_obj.reflect(bind=self.engine, extend_existing=True)
96
+ else:
97
+ self.metadata_obj.reflect(bind=self.engine, only=tables, extend_existing=True)
98
+
92
99
  def _insert_partition_hint_for_query_sql(self, sql: str, partition_hint: str):
93
100
  from_index = sql.find("FROM")
94
101
  assert from_index != -1
@@ -10,7 +10,6 @@ class ARRAY(UserDefinedType):
10
10
  """ARRAY data type definition with support for up to 6 levels of nesting."""
11
11
  cache_ok = True
12
12
  _string = String()
13
- _max_nesting_level = 6
14
13
 
15
14
  def __init__(self, item_type: Union[TypeEngine, type]):
16
15
  """Construct an ARRAY.
@@ -18,25 +17,17 @@ class ARRAY(UserDefinedType):
18
17
  Args:
19
18
  item_type: The data type of items in this array. For nested arrays,
20
19
  pass another ARRAY type.
21
-
22
- Raises:
23
- ValueError: If nesting level exceeds the maximum allowed level (6).
24
20
  """
25
21
  super(UserDefinedType, self).__init__()
26
22
  if isinstance(item_type, type):
27
23
  item_type = item_type()
28
24
  self.item_type = item_type
29
- self._validate_nesting_level()
30
-
31
- def _validate_nesting_level(self):
32
- """Validate that the nesting level does not exceed the maximum allowed level."""
33
- level = 1
34
- current_type = self.item_type
35
- while isinstance(current_type, ARRAY):
36
- level += 1
37
- if level > self._max_nesting_level:
38
- raise ValueError(f"Maximum nesting level of {self._max_nesting_level} exceeded")
39
- current_type = current_type.item_type
25
+ if isinstance(item_type, ARRAY):
26
+ self.dim = item_type.dim + 1
27
+ else:
28
+ self.dim = 1
29
+ if self.dim > 6:
30
+ raise ValueError("Maximum nesting level of 6 exceeded")
40
31
 
41
32
  def get_col_spec(self, **kw): # pylint: disable=unused-argument
42
33
  """Parse to array data type definition in text SQL."""
@@ -46,12 +37,33 @@ class ARRAY(UserDefinedType):
46
37
  base_type = str(self.item_type)
47
38
  return f"ARRAY({base_type})"
48
39
 
40
+ def _get_list_depth(self, value: Any) -> int:
41
+ if not isinstance(value, list):
42
+ return 0
43
+ max_depth = 0
44
+ for element in value:
45
+ current_depth = self._get_list_depth(element)
46
+ if current_depth > max_depth:
47
+ max_depth = current_depth
48
+ return 1 + max_depth
49
+
50
+ def _validate_dimension(self, value: list[Any]):
51
+ arr_depth = self._get_list_depth(value)
52
+ assert arr_depth == self.dim, "Array dimension mismatch, expected {}, got {}".format(self.dim, arr_depth)
53
+
49
54
  def bind_processor(self, dialect):
50
- item_proc = self.item_type.dialect_impl(dialect).bind_processor(dialect)
55
+ item_type = self.item_type
56
+ while isinstance(item_type, ARRAY):
57
+ item_type = item_type.item_type
51
58
 
52
- def process(value: Optional[Sequence[Any]]) -> Optional[str]:
59
+ item_proc = item_type.dialect_impl(dialect).bind_processor(dialect)
60
+
61
+ def process(value: Optional[Sequence[Any] | str]) -> Optional[str]:
53
62
  if value is None:
54
63
  return None
64
+ if isinstance(value, str):
65
+ self._validate_dimension(json.loads(value))
66
+ return value
55
67
 
56
68
  def convert(val):
57
69
  if isinstance(val, (list, tuple)):
@@ -61,12 +73,17 @@ class ARRAY(UserDefinedType):
61
73
  return val
62
74
 
63
75
  processed = convert(value)
76
+ self._validate_dimension(processed)
64
77
  return json.dumps(processed)
65
78
 
66
79
  return process
67
80
 
68
81
  def result_processor(self, dialect, coltype):
69
- item_proc = self.item_type.dialect_impl(dialect).result_processor(dialect, coltype)
82
+ item_type = self.item_type
83
+ while isinstance(item_type, ARRAY):
84
+ item_type = item_type.item_type
85
+
86
+ item_proc = item_type.dialect_impl(dialect).result_processor(dialect, coltype)
70
87
 
71
88
  def process(value: Optional[str]) -> Optional[List[Any]]:
72
89
  if value is None:
@@ -85,7 +102,11 @@ class ARRAY(UserDefinedType):
85
102
  return process
86
103
 
87
104
  def literal_processor(self, dialect):
88
- item_proc = self.item_type.dialect_impl(dialect).literal_processor(dialect)
105
+ item_type = self.item_type
106
+ while isinstance(item_type, ARRAY):
107
+ item_type = item_type.item_type
108
+
109
+ item_proc = item_type.dialect_impl(dialect).literal_processor(dialect)
89
110
 
90
111
  def process(value: Sequence[Any]) -> str:
91
112
  def convert(val):
@@ -100,21 +121,6 @@ class ARRAY(UserDefinedType):
100
121
 
101
122
  return process
102
123
 
103
- def __repr__(self):
104
- """Return a string representation of the array type."""
105
- current_type = self.item_type
106
- nesting_level = 1
107
- base_type = current_type
108
-
109
- # Find the innermost type and count nesting level
110
- while isinstance(current_type, ARRAY):
111
- nesting_level += 1
112
- current_type = current_type.item_type
113
- if not isinstance(current_type, ARRAY):
114
- base_type = current_type
115
-
116
- return f"{nesting_level}D_Array({base_type})"
117
-
118
124
 
119
125
  def nested_array(dim: int) -> Type[ARRAY]:
120
126
  """Create a nested array type class with specified dimensions.
@@ -131,12 +137,22 @@ def nested_array(dim: int) -> Type[ARRAY]:
131
137
  if not 1 <= dim <= 6:
132
138
  raise ValueError("Dimension must be between 1 and 6")
133
139
 
134
- class ArrayType(ARRAY):
140
+ class NestedArray(ARRAY):
141
+ cache_ok = True
142
+ _string = String()
143
+
135
144
  def __init__(self, item_type: Union[TypeEngine, type]):
145
+ super(UserDefinedType, self).__init__()
146
+ if isinstance(item_type, type):
147
+ item_type = item_type()
148
+
149
+ assert not isinstance(item_type, ARRAY), "The item_type of NestedArray should not be an ARRAY type"
150
+
136
151
  nested_type = item_type
137
- for _ in range(dim - 1):
152
+ for _ in range(dim):
138
153
  nested_type = ARRAY(nested_type)
139
- super().__init__(nested_type)
140
154
 
141
- ArrayType.__name__ = f"{dim}D_Array"
142
- return ArrayType
155
+ self.item_type = nested_type.item_type
156
+ self.dim = dim
157
+
158
+ return NestedArray
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyobvector
3
- Version: 0.2.12
3
+ Version: 0.2.13
4
4
  Summary: A python SDK for OceanBase Vector Store, based on SQLAlchemy, compatible with Milvus API.
5
5
  Author: shanhaikang.shk
6
6
  Author-email: shanhaikang.shk@oceanbase.com
@@ -36,7 +36,7 @@ poetry install
36
36
  - install with pip:
37
37
 
38
38
  ```shell
39
- pip install pyobvector==0.2.12
39
+ pip install pyobvector==0.2.13
40
40
  ```
41
41
 
42
42
  ## Build Doc
@@ -6,7 +6,7 @@ pyobvector/client/exceptions.py,sha256=CAsTHR9juYleRjYIa4bqk_lw14h8daBvChKoU0o19
6
6
  pyobvector/client/fts_index_param.py,sha256=hMCjA3Aecnt0uQQT6UQGTIIqdPk1M4gX4-zREDQygLs,1139
7
7
  pyobvector/client/index_param.py,sha256=3gXi66Ey1PO9x5_61CrH7DmPb496kviBQI5NT7nfbGc,6309
8
8
  pyobvector/client/milvus_like_client.py,sha256=CpPo6mkGE8iNFpKGBFof3h7E1VTzy1DAPGlFM9F_s8g,26373
9
- pyobvector/client/ob_vec_client.py,sha256=Yt2nG0w4268hg7DE0tqkGaytGsY-jqojX8hGTQjmsKg,29390
9
+ pyobvector/client/ob_vec_client.py,sha256=QZAZxtSgsS2Z8SgEtsSSUcCroaML_XS-cq7aK-sSxic,29718
10
10
  pyobvector/client/ob_vec_json_table_client.py,sha256=m0Oq41dXEil9S1YCK2_RGbSMziatqAItn8Osk-9rzJI,39066
11
11
  pyobvector/client/partitions.py,sha256=Bxwr5yVNlXwZc7SXBC03NeqL9giy4Fe6S2qZdHD8xGw,15621
12
12
  pyobvector/client/schema_type.py,sha256=u1LJsr1o9lxv2b_6KYu77RciFa1R_Qk69k_WT30x6BU,1582
@@ -15,7 +15,7 @@ pyobvector/json_table/json_value_returning_func.py,sha256=NWSV2zhe2-1KhIprQaFqOH
15
15
  pyobvector/json_table/oceanbase_dialect.py,sha256=lxpbWBQdK18LWXLmGyk_-ODv6VfnwGLHbcpsQMElOUo,4480
16
16
  pyobvector/json_table/virtual_data_type.py,sha256=uQh6ZQ0UbwpVO9TFegGeu4E8bXW7rdLHAXFQJdiEjLs,3467
17
17
  pyobvector/schema/__init__.py,sha256=EU8NH8Q-L05sFBGKPV6yIBUeh5f3awTkArdBJ7d4CvQ,2271
18
- pyobvector/schema/array.py,sha256=cFAbayxsJoArPciawFImH835Wnrfm6KeahjBQB7uS44,4787
18
+ pyobvector/schema/array.py,sha256=PoSBc3qCVdMJcLramZp95t69i15ES1J_bqnFANqQoRs,5255
19
19
  pyobvector/schema/dialect.py,sha256=mdRjn3roztCkk6RXbaB0Wn1uhT2BPS2y18MwL6wW-jo,1840
20
20
  pyobvector/schema/full_text_index.py,sha256=ohQX8uTPdRswEJONuN5A-bNv203d0N0b2BsJ7etx71g,2071
21
21
  pyobvector/schema/geo_srid_point.py,sha256=RwEoCgGTmXDc0le1B2E3mZudtqiFdMf2M0Va1ocmVSY,1210
@@ -30,7 +30,7 @@ pyobvector/schema/vector_index.py,sha256=aNtrEBUclc4s6QuqCZpu3Hj3OdjyhbWgtLiJzo6
30
30
  pyobvector/util/__init__.py,sha256=D9EgRDlcMSDhY3uI__vnCl45Or75dOXMWSval5P5fqs,251
31
31
  pyobvector/util/ob_version.py,sha256=ZIySam8q_MCiwctAiAHPB4GdAzGQiXEo1wVkc9IOTDU,1539
32
32
  pyobvector/util/vector.py,sha256=xyM-NuOyd78K7P3kinqyWvLIzEbf9c-4TKn_QVF7qgw,2265
33
- pyobvector-0.2.12.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
34
- pyobvector-0.2.12.dist-info/METADATA,sha256=b8nShwi2i0RfIRXdmaF-9zgy3LTt0mpujD3tgtOx9L8,6659
35
- pyobvector-0.2.12.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
36
- pyobvector-0.2.12.dist-info/RECORD,,
33
+ pyobvector-0.2.13.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
34
+ pyobvector-0.2.13.dist-info/METADATA,sha256=fxRXFWsunoyvBZ3wW5r7FMo8JB6WZbYBj9ijOtF8tnU,6659
35
+ pyobvector-0.2.13.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
36
+ pyobvector-0.2.13.dist-info/RECORD,,