pyobvector 0.2.19__tar.gz → 0.2.20__tar.gz

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.
Files changed (40) hide show
  1. {pyobvector-0.2.19 → pyobvector-0.2.20}/PKG-INFO +6 -5
  2. {pyobvector-0.2.19 → pyobvector-0.2.20}/README.md +5 -4
  3. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/hybrid_search.py +3 -7
  4. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/index_param.py +5 -2
  5. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/ob_client.py +20 -0
  6. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/ob_vec_client.py +5 -1
  7. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/ob_vec_json_table_client.py +3 -2
  8. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyproject.toml +1 -1
  9. {pyobvector-0.2.19 → pyobvector-0.2.20}/LICENSE +0 -0
  10. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/__init__.py +0 -0
  11. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/__init__.py +0 -0
  12. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/collection_schema.py +0 -0
  13. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/enum.py +0 -0
  14. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/exceptions.py +0 -0
  15. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/fts_index_param.py +0 -0
  16. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/milvus_like_client.py +0 -0
  17. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/partitions.py +0 -0
  18. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/client/schema_type.py +0 -0
  19. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/json_table/__init__.py +0 -0
  20. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/json_table/json_value_returning_func.py +0 -0
  21. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/json_table/oceanbase_dialect.py +0 -0
  22. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/json_table/virtual_data_type.py +0 -0
  23. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/__init__.py +0 -0
  24. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/array.py +0 -0
  25. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/dialect.py +0 -0
  26. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/full_text_index.py +0 -0
  27. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/geo_srid_point.py +0 -0
  28. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/gis_func.py +0 -0
  29. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/match_against_func.py +0 -0
  30. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/ob_table.py +0 -0
  31. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/reflection.py +0 -0
  32. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/replace_stmt.py +0 -0
  33. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/sparse_vector.py +0 -0
  34. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/vec_dist_func.py +0 -0
  35. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/vector.py +0 -0
  36. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/schema/vector_index.py +0 -0
  37. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/util/__init__.py +0 -0
  38. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/util/ob_version.py +0 -0
  39. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/util/sparse_vector.py +0 -0
  40. {pyobvector-0.2.19 → pyobvector-0.2.20}/pyobvector/util/vector.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyobvector
3
- Version: 0.2.19
3
+ Version: 0.2.20
4
4
  Summary: A python SDK for OceanBase Vector Store, based on SQLAlchemy, compatible with Milvus API.
5
5
  License-File: LICENSE
6
6
  Author: shanhaikang.shk
@@ -38,7 +38,7 @@ poetry install
38
38
  - install with pip:
39
39
 
40
40
  ```shell
41
- pip install pyobvector==0.2.19
41
+ pip install pyobvector==0.2.20
42
42
  ```
43
43
 
44
44
  ## Build Doc
