pyobvector 0.2.7__tar.gz → 0.2.8__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.
- {pyobvector-0.2.7 → pyobvector-0.2.8}/PKG-INFO +2 -2
- {pyobvector-0.2.7 → pyobvector-0.2.8}/README.md +1 -1
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/client/ob_vec_json_table_client.py +49 -25
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyproject.toml +1 -1
- {pyobvector-0.2.7 → pyobvector-0.2.8}/LICENSE +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/__init__.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/client/__init__.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/client/collection_schema.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/client/enum.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/client/exceptions.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/client/fts_index_param.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/client/index_param.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/client/milvus_like_client.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/client/ob_vec_client.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/client/partitions.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/client/schema_type.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/json_table/__init__.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/json_table/json_value_returning_func.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/json_table/oceanbase_dialect.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/json_table/virtual_data_type.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/__init__.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/dialect.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/full_text_index.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/geo_srid_point.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/gis_func.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/match_against_func.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/ob_table.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/reflection.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/replace_stmt.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/vec_dist_func.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/vector.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/schema/vector_index.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/util/__init__.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/util/ob_version.py +0 -0
- {pyobvector-0.2.7 → pyobvector-0.2.8}/pyobvector/util/vector.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pyobvector
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
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.
|
|
39
|
+
pip install pyobvector==0.2.8
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
## Build Doc
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
3
|
import re
|
|
4
|
-
from typing import Dict, List, Optional, Any
|
|
4
|
+
from typing import Dict, List, Optional, Any, Union
|
|
5
5
|
|
|
6
6
|
from sqlalchemy import Column, Integer, String, JSON, Engine, select, text, func, CursorResult
|
|
7
7
|
from sqlalchemy.dialects.mysql import TINYINT
|
|
@@ -163,7 +163,12 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
163
163
|
def refresh_metadata(self) -> None:
|
|
164
164
|
self.jmetadata.reflect(self.engine)
|
|
165
165
|
|
|
166
|
-
def perform_json_table_sql(
|
|
166
|
+
def perform_json_table_sql(
|
|
167
|
+
self,
|
|
168
|
+
sql: str,
|
|
169
|
+
select_with_data_id: bool = False,
|
|
170
|
+
opt_user_id: Optional[str] = None,
|
|
171
|
+
) -> Union[Optional[CursorResult], int]:
|
|
167
172
|
"""Perform common SQL that operates on JSON Table."""
|
|
168
173
|
ast = parse_one(sql, dialect="oceanbase")
|
|
169
174
|
if isinstance(ast, exp.Create):
|
|
@@ -176,16 +181,16 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
176
181
|
self._handle_alter_json_table(ast)
|
|
177
182
|
return None
|
|
178
183
|
elif isinstance(ast, exp.Insert):
|
|
179
|
-
self._handle_jtable_dml_insert(ast)
|
|
180
|
-
return
|
|
184
|
+
row_count = self._handle_jtable_dml_insert(ast, opt_user_id)
|
|
185
|
+
return row_count
|
|
181
186
|
elif isinstance(ast, exp.Update):
|
|
182
|
-
self._handle_jtable_dml_update(ast)
|
|
183
|
-
return
|
|
187
|
+
row_count = self._handle_jtable_dml_update(ast, opt_user_id)
|
|
188
|
+
return row_count
|
|
184
189
|
elif isinstance(ast, exp.Delete):
|
|
185
|
-
self._handle_jtable_dml_delete(ast)
|
|
186
|
-
return
|
|
190
|
+
row_count = self._handle_jtable_dml_delete(ast, opt_user_id)
|
|
191
|
+
return row_count
|
|
187
192
|
elif isinstance(ast, exp.Select):
|
|
188
|
-
return self._handle_jtable_dml_select(ast, select_with_data_id)
|
|
193
|
+
return self._handle_jtable_dml_select(ast, select_with_data_id, opt_user_id)
|
|
189
194
|
else:
|
|
190
195
|
raise ValueError(f"{type(ast)} not supported")
|
|
191
196
|
|
|
@@ -642,8 +647,10 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
642
647
|
finally:
|
|
643
648
|
session.close()
|
|
644
649
|
|
|
645
|
-
def _handle_jtable_dml_insert(self, ast: Expression):
|
|
646
|
-
|
|
650
|
+
def _handle_jtable_dml_insert(self, ast: Expression, opt_user_id: Optional[str] = None):
|
|
651
|
+
real_user_id = opt_user_id or self.user_id
|
|
652
|
+
|
|
653
|
+
if real_user_id is None:
|
|
647
654
|
raise ValueError(f"inserting is disabled when user_id is None")
|
|
648
655
|
|
|
649
656
|
if isinstance(ast.this, exp.Schema):
|
|
@@ -673,6 +680,7 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
673
680
|
raise ValueError(f"Invalid ast type {ast.this}")
|
|
674
681
|
|
|
675
682
|
session = self.session()
|
|
683
|
+
n_new_records = 0
|
|
676
684
|
for tuple in ast.expression.expressions:
|
|
677
685
|
expr_list = tuple.expressions
|
|
678
686
|
if len(expr_list) != len(insert_col_names):
|
|
@@ -691,21 +699,26 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
691
699
|
logger.debug(f"================= [INSERT] =============== {kv}")
|
|
692
700
|
|
|
693
701
|
session.add(ObVecJsonTableClient.JsonTableDataTBL(
|
|
694
|
-
user_id =
|
|
702
|
+
user_id = real_user_id,
|
|
695
703
|
admin_id = self.admin_id,
|
|
696
704
|
jtable_name = table_name,
|
|
697
705
|
jdata = kv,
|
|
698
706
|
))
|
|
707
|
+
n_new_records += 1
|
|
699
708
|
|
|
700
709
|
try:
|
|
701
710
|
session.commit()
|
|
702
711
|
except Exception as e:
|
|
703
712
|
session.rollback()
|
|
704
713
|
logger.error(f"Error occurred: {e}")
|
|
714
|
+
n_new_records = 0
|
|
705
715
|
finally:
|
|
706
716
|
session.close()
|
|
717
|
+
return n_new_records
|
|
718
|
+
|
|
719
|
+
def _handle_jtable_dml_update(self, ast: Expression, opt_user_id: Optional[str] = None):
|
|
720
|
+
real_user_id = opt_user_id or self.user_id
|
|
707
721
|
|
|
708
|
-
def _handle_jtable_dml_update(self, ast: Expression):
|
|
709
722
|
table_name = ast.this.this.this
|
|
710
723
|
if not self._check_table_exists(table_name):
|
|
711
724
|
raise ValueError(f"Table {table_name} does not exists")
|
|
@@ -733,7 +746,7 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
733
746
|
path_settings.append(f"'$.{col_name}', {str(col_expr)}")
|
|
734
747
|
|
|
735
748
|
where_clause = None
|
|
736
|
-
if 'where' in ast.args.keys():
|
|
749
|
+
if 'where' in ast.args.keys() and ast.args['where']:
|
|
737
750
|
for column in ast.args['where'].find_all(exp.Column):
|
|
738
751
|
where_col_name = column.this.this
|
|
739
752
|
if not self._check_col_exists(table_name, where_col_name):
|
|
@@ -741,8 +754,8 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
741
754
|
column.parent.args['this'] = parse_one(
|
|
742
755
|
f"JSON_VALUE({JSON_TABLE_DATA_TABLE_NAME}.jdata, '$.{where_col_name}')"
|
|
743
756
|
)
|
|
744
|
-
if
|
|
745
|
-
where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{
|
|
757
|
+
if real_user_id:
|
|
758
|
+
where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{real_user_id}' AND {JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}' AND ({str(ast.args['where'].this)})"
|
|
746
759
|
else:
|
|
747
760
|
where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}' AND ({str(ast.args['where'].this)})"
|
|
748
761
|
|
|
@@ -752,15 +765,18 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
752
765
|
update_sql = f"UPDATE {JSON_TABLE_DATA_TABLE_NAME} SET jdata = JSON_REPLACE({JSON_TABLE_DATA_TABLE_NAME}.jdata, {', '.join(path_settings)})"
|
|
753
766
|
|
|
754
767
|
logger.debug(f"===================== do update: {update_sql}")
|
|
755
|
-
self.perform_raw_text_sql(update_sql)
|
|
768
|
+
res = self.perform_raw_text_sql(update_sql)
|
|
769
|
+
return res.rowcount
|
|
770
|
+
|
|
771
|
+
def _handle_jtable_dml_delete(self, ast: Expression, opt_user_id: Optional[str] = None):
|
|
772
|
+
real_user_id = opt_user_id or self.user_id
|
|
756
773
|
|
|
757
|
-
def _handle_jtable_dml_delete(self, ast: Expression):
|
|
758
774
|
table_name = ast.this.this.this
|
|
759
775
|
if not self._check_table_exists(table_name):
|
|
760
776
|
raise ValueError(f"Table {table_name} does not exists")
|
|
761
777
|
|
|
762
778
|
where_clause = None
|
|
763
|
-
if 'where' in ast.args.keys():
|
|
779
|
+
if 'where' in ast.args.keys() and ast.args['where']:
|
|
764
780
|
for column in ast.args['where'].find_all(exp.Column):
|
|
765
781
|
where_col_name = column.this.this
|
|
766
782
|
if not self._check_col_exists(table_name, where_col_name):
|
|
@@ -768,8 +784,8 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
768
784
|
column.parent.args['this'] = parse_one(
|
|
769
785
|
f"JSON_VALUE({JSON_TABLE_DATA_TABLE_NAME}.jdata, '$.{where_col_name}')"
|
|
770
786
|
)
|
|
771
|
-
if
|
|
772
|
-
where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{
|
|
787
|
+
if real_user_id:
|
|
788
|
+
where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{real_user_id}' AND {JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}' AND ({str(ast.args['where'].this)})"
|
|
773
789
|
else:
|
|
774
790
|
where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}' AND ({str(ast.args['where'].this)})"
|
|
775
791
|
|
|
@@ -779,7 +795,8 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
779
795
|
delete_sql = f"DELETE FROM {JSON_TABLE_DATA_TABLE_NAME}"
|
|
780
796
|
|
|
781
797
|
logger.debug(f"===================== do delete: {delete_sql}")
|
|
782
|
-
self.perform_raw_text_sql(delete_sql)
|
|
798
|
+
res = self.perform_raw_text_sql(delete_sql)
|
|
799
|
+
return res.rowcount
|
|
783
800
|
|
|
784
801
|
def _get_full_datatype(self, jdata_type: str):
|
|
785
802
|
if jdata_type.upper() == "VARCHAR":
|
|
@@ -788,7 +805,14 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
788
805
|
return "DECIMAL(10, 0)"
|
|
789
806
|
return jdata_type
|
|
790
807
|
|
|
791
|
-
def _handle_jtable_dml_select(
|
|
808
|
+
def _handle_jtable_dml_select(
|
|
809
|
+
self,
|
|
810
|
+
ast: Expression,
|
|
811
|
+
select_with_data_id: bool = False,
|
|
812
|
+
opt_user_id: Optional[str] = None
|
|
813
|
+
):
|
|
814
|
+
real_user_id = opt_user_id or self.user_id
|
|
815
|
+
|
|
792
816
|
table_name = ast.args['from'].this.this.this
|
|
793
817
|
if not self._check_table_exists(table_name):
|
|
794
818
|
raise ValueError(f"Table {table_name} does not exists")
|
|
@@ -856,8 +880,8 @@ class ObVecJsonTableClient(ObVecClient):
|
|
|
856
880
|
else:
|
|
857
881
|
ast.args['joins'] = [join_node]
|
|
858
882
|
|
|
859
|
-
if
|
|
860
|
-
extra_filter_str = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{
|
|
883
|
+
if real_user_id:
|
|
884
|
+
extra_filter_str = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{real_user_id}' AND {JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}'"
|
|
861
885
|
else:
|
|
862
886
|
extra_filter_str = f"{JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}'"
|
|
863
887
|
if 'where' in ast.args.keys():
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "pyobvector"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.8"
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|