pyobvector 0.2.15__py3-none-any.whl → 0.2.17__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.
pyobvector/__init__.py CHANGED
@@ -14,6 +14,7 @@ In this mode, you can regard `pyobvector` as an extension of SQLAlchemy.
14
14
  * IndexParams A list of IndexParam to create vector index in batch
15
15
  * DataType Specify field type in collection schema for MilvusLikeClient
16
16
  * VECTOR An extended data type in SQLAlchemy for ObVecClient
17
+ * SPARSE_VECTOR An extended data type in SQLAlchemy for ObVecClient
17
18
  * VectorIndex An extended index type in SQLAlchemy for ObVecClient
18
19
  * FtsIndex Full Text Search Index
19
20
  * FieldSchema Clas to define field schema in collection for MilvusLikeClient
@@ -43,6 +44,7 @@ from .client import *
43
44
  from .schema import (
44
45
  ARRAY,
45
46
  VECTOR,
47
+ SPARSE_VECTOR,
46
48
  POINT,
47
49
  VectorIndex,
48
50
  OceanBaseDialect,
@@ -70,6 +72,7 @@ __all__ = [
70
72
  "DataType",
71
73
  "ARRAY",
72
74
  "VECTOR",
75
+ "SPARSE_VECTOR",
73
76
  "POINT",
74
77
  "VectorIndex",
75
78
  "FtsIndex",
@@ -79,14 +79,14 @@ class FieldSchema:
79
79
  if "max_length" not in self.kwargs:
80
80
  raise VarcharFieldParamException(
81
81
  code=ErrorCode.INVALID_ARGUMENT,
82
- message=ExceptionsMessage.VarcharFieldMissinglengthParam,
82
+ message=ExceptionsMessage.VarcharFieldMissingLengthParam,
83
83
  )
84
84
  self.type_params["length"] = self.kwargs["max_length"]
85
85
  elif self.dtype == DataType.ARRAY:
86
86
  if "element_type" not in self.kwargs:
87
87
  raise ArrayFieldParamException(
88
88
  code=ErrorCode.INVALID_ARGUMENT,
89
- message=ExceptionsMessage.ArrayFiledMissingElementType,
89
+ message=ExceptionsMessage.ArrayFieldMissingElementType,
90
90
  )
91
91
  if self.kwargs["element_type"] in (
92
92
  DataType.ARRAY,
@@ -95,7 +95,7 @@ class FieldSchema:
95
95
  ):
96
96
  raise ArrayFieldParamException(
97
97
  code=ErrorCode.INVALID_ARGUMENT,
98
- message=ExceptionsMessage.ArrayFiledInvalidElementType,
98
+ message=ExceptionsMessage.ArrayFieldInvalidElementType,
99
99
  )
100
100
 
101
101
  self.type_params["item_type"] = convert_datatype_to_sqltype(
@@ -147,9 +147,9 @@ class CollectionSchema:
147
147
  """Add field to collection.
148
148
 
149
149
  Args:
150
- :param field_name (string) : new field name
151
- :param datatype (DataType) : field data type
152
- :param kwargs : parameters for data type
150
+ field_name (string): new field name
151
+ datatype (DataType): field data type
152
+ **kwargs: parameters for data type
153
153
  """
154
154
  field = FieldSchema(field_name, datatype, **kwargs)
155
155
  cur_idx = len(self.fields)
@@ -101,14 +101,14 @@ class ExceptionsMessage:
101
101
  )
102
102
  PrimaryFieldType = "Param primary_field must be int or str type."
103
103
  VectorFieldMissingDimParam = "Param 'dim' must be set for vector field."
104
- VarcharFieldMissinglengthParam = "Param 'max_length' must be set for varchar field."
105
- ArrayFiledMissingElementType = "Param 'element_type' must be set for array field."
106
- ArrayFiledInvalidElementType = (
104
+ VarcharFieldMissingLengthParam = "Param 'max_length' must be set for varchar field."
105
+ ArrayFieldMissingElementType = "Param 'element_type' must be set for array field."
106
+ ArrayFieldInvalidElementType = (
107
107
  "Param 'element_type' can not be array/vector/varchar."
108
108
  )
109
109
  CollectionNotExists = "Collection does not exist."
110
110
  MetricTypeParamTypeInvalid = "MetricType param type should be string."
111
- MetricTypeValueInvalid = "MetricType should be 'l2'/'ip' in ann search."
111
+ MetricTypeValueInvalid = "MetricType should be 'l2'/'ip'/'neg_ip'/'cosine' in ann search."
112
112
  UsingInIDsWhenMultiPrimaryKey = "Using 'ids' when table has multi primary key."
113
113
  ClusterVersionIsLow = (
114
114
  "OceanBase Vector Store is not supported because cluster version is below 4.3.3.0."
@@ -18,13 +18,12 @@ class FtsIndexParam:
18
18
  self.field_names = field_names
19
19
  self.parser_type = parser_type
20
20
 
21
- def param_str(self) -> str:
22
- if self.parser_type is None:
23
- return None
21
+ def param_str(self) -> str | None:
24
22
  if self.parser_type == FtsParser.IK:
25
23
  return "ik"
26
24
  if self.parser_type == FtsParser.NGRAM:
27
25
  return "ngram"
26
+ return None
28
27
 
29
28
  def __iter__(self):
30
29
  yield "index_name", self.index_name
@@ -9,7 +9,7 @@ class VecIndexType(Enum):
9
9
  IVFFLAT = 2
10
10
  IVFSQ = 3
11
11
  IVFPQ = 4
12
-
12
+ DAAT = 5
13
13
 
14
14
  class IndexParam:
15
15
  """Vector index parameters.
@@ -31,6 +31,7 @@ class IndexParam:
31
31
  IVFFLAT_ALGO_NAME = "ivf_flat"
32
32
  IVFSQ_ALGO_NAME = "ivf_sq8"
33
33
  IVFPQ_ALGO_NAME = "ivf_pq"
34
+ DAAT_ALGO_NAME = "daat"
34
35
 
35
36
  def __init__(
36
37
  self, index_name: str, field_name: str, index_type: Union[VecIndexType, str], **kwargs
@@ -57,6 +58,11 @@ class IndexParam:
57
58
  return self.index_type in [
58
59
  IndexParam.IVFPQ_ALGO_NAME,
59
60
  ]
61
+
62
+ def is_index_type_sparse_vector(self):
63
+ return self.index_type in [
64
+ IndexParam.DAAT_ALGO_NAME,
65
+ ]
60
66
 
61
67
  def _get_vector_index_type_str(self):
62
68
  """Parse vector index type to string."""
@@ -71,6 +77,8 @@ class IndexParam:
71
77
  return IndexParam.IVFSQ_ALGO_NAME
72
78
  elif self.index_type == VecIndexType.IVFPQ:
73
79
  return IndexParam.IVFPQ_ALGO_NAME
80
+ elif self.index_type == VecIndexType.DAAT:
81
+ return IndexParam.DAAT_ALGO_NAME
74
82
  raise ValueError(f"unsupported vector index type: {self.index_type}")
75
83
  assert isinstance(self.index_type, str)
76
84
  index_type = self.index_type.lower()
@@ -80,6 +88,7 @@ class IndexParam:
80
88
  IndexParam.IVFFLAT_ALGO_NAME,
81
89
  IndexParam.IVFSQ_ALGO_NAME,
82
90
  IndexParam.IVFPQ_ALGO_NAME,
91
+ IndexParam.DAAT_ALGO_NAME,
83
92
  ]:
84
93
  raise ValueError(f"unsupported vector index type: {self.index_type}")
85
94
  return index_type
@@ -124,15 +133,19 @@ class IndexParam:
124
133
  ob_params['ef_construction'] = params['efConstruction']
125
134
  if 'efSearch' in params:
126
135
  ob_params['ef_search'] = params['efSearch']
136
+
137
+ if self.is_index_type_sparse_vector() and ob_params['distance'] != 'inner_product':
138
+ raise ValueError("Metric type should be 'inner_product' for sparse vector index.")
127
139
  return ob_params
128
140
 
129
141
  def param_str(self):
130
142
  """Parse vector index parameters to string."""
131
143
  ob_param = self._parse_kwargs()
132
144
  partial_str = ",".join([f"{k}={v}" for k, v in ob_param.items()])
133
- if len(partial_str) > 0:
134
- partial_str += ","
135
- partial_str += f"type={self.index_type}"
145
+ if not self.is_index_type_sparse_vector():
146
+ if len(partial_str) > 0:
147
+ partial_str += ","
148
+ partial_str += f"type={self.index_type}"
136
149
  return partial_str
137
150
 
138
151
  def __iter__(self):
@@ -165,10 +178,10 @@ class IndexParams:
165
178
  """Add `IndexParam` to `IndexParams`
166
179
 
167
180
  Args:
168
- :param field_name (string) : vector index built on which field
169
- :param index_type (VecIndexType) :
170
- vector index algorithms (Only HNSW supported)
171
- :param index_name (string) : vector index name
181
+ field_name (string): vector index built on which field
182
+ index_type (VecIndexType): vector index algorithms (Only HNSW supported)
183
+ index_name (string): vector index name
184
+ **kwargs: additional parameters for different index types
172
185
  """
173
186
  index_param = IndexParam(index_name, field_name, index_type, **kwargs)
174
187
  pair_key = (field_name, index_name)
@@ -68,22 +68,19 @@ class MilvusLikeClient(Client):
68
68
  `metric_type`, `auto_id` will be ignored.
69
69
 
70
70
  Args:
71
- :param collection_name (string) : collection name
72
- :param dimension (Optional[int]) : vector data dimension
73
- :param primary_field_name (string) : primary field name
74
- :param id_type (Union[DataType, str]) :
75
- primary field data type(Only VARCHAR and INT type supported)
76
- :param vector_field_name (string) : vector field name
77
- :param metric_type (str) : not used in OceanBase (for default, l2 distance)
78
- :param auto_id (bool) : whether primary field is auto incremented
79
- :param timeout (Optional[float]) : not used in OceanBase
80
- :param schema (Optional[CollectionSchema]) :
81
- customed collection schema, when `schema` is not None
71
+ collection_name (string): collection name
72
+ dimension (Optional[int]): vector data dimension
73
+ primary_field_name (string): primary field name
74
+ id_type (Union[DataType, str]): primary field data type (Only VARCHAR and INT type supported)
75
+ vector_field_name (string): vector field name
76
+ metric_type (str): not used in OceanBase (for default, l2 distance)
77
+ auto_id (bool): whether primary field is auto incremented
78
+ timeout (Optional[float]): not used in OceanBase
79
+ schema (Optional[CollectionSchema]): custom collection schema, when `schema` is not None
82
80
  the above argument will be ignored
83
- :param index_params (Optional[IndexParams]) : customed vector index parameters
84
- :param max_length (int) :
85
- when primary field data type is VARCHAR and `schema` is not None
86
- the max varchar length is `max_length`
81
+ index_params (Optional[IndexParams]): custom vector index parameters
82
+ max_length (int): when primary field data type is VARCHAR and `schema` is not None,
83
+ the max varchar length is `max_length`
87
84
  """
88
85
  if isinstance(id_type, str):
89
86
  if id_type not in ("str", "string", "int", "integer"):
@@ -154,8 +151,11 @@ class MilvusLikeClient(Client):
154
151
  """Get collection row count.
155
152
 
156
153
  Args:
157
- :param collection_name (string) : collection name
158
- :return {'row_count': count}
154
+ collection_name (string): collection name
155
+ timeout (Optional[float]): not used in OceanBase
156
+
157
+ Returns:
158
+ dict: {'row_count': count}
159
159
  """
160
160
  with self.engine.connect() as conn:
161
161
  with conn.begin():
@@ -168,30 +168,34 @@ class MilvusLikeClient(Client):
168
168
  def has_collection(
169
169
  self, collection_name: str, timeout: Optional[float] = None # pylint: disable=unused-argument
170
170
  ) -> bool: # pylint: disable=unused-argument
171
- """check if collection exists.
171
+ """Check if collection exists.
172
172
 
173
173
  Args:
174
- :param collection_name (string) : collection name
175
- :return True if collection exists else False
174
+ collection_name (string): collection name
175
+ timeout (Optional[float]): not used in OceanBase
176
+
177
+ Returns:
178
+ bool: True if collection exists else False
176
179
  """
177
180
  return self.check_table_exists(collection_name)
178
181
 
179
182
  def drop_collection(self, collection_name: str) -> None:
180
- """drop collection if exists.
183
+ """Drop collection if exists.
181
184
 
182
185
  Args:
183
- :param collection_name (string) : collection name
186
+ collection_name (string): collection name
184
187
  """
185
188
  self.drop_table_if_exist(collection_name)
186
189
 
187
190
  def rename_collection(
188
191
  self, old_name: str, new_name: str, timeout: Optional[float] = None # pylint: disable=unused-argument
189
192
  ) -> None:
190
- """rename collection.
193
+ """Rename collection.
191
194
 
192
195
  Args:
193
- :param old_name (string) : old collection name
194
- :param new_name (string) : new collection name
196
+ old_name (string): old collection name
197
+ new_name (string): new collection name
198
+ timeout (Optional[float]): not used in OceanBase
195
199
  """
196
200
  with self.engine.connect() as conn:
197
201
  with conn.begin():
@@ -201,11 +205,13 @@ class MilvusLikeClient(Client):
201
205
  self,
202
206
  collection_name: str,
203
207
  ):
204
- """load table into SQLAlchemy metadata.
208
+ """Load table into SQLAlchemy metadata.
205
209
 
206
210
  Args:
207
- :param collection_name (string) : which collection to load
208
- :return sqlalchemy.Table
211
+ collection_name (string): which collection to load
212
+
213
+ Returns:
214
+ sqlalchemy.Table: table object
209
215
  """
210
216
  try:
211
217
  table = Table(collection_name, self.metadata_obj, autoload_with=self.engine)
@@ -225,12 +231,13 @@ class MilvusLikeClient(Client):
225
231
  timeout: Optional[float] = None,
226
232
  **kwargs,
227
233
  ): # pylint: disable=unused-argument
228
- """create vector index with index params.
234
+ """Create vector index with index params.
229
235
 
230
236
  Args:
231
- :param collection_name (string) : which collection to create vector index
232
- :param index_params (IndexParams) : the vectpr index parameters
233
- :param kwargs : different args for different vector index type
237
+ collection_name (string): which collection to create vector index
238
+ index_params (IndexParams): the vector index parameters
239
+ timeout (Optional[float]): not used in OceanBase
240
+ **kwargs: different args for different vector index type
234
241
  """
235
242
  try:
236
243
  table = Table(collection_name, self.metadata_obj, autoload_with=self.engine)
@@ -261,8 +268,11 @@ class MilvusLikeClient(Client):
261
268
 
262
269
  If the index not exists, SQL ERROR 1091 will raise.
263
270
 
264
- :param collection_name (string) : which collection the index belongs to
265
- :param index_name (string) : which index
271
+ Args:
272
+ collection_name (string): which collection the index belongs to
273
+ index_name (string): which index
274
+ timeout (Optional[float]): not used in OceanBase
275
+ **kwargs: additional arguments
266
276
  """
267
277
  super().drop_index(collection_name, index_name)
268
278
 
@@ -275,10 +285,9 @@ class MilvusLikeClient(Client):
275
285
  """Refresh vector index for performance.
276
286
 
277
287
  Args:
278
- :param collection_name (string) : collection name
279
- :param index_name (string) : vector index name
280
- :param trigger_threshold (int) :
281
- If delta_buffer_table row count is greater than `trigger_threshold`,
288
+ collection_name (string): collection name
289
+ index_name (string): vector index name
290
+ trigger_threshold (int): If delta_buffer_table row count is greater than `trigger_threshold`,
282
291
  refreshing is actually triggered.
283
292
  """
284
293
  super().refresh_index(
@@ -296,9 +305,9 @@ class MilvusLikeClient(Client):
296
305
  """Rebuild vector index for performance.
297
306
 
298
307
  Args:
299
- :param collection_name (string) : collection name
300
- :param index_name (string) : vector index name
301
- :param trigger_threshold (float)
308
+ collection_name (string): collection name
309
+ index_name (string): vector index name
310
+ trigger_threshold (float): threshold value for rebuilding index
302
311
  """
303
312
  super().rebuild_index(
304
313
  table_name=collection_name,
@@ -340,7 +349,7 @@ class MilvusLikeClient(Client):
340
349
  def search(
341
350
  self,
342
351
  collection_name: str,
343
- data: list,
352
+ data: Union[list, dict],
344
353
  anns_field: str,
345
354
  with_dist: bool = False,
346
355
  flter=None,
@@ -351,24 +360,29 @@ class MilvusLikeClient(Client):
351
360
  partition_names: Optional[List[str]] = None,
352
361
  **kwargs, # pylint: disable=unused-argument
353
362
  ) -> List[dict]:
354
- """perform ann search.
363
+ """Perform ann search.
355
364
  Note: OceanBase does not support batch search now. `data` & the return value is not a batch.
356
365
 
357
366
  Args:
358
- :param collection_name (string) : collection name
359
- :param data (list) : the vector data to search
360
- :param anns_field (string) : which vector field to search
361
- :param with_dist (bool) : return result with distance
362
- :param flter : do ann search with filter
363
- :param limit (int) : top K
364
- :param output_fields (Optional[List[str]]) : output fields
365
- :param search_params (Optional[dict]) :
366
- Only `metric_type` with value `l2`/`neg_ip` supported
367
- :param timeout : not used in OceanBase
368
- :param partition_names (List[str]) : limit the query to certain partitions
369
- :return : A list of records, each record is a dict
370
- indicates a mapping from column_name to column value.
367
+ collection_name (string): collection name
368
+ data (list): the vector/sparse_vector data to search
369
+ anns_field (string): which vector field to search
370
+ with_dist (bool): return result with distance
371
+ flter: do ann search with filter (note: parameter name is intentionally 'flter' to distinguish it from the built-in function)
372
+ limit (int): top K
373
+ output_fields (Optional[List[str]]): output fields
374
+ search_params (Optional[dict]): Only `metric_type` with value `l2`/`neg_ip` supported
375
+ timeout (Optional[float]): not used in OceanBase
376
+ partition_names (Optional[List[str]]): limit the query to certain partitions
377
+ **kwargs: additional arguments
378
+
379
+ Returns:
380
+ List[dict]: A list of records, each record is a dict indicating a mapping from
381
+ column_name to column value.
371
382
  """
383
+ if not (isinstance(data, list) or isinstance(data, dict)):
384
+ raise ValueError("'data' type must be in 'list'/'dict'")
385
+
372
386
  lower_metric_type_str = "l2"
373
387
  if search_params is not None:
374
388
  if "metric_type" in search_params:
@@ -379,8 +393,8 @@ class MilvusLikeClient(Client):
379
393
  )
380
394
  lower_metric_type_str = search_params["metric_type"].lower()
381
395
  if lower_metric_type_str not in (
382
- "l2", "neg_ip"
383
- ): # For OceanBase, only support l2/ip distance in ann_search
396
+ "l2", "neg_ip", "cosine", "ip"
397
+ ):
384
398
  raise VectorMetricTypeException(
385
399
  code=ErrorCode.INVALID_ARGUMENT,
386
400
  message=ExceptionsMessage.MetricTypeValueInvalid,
@@ -401,15 +415,21 @@ class MilvusLikeClient(Client):
401
415
  columns = [table.c[column.name] for column in table.columns]
402
416
 
403
417
  if with_dist:
404
- columns.append(distance_func(table.c[anns_field],
405
- "[" + ",".join([str(np.float32(v)) for v in data]) + "]"))
418
+ if isinstance(data, list):
419
+ columns.append(distance_func(table.c[anns_field],
420
+ "[" + ",".join([str(np.float32(v)) for v in data]) + "]"))
421
+ else:
422
+ columns.append(distance_func(table.c[anns_field], f"{data}"))
406
423
  stmt = select(*columns)
407
424
 
408
425
  if flter is not None:
409
426
  stmt = stmt.where(*flter)
410
-
411
- stmt = stmt.order_by(distance_func(table.c[anns_field],
412
- "[" + ",".join([str(np.float32(v)) for v in data]) + "]"))
427
+
428
+ if isinstance(data, list):
429
+ stmt = stmt.order_by(distance_func(table.c[anns_field],
430
+ "[" + ",".join([str(np.float32(v)) for v in data]) + "]"))
431
+ else:
432
+ stmt = stmt.order_by(distance_func(table.c[anns_field], f"{data}"))
413
433
  stmt_str = (
414
434
  str(stmt.compile(
415
435
  dialect=self.engine.dialect,
@@ -452,16 +472,19 @@ class MilvusLikeClient(Client):
452
472
  partition_names: Optional[List[str]] = None,
453
473
  **kwargs, # pylint: disable=unused-argument
454
474
  ) -> List[dict]:
455
- """query records.
475
+ """Query records.
456
476
 
457
477
  Args:
458
- :param collection_name (string) : collection name
459
- :param flter : do ann search with filter
460
- :param output_fields (Optional[List[str]]) : output fields
461
- :param timeout : not used in OceanBase
462
- :param partition_names (List[str]) : limit the query to certain partitions
463
- :return : A list of records, each record is a dict
464
- indicates a mapping from column_name to column value
478
+ collection_name (string): collection name
479
+ flter: do ann search with filter (note: parameter name is intentionally 'flter' to distinguish it from the built-in function)
480
+ output_fields (Optional[List[str]]): output fields
481
+ timeout (Optional[float]): not used in OceanBase
482
+ partition_names (Optional[List[str]]): limit the query to certain partitions
483
+ **kwargs: additional arguments
484
+
485
+ Returns:
486
+ List[dict]: A list of records, each record is a dict indicating a mapping from
487
+ column_name to column value.
465
488
  """
466
489
  try:
467
490
  table = Table(collection_name, self.metadata_obj, autoload_with=self.engine)
@@ -509,22 +532,25 @@ class MilvusLikeClient(Client):
509
532
  def get(
510
533
  self,
511
534
  collection_name: str,
512
- ids: Union[list, str, int],
535
+ ids: Union[list, str, int] = None,
513
536
  output_fields: Optional[List[str]] = None,
514
537
  timeout: Optional[float] = None, # pylint: disable=unused-argument
515
538
  partition_names: Optional[List[str]] = None,
516
539
  **kwargs, # pylint: disable=unused-argument
517
540
  ) -> List[dict]:
518
- """get records with specified primary field `ids`.
541
+ """Get records with specified primary field `ids`.
519
542
 
520
543
  Args:
521
- :param collection_name (string) : collection name
522
- :param ids : specified primary field values
523
- :param output_fields (Optional[List[str]]) : output fields
524
- :param timeout : not used in OceanBase
525
- :param partition_names (List[str]) : limit the query to certain partitions
526
- :return : A list of records, each record is a dict
527
- indicates a mapping from column_name to column value
544
+ collection_name (string): collection name
545
+ ids (Union[list, str, int]): specified primary field values
546
+ output_fields (Optional[List[str]]): output fields
547
+ timeout (Optional[float]): not used in OceanBase
548
+ partition_names (Optional[List[str]]): limit the query to certain partitions
549
+ **kwargs: additional arguments
550
+
551
+ Returns:
552
+ List[dict]: A list of records, each record is a dict indicating a mapping from
553
+ column_name to column value.
528
554
  """
529
555
  try:
530
556
  table = Table(collection_name, self.metadata_obj, autoload_with=self.engine)
@@ -593,10 +619,15 @@ class MilvusLikeClient(Client):
593
619
  """Delete data in collection.
594
620
 
595
621
  Args:
596
- :param collection_name (string) : collection name
597
- :param ids (Optional[Union[list, str, int]]) : a list of primary keys value
598
- :param flter : delete with filter
599
- :param partition_name (Optional[str]) : limit the query to certain partition
622
+ collection_name (string): collection name
623
+ ids (Optional[Union[list, str, int]]): a list of primary keys value
624
+ timeout (Optional[float]): not used in OceanBase
625
+ flter: delete with filter (note: parameter name is intentionally 'flter' to distinguish it from the built-in function)
626
+ partition_name (Optional[str]): limit the query to certain partition
627
+ **kwargs: additional arguments
628
+
629
+ Returns:
630
+ dict: deletion result
600
631
  """
601
632
  try:
602
633
  table = Table(collection_name, self.metadata_obj, autoload_with=self.engine)
@@ -650,9 +681,10 @@ class MilvusLikeClient(Client):
650
681
  """Insert data into collection.
651
682
 
652
683
  Args:
653
- :param collection_name (string) : collection name
654
- :param data (Union[Dict, List[Dict]]) : data that will be inserted
655
- :param partition_names (Optional[str]) : limit the query to certain partition
684
+ collection_name (string): collection name
685
+ data (Union[Dict, List[Dict]]): data that will be inserted
686
+ timeout (Optional[float]): not used in OceanBase
687
+ partition_name (Optional[str]): limit the query to certain partition
656
688
  """
657
689
  # different from milvus: OceanBase in mysql mode do not support returning.
658
690
  try:
@@ -675,9 +707,13 @@ class MilvusLikeClient(Client):
675
707
  """Update data in table. If primary key is duplicated, replace it.
676
708
 
677
709
  Args:
678
- :param collection_name (string) : collection name
679
- :param data (Union[Dict, List[Dict]]) : data that will be upserted
680
- :param partition_name (Optional[str]) : limit the query to certain partition
710
+ collection_name (string): collection name
711
+ data (Union[Dict, List[Dict]]): data that will be upserted
712
+ timeout (Optional[float]): not used in OceanBase
713
+ partition_name (Optional[str]): limit the query to certain partition
714
+
715
+ Returns:
716
+ List[Union[str, int]]: list of primary keys
681
717
  """
682
718
  try:
683
719
  super().upsert(