pyobvector 0.2.19__py3-none-any.whl → 0.2.20__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/client/hybrid_search.py +3 -7
- pyobvector/client/index_param.py +5 -2
- pyobvector/client/ob_client.py +20 -0
- pyobvector/client/ob_vec_client.py +5 -1
- pyobvector/client/ob_vec_json_table_client.py +3 -2
- {pyobvector-0.2.19.dist-info → pyobvector-0.2.20.dist-info}/METADATA +6 -5
- {pyobvector-0.2.19.dist-info → pyobvector-0.2.20.dist-info}/RECORD +9 -9
- {pyobvector-0.2.19.dist-info → pyobvector-0.2.20.dist-info}/WHEEL +0 -0
- {pyobvector-0.2.19.dist-info → pyobvector-0.2.20.dist-info}/licenses/LICENSE +0 -0
|
@@ -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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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"),
|
pyobvector/client/index_param.py
CHANGED
|
@@ -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()
|
|
138
|
-
|
|
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):
|
pyobvector/client/ob_client.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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[
|
|
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
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyobvector
|
|
3
|
-
Version: 0.2.
|
|
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.
|
|
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
|
+
|
|
@@ -4,12 +4,12 @@ pyobvector/client/collection_schema.py,sha256=a7JQk83ZxMsvMDGt5CC_4lz2-skONqKgk-
|
|
|
4
4
|
pyobvector/client/enum.py,sha256=3lPjSltITSE694-qOAP4yoX6fzCjKD4WAewmIxFs49o,139
|
|
5
5
|
pyobvector/client/exceptions.py,sha256=CjoquSCc0H705MtvhpQW_F7_KaviYrKAHkndpF8sJx4,3777
|
|
6
6
|
pyobvector/client/fts_index_param.py,sha256=UvU82p9_x444WAQMqhIUPHbqVHV5B3cFazje1Gw-slo,1105
|
|
7
|
-
pyobvector/client/hybrid_search.py,sha256=
|
|
8
|
-
pyobvector/client/index_param.py,sha256=
|
|
7
|
+
pyobvector/client/hybrid_search.py,sha256=wXHu4iOBRyVuMByiH3XyB4kKYqvzmVBSSiod5lj7cVY,2571
|
|
8
|
+
pyobvector/client/index_param.py,sha256=Tbu_-qg4SIXIzn1qpTg8Zl1L_RCXCUAEsZPKsA0LsNY,7062
|
|
9
9
|
pyobvector/client/milvus_like_client.py,sha256=jHxB-ZmIGZiIDxEpurSlAKffiCF_KFNZP-14_vq1RQM,27887
|
|
10
|
-
pyobvector/client/ob_client.py,sha256=
|
|
11
|
-
pyobvector/client/ob_vec_client.py,sha256=
|
|
12
|
-
pyobvector/client/ob_vec_json_table_client.py,sha256=
|
|
10
|
+
pyobvector/client/ob_client.py,sha256=xfLbkTJrrmKArUJSLyfUcI_CsMk26KLB2DVFb6Y1-OQ,16987
|
|
11
|
+
pyobvector/client/ob_vec_client.py,sha256=jtAs2pB987zYfwyFgaipv8TgYsDfiFqeBDU7PKiUFbs,20241
|
|
12
|
+
pyobvector/client/ob_vec_json_table_client.py,sha256=YwAKG1pGAYgbhaYB6wDCdxB6L4uJcXCHCwLTy99ZirY,39312
|
|
13
13
|
pyobvector/client/partitions.py,sha256=Bxwr5yVNlXwZc7SXBC03NeqL9giy4Fe6S2qZdHD8xGw,15621
|
|
14
14
|
pyobvector/client/schema_type.py,sha256=gH2YiBsgkryo-R0GB_NYuRXMvzvrSjOamZTy6pwn2n0,1673
|
|
15
15
|
pyobvector/json_table/__init__.py,sha256=X5MmK3f10oyJleUUFZJFeunMEfzmf6P1f_7094b-FZc,554
|
|
@@ -34,7 +34,7 @@ pyobvector/util/__init__.py,sha256=-opvZ4Ya0ByTAhls06547-zW3vkdYRkUH6W5OCKUHD4,3
|
|
|
34
34
|
pyobvector/util/ob_version.py,sha256=cWkQWoJkIxG6OEF9-gBwJK8LUorltHuKSVAb_NFkpdE,1542
|
|
35
35
|
pyobvector/util/sparse_vector.py,sha256=1IG0CRYfC2z39nGwuG43TImQkWiuPAXOlOnYqJ1hA-o,1275
|
|
36
36
|
pyobvector/util/vector.py,sha256=58glSQqjOSTrGyNhUEIrs9r4F9oaYO_SdPNhMfbSnWs,2392
|
|
37
|
-
pyobvector-0.2.
|
|
38
|
-
pyobvector-0.2.
|
|
39
|
-
pyobvector-0.2.
|
|
40
|
-
pyobvector-0.2.
|
|
37
|
+
pyobvector-0.2.20.dist-info/METADATA,sha256=f8EONRGcUmb7zDKtSU6R-axq16x4SKLh4okd9vwT5Cg,14317
|
|
38
|
+
pyobvector-0.2.20.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
39
|
+
pyobvector-0.2.20.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
|
40
|
+
pyobvector-0.2.20.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|