@@ -234,17 +234,17 @@ res = self.client.ann_search(
234
234
  The `ann_search` method supports flexible output column selection through the `output_columns` parameter:
235
235
 
236
236
  - **`output_columns`** (recommended): Accepts SQLAlchemy Column objects, expressions, or a mix of both
237
-
237
+
238
238
  - Column objects: `table.c.id`, `table.c.name`
239
239
  - Expressions: `(table.c.age + 10).label('age_plus_10')`
240
240
  - JSON queries: `text("JSON_EXTRACT(meta, '$.key') as extracted_key")`
241
241
  - String functions: `func.concat(table.c.name, ' (', table.c.age, ')').label('name_age')`
242
242
  - **`output_column_names`** (legacy): Accepts list of column name strings
243
-
243
+
244
244
  - Example: `['id', 'name', 'meta']`
245
245
  - **Parameter Priority**: `output_columns` takes precedence over `output_column_names` when both are provided
246
246
  - **`distance_threshold`** (optional): Filter results by distance threshold
247
-
247
+
248
248
  - Type: `Optional[float]`
249
249
  - Only returns results where `distance <= threshold`
250
250
  - Example: `distance_threshold=0.5` returns only results with distance <= 0.5
@@ -454,3 +454,4 @@ sql = client.get_sql(index=test_table_name, body=body)
454
454
  print(sql) # prints the SQL query
455
455
  ```
456
456
 
457
+
@@ -15,7 +15,7 @@ poetry install
15
15
  - install with pip:
16
16
 
17
17
  ```shell
18
- pip install pyobvector==0.2.19
18
+ pip install pyobvector==0.2.20
19
19
  ```
20
20
 
21
21
  ## Build Doc
@@ -211,17 +211,17 @@ res = self.client.ann_search(
211
211
  The `ann_search` method supports flexible output column selection through the `output_columns` parameter:
212
212
 
213
213
  - **`output_columns`** (recommended): Accepts SQLAlchemy Column objects, expressions, or a mix of both
214
-
214
+
215
215
  - Column objects: `table.c.id`, `table.c.name`
216
216
  - Expressions: `(table.c.age + 10).label('age_plus_10')`
217
217
  - JSON queries: `text("JSON_EXTRACT(meta, '$.key') as extracted_key")`
218
218
  - String functions: `func.concat(table.c.name, ' (', table.c.age, ')').label('name_age')`
219
219
  - **`output_column_names`** (legacy): Accepts list of column name strings
220
-
220
+
221
221
  - Example: `['id', 'name', 'meta']`
222
222
  - **Parameter Priority**: `output_columns` takes precedence over `output_column_names` when both are provided
223
223
  - **`distance_threshold`** (optional): Filter results by distance threshold
224
-
224
+
225
225
  - Type: `Optional[float]`
226
226
  - Only returns results where `distance <= threshold`
227
227
  - Example: `distance_threshold=0.5` returns only results with distance <= 0.5
@@ -430,3 +430,4 @@ You can also get the actual SQL that will be executed:
430
430
  sql = client.get_sql(index=test_table_name, body=body)
431
431
  print(sql) # prints the SQL query
432
432
  ```
433
+
@@ -30,13 +30,9 @@ class HybridSearch(Client):
30
30
 
31
31
  if self.ob_version < min_required_version:
32
32
  # For versions < 4.4.1.0, check if it's SeekDB
33
- with self.engine.connect() as conn:
34
- with conn.begin():
35
- res = conn.execute(text("SELECT version()"))
36
- version_str = [r[0] for r in res][0]
37
- if "SeekDB" in version_str:
38
- logger.info(f"SeekDB detected in version string: {version_str}, allowing hybrid search")
39
- return
33
+ if self._is_seekdb():
34
+ logger.info("SeekDB detected, allowing hybrid search")
35
+ return
40
36
  raise ClusterVersionException(
41
37
  code=ErrorCode.NOT_SUPPORTED,
42
38
  message=ExceptionsMessage.ClusterVersionIsLow % ("Hybrid Search", "4.4.1.0"),
@@ -134,8 +134,11 @@ class IndexParam:
134
134
  if 'efSearch' in params:
135
135
  ob_params['ef_search'] = params['efSearch']
136
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.")
137
+ if self.is_index_type_sparse_vector():
138
+ if ob_params['distance'] != 'inner_product':
139
+ raise ValueError("Metric type should be 'inner_product' for sparse vector index.")
140
+ if 'sparse_index_type' in self.kwargs:
141
+ ob_params['type'] = self.kwargs['sparse_index_type']
139
142
  return ob_params
140
143
 
141
144
  def param_str(self):
@@ -93,6 +93,26 @@ class ObClient:
93
93
  self.metadata_obj.clear()
94
94
  self.metadata_obj.reflect(bind=self.engine, extend_existing=True)
95
95
 
96
+ def _is_seekdb(self) -> bool:
97
+ """Check if the database is SeekDB by querying version.
98
+
99
+ Returns:
100
+ bool: True if database is SeekDB, False otherwise
101
+ """
102
+ is_seekdb = False
103
+ try:
104
+ if hasattr(self, '_is_seekdb_cached'):
105
+ return self._is_seekdb_cached
106
+ with self.engine.connect() as conn:
107
+ result = conn.execute(text("SELECT VERSION()"))
108
+ version_str = [r[0] for r in result][0]
109
+ is_seekdb = "SeekDB" in version_str
110
+ self._is_seekdb_cached = is_seekdb
111
+ logger.debug(f"Version query result: {version_str}, is_seekdb: {is_seekdb}")
112
+ except Exception as e:
113
+ logger.warning(f"Failed to query version: {e}")
114
+ return is_seekdb
115
+
96
116
  def _insert_partition_hint_for_query_sql(self, sql: str, partition_hint: str):
97
117
  from_index = sql.find("FROM")
98
118
  assert from_index != -1
@@ -99,7 +99,11 @@ class ObVecClient(ObClient):
99
99
  create_table_sql = str(CreateTable(table).compile(self.engine))
100
100
  new_sql = create_table_sql[:create_table_sql.rfind(')')]
101
101
  for sparse_vidx in sparse_vidxs:
102
- new_sql += f",\n\tVECTOR INDEX {sparse_vidx.index_name}({sparse_vidx.field_name}) with (distance=inner_product)"
102
+ sparse_params = sparse_vidx._parse_kwargs()
103
+ if 'type' in sparse_params:
104
+ new_sql += f",\n\tVECTOR INDEX {sparse_vidx.index_name}({sparse_vidx.field_name}) with (type={sparse_params['type']}, distance=inner_product)"
105
+ else:
106
+ new_sql += f",\n\tVECTOR INDEX {sparse_vidx.index_name}({sparse_vidx.field_name}) with (distance=inner_product)"
103
107
  new_sql += "\n)"
104
108
  conn.execute(text(new_sql))
105
109
  else:
@@ -817,11 +817,12 @@ class ObVecJsonTableClient(ObVecClient):
817
817
  ):
818
818
  real_user_id = opt_user_id or self.user_id
819
819
 
820
- table_name = ast.args['from'].this.this.this
820
+ from_key = 'from_' if 'from_' in ast.args else 'from'
821
+ table_name = ast.args[from_key].this.this.this
821
822
  if not self._check_table_exists(table_name):
822
823
  raise ValueError(f"Table {table_name} does not exists")
823
824
 
824
- ast.args['from'].args['this'].args['this'] = to_identifier(name=JSON_TABLE_DATA_TABLE_NAME, quoted=False)
825
+ ast.args[from_key].args['this'].args['this'] = to_identifier(name=JSON_TABLE_DATA_TABLE_NAME, quoted=False)
825
826
 
826
827
  col_meta = self.jmetadata.meta_cache[table_name]
827
828
  json_table_meta_str = []
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pyobvector"
3
- version = "0.2.19"
3
+ version = "0.2.20"
4
4
  description = "A python SDK for OceanBase Vector Store, based on SQLAlchemy, compatible with Milvus API."
5
5
  authors = ["shanhaikang.shk <shanhaikang.shk@oceanbase.com>"]
6
6
  readme = "README.md"
File without changes