pyobvector 0.2.7__py3-none-any.whl → 0.2.8__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.
@@ -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(self, sql: str, select_with_data_id: bool = False) -> Optional[CursorResult]:
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 None
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 None
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 None
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
- if self.user_id is None:
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 = self.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 self.user_id:
745
- where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{self.user_id}' AND {JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}' AND ({str(ast.args['where'].this)})"
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 self.user_id:
772
- where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{self.user_id}' AND {JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}' AND ({str(ast.args['where'].this)})"
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(self, ast: Expression, select_with_data_id: bool = False):
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 self.user_id:
860
- extra_filter_str = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{self.user_id}' AND {JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}'"
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
  Metadata-Version: 2.3
2
2
  Name: pyobvector
3
- Version: 0.2.7
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.7
39
+ pip install pyobvector==0.2.8
40
40
  ```
41
41
 
42
42
  ## Build Doc
@@ -7,7 +7,7 @@ pyobvector/client/fts_index_param.py,sha256=hMCjA3Aecnt0uQQT6UQGTIIqdPk1M4gX4-zR
7
7
  pyobvector/client/index_param.py,sha256=3gXi66Ey1PO9x5_61CrH7DmPb496kviBQI5NT7nfbGc,6309
8
8
  pyobvector/client/milvus_like_client.py,sha256=CpPo6mkGE8iNFpKGBFof3h7E1VTzy1DAPGlFM9F_s8g,26373
9
9
  pyobvector/client/ob_vec_client.py,sha256=Yt2nG0w4268hg7DE0tqkGaytGsY-jqojX8hGTQjmsKg,29390
10
- pyobvector/client/ob_vec_json_table_client.py,sha256=vQQoRGv8Dl2ZCnOcd4aC2g1Vc_15zwsHYw9CgHkdTYs,37807
10
+ pyobvector/client/ob_vec_json_table_client.py,sha256=l9zlryiyuk7wubksWJjmbUuNWErQZwM69K2qu4K8yVE,38621
11
11
  pyobvector/client/partitions.py,sha256=Bxwr5yVNlXwZc7SXBC03NeqL9giy4Fe6S2qZdHD8xGw,15621
12
12
  pyobvector/client/schema_type.py,sha256=ICCSriOhk-P7Q1PhK0D0XQMTd3ZDFenCrJMXp6hRQdw,1579
13
13
  pyobvector/json_table/__init__.py,sha256=X5MmK3f10oyJleUUFZJFeunMEfzmf6P1f_7094b-FZc,554
@@ -29,7 +29,7 @@ pyobvector/schema/vector_index.py,sha256=aNtrEBUclc4s6QuqCZpu3Hj3OdjyhbWgtLiJzo6
29
29
  pyobvector/util/__init__.py,sha256=D9EgRDlcMSDhY3uI__vnCl45Or75dOXMWSval5P5fqs,251
30
30
  pyobvector/util/ob_version.py,sha256=ZIySam8q_MCiwctAiAHPB4GdAzGQiXEo1wVkc9IOTDU,1539
31
31
  pyobvector/util/vector.py,sha256=xyM-NuOyd78K7P3kinqyWvLIzEbf9c-4TKn_QVF7qgw,2265
32
- pyobvector-0.2.7.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
33
- pyobvector-0.2.7.dist-info/METADATA,sha256=fXmr0B-1B9Q-fqT4K6PAHiHakyqMBHv88lmySvv2t4U,6661
34
- pyobvector-0.2.7.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
35
- pyobvector-0.2.7.dist-info/RECORD,,
32
+ pyobvector-0.2.8.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
33
+ pyobvector-0.2.8.dist-info/METADATA,sha256=PVTCENc27h0nh_UwNAF4M1ewnyHZlRGijs9wR3Gkv1o,6661
34
+ pyobvector-0.2.8.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
35
+ pyobvector-0.2.8.dist-info/RECORD,,