sunholo 0.123.3__py3-none-any.whl → 0.123.4__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.
@@ -228,22 +228,31 @@ class AlloyDBClient:
228
228
  def _execute_sql_langchain(self, sql_statement):
229
229
  return self.engine._fetch(query = sql_statement)
230
230
 
231
- def _execute_sql_pg8000(self, sql_statement):
232
- """Executes a given SQL statement with error handling.
231
+ def _execute_sql_pg8000(self, sql_statement, params=None):
232
+ """
233
+ Executes a given SQL statement with error handling.
233
234
 
234
- - sql_statement (str): The SQL statement to execute.
235
- - Returns: The result of the execution, if any.
235
+ Args:
236
+ sql_statement (str): The SQL statement to execute.
237
+ params (dict or list, optional): Parameters for the SQL statement.
238
+
239
+ Returns:
240
+ The result of the execution, if any.
236
241
  """
237
242
  sql_ = sqlalchemy.text(sql_statement)
238
243
  result = None
239
244
  with self.engine.connect() as conn:
240
245
  try:
241
246
  log.info(f"Executing SQL statement: {sql_}")
242
- result = conn.execute(sql_)
247
+ if params:
248
+ result = conn.execute(sql_, params)
249
+ else:
250
+ result = conn.execute(sql_)
243
251
  except DatabaseError as e:
244
252
  if "already exists" in str(e):
245
253
  log.warning(f"Error ignored: {str(e)}. Assuming object already exists.")
246
254
  else:
255
+ log.error(f"Database error: {e}, SQL: {sql_statement}, Params: {params}")
247
256
  raise
248
257
  finally:
249
258
  conn.close()
@@ -253,6 +262,7 @@ class AlloyDBClient:
253
262
  async def execute_sql_async(self, sql_statement):
254
263
  log.info(f"Executing async SQL statement: {sql_statement}")
255
264
  if self.engine_type == "pg8000":
265
+ # dont use async???
256
266
  result = await self._execute_sql_async_pg8000(sql_statement)
257
267
  elif self.engine_type == "langchain":
258
268
  result = await self._execute_sql_async_langchain(sql_statement)
@@ -275,14 +285,14 @@ class AlloyDBClient:
275
285
  sql_ = sqlalchemy.text(sql_statement)
276
286
  result = None
277
287
 
278
- # Get connection directly, avoiding async with
279
- conn = await self.engine.connect()
288
+ # IMPORTANT: Don't use await here, the engine.connect() is synchronous
289
+ conn = self.engine.connect()
280
290
  try:
281
291
  log.info(f"Executing SQL statement asynchronously: {sql_}")
282
292
  if values:
283
- result = await conn.execute(sql_, values)
293
+ result = conn.execute(sql_, values)
284
294
  else:
285
- result = await conn.execute(sql_)
295
+ result = conn.execute(sql_)
286
296
 
287
297
  # Explicitly commit transaction
288
298
  await conn.commit()
@@ -293,7 +303,7 @@ class AlloyDBClient:
293
303
  raise
294
304
  finally:
295
305
  # Close connection only here, not inside the context manager
296
- await conn.close()
306
+ conn.close()
297
307
 
298
308
  return result
299
309
 
@@ -512,42 +522,6 @@ class AlloyDBClient:
512
522
 
513
523
  self.grant_table_permissions(vectorstore_id, users)
514
524
 
515
- async def _execute_sql_async_pg8000(self, sql_statement, values=None):
516
- """Executes a given SQL statement asynchronously with error handling."""
517
- sql_ = sqlalchemy.text(sql_statement)
518
- result = None
519
- async with self.engine.connect() as conn:
520
- try:
521
- log.info(f"Executing SQL statement asynchronously: {sql_}")
522
- if values:
523
- result = await conn.execute(sql_, values)
524
- else:
525
- result = await conn.execute(sql_)
526
- except DatabaseError as e:
527
- if "already exists" in str(e):
528
- log.warning(f"Error ignored: {str(e)}. Assuming object already exists.")
529
- else:
530
- raise
531
- finally:
532
- await conn.close()
533
-
534
- return result
535
-
536
- async def _execute_sql_async_langchain(self, sql_statement, values=None):
537
- """Execute SQL asynchronously using langchain engine"""
538
- if values:
539
- # Implement parameterized queries for langchain engine
540
- # This would need to be adjusted based on how langchain engine handles parameters
541
- log.warning("Parameterized queries may not be fully supported with langchain engine")
542
- # For now, attempt a basic string substitution (not ideal for production)
543
- for value in values:
544
- if isinstance(value, str):
545
- sql_statement = sql_statement.replace("%s", f"'{value}'", 1)
546
- else:
547
- sql_statement = sql_statement.replace("%s", str(value), 1)
548
-
549
- return await self.engine._afetch(query=sql_statement)
550
-
551
525
  async def check_connection(self):
552
526
  """
553
527
  Checks if the database connection is still valid.
@@ -650,15 +624,24 @@ class AlloyDBClient:
650
624
  )
651
625
  '''
652
626
 
653
- # Execute SQL to create table
654
- result = await self.execute_sql_async(sql)
627
+ # Execute SQL to create table based on engine type
628
+ if self.engine_type == "pg8000":
629
+ # Use the synchronous method for pg8000
630
+ result = self._execute_sql_pg8000(sql)
631
+ else:
632
+ # Use the async method for langchain
633
+ result = await self._execute_sql_async_langchain(sql)
634
+
655
635
  log.info(f"Created or ensured table {table_name} exists")
656
636
 
657
637
  # Grant permissions if users are provided
658
638
  if users:
659
639
  for user in users:
660
640
  grant_sql = f'GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE "{table_name}" TO "{user}";'
661
- await self.execute_sql_async(grant_sql)
641
+ if self.engine_type == "pg8000":
642
+ self.execute_sql(grant_sql)
643
+ else:
644
+ await self._execute_sql_async_langchain(grant_sql)
662
645
 
663
646
  return result
664
647
 
@@ -683,15 +666,22 @@ class AlloyDBClient:
683
666
  insert_data["extraction_backend"] = metadata.get("extraction_backend", "unknown")
684
667
  insert_data["extraction_model"] = metadata.get("extraction_model", "unknown")
685
668
 
686
- # Prepare column names and placeholders for values
669
+ # Prepare column names and values for SQL
687
670
  columns = [f'"{key}"' for key in insert_data.keys()]
688
- placeholders = []
689
- values = []
690
671
 
691
- # Process values and create properly formatted placeholders
692
- for key, value in insert_data.items():
693
- values.append(json.dumps(value) if isinstance(value, (dict, list)) else value)
694
- placeholders.append("%s")
672
+ # Process values
673
+ processed_values = {}
674
+ for i, (key, value) in enumerate(insert_data.items()):
675
+ # Create a unique parameter name
676
+ param_name = f"param_{i}"
677
+ # For JSON values, convert to string
678
+ if isinstance(value, (dict, list)):
679
+ processed_values[param_name] = json.dumps(value)
680
+ else:
681
+ processed_values[param_name] = value
682
+
683
+ # Create placeholders using named parameters
684
+ placeholders = [f":{param_name}" for param_name in processed_values.keys()]
695
685
 
696
686
  # Create SQL statement for insertion
697
687
  columns_str = ", ".join(columns)
@@ -703,8 +693,14 @@ class AlloyDBClient:
703
693
  RETURNING id
704
694
  '''
705
695
 
706
- # Execute SQL to insert data
707
- result = await self.execute_sql_async(sql, values)
696
+ # Execute SQL to insert data based on engine type
697
+ if self.engine_type == "pg8000":
698
+ # Use the synchronous method for pg8000 with properly formatted parameters
699
+ result = self._execute_sql_pg8000(sql, processed_values)
700
+ else:
701
+ # Use the async method for langchain
702
+ result = await self._execute_sql_async_langchain(sql, processed_values)
703
+
708
704
  log.info(f"Inserted data into table {table_name}")
709
705
 
710
706
  return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sunholo
3
- Version: 0.123.3
3
+ Version: 0.123.4
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Author-email: Holosun ApS <multivac@sunholo.com>
6
6
  License: Apache License, Version 2.0
@@ -60,7 +60,7 @@ sunholo/components/retriever.py,sha256=Wmchv3huAM4w7DIS-a5Lp9Hi7M8pE6vZdxgseiT9S
60
60
  sunholo/components/vectorstore.py,sha256=k7GS1Y5c6ZGXSDAJvyCes6dTjhDAi0fjGbVLqpyfzBc,5918
61
61
  sunholo/database/__init__.py,sha256=bpB5Nk21kwqYj-qdVnvNgXjLsbflnH4g-San7OHMqR4,283
62
62
  sunholo/database/alloydb.py,sha256=x1zUMB-EVWbE2Zvp4nAs2Z-tB_kOZmS45H2lwVHdYnk,11678
63
- sunholo/database/alloydb_client.py,sha256=yksz52Qnx8xCsW61TPKGqSGTehSukP8suKwShec4z54,27401
63
+ sunholo/database/alloydb_client.py,sha256=pppcmPx1liMmQSiKCdpNR6BLODbvEdICAQMz2EEjxnQ,27081
64
64
  sunholo/database/database.py,sha256=VqhZdkXUNdvWn8sUcUV3YNby1JDVf7IykPVXWBtxo9U,7361
65
65
  sunholo/database/lancedb.py,sha256=DyfZntiFKBlVPaFooNN1Z6Pl-LAs4nxWKKuq8GBqN58,715
66
66
  sunholo/database/static_dbs.py,sha256=8cvcMwUK6c32AS2e_WguKXWMkFf5iN3g9WHzsh0C07Q,442
@@ -168,9 +168,9 @@ sunholo/vertex/init.py,sha256=1OQwcPBKZYBTDPdyU7IM4X4OmiXLdsNV30C-fee2scQ,2875
168
168
  sunholo/vertex/memory_tools.py,sha256=tBZxqVZ4InTmdBvLlOYwoSEWu4-kGquc-gxDwZCC4FA,7667
169
169
  sunholo/vertex/safety.py,sha256=S9PgQT1O_BQAkcqauWncRJaydiP8Q_Jzmu9gxYfy1VA,2482
170
170
  sunholo/vertex/type_dict_to_json.py,sha256=uTzL4o9tJRao4u-gJOFcACgWGkBOtqACmb6ihvCErL8,4694
171
- sunholo-0.123.3.dist-info/licenses/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
172
- sunholo-0.123.3.dist-info/METADATA,sha256=BYdslKNSlXmkUMdV4JExD5JzamsfnwVfzIepQV9PsAA,10001
173
- sunholo-0.123.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
174
- sunholo-0.123.3.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
175
- sunholo-0.123.3.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
176
- sunholo-0.123.3.dist-info/RECORD,,
171
+ sunholo-0.123.4.dist-info/licenses/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
172
+ sunholo-0.123.4.dist-info/METADATA,sha256=iJAH2MBdmtJhWAoZmyMoVQZUGHs3Q8iuJYkC_JmRhSo,10001
173
+ sunholo-0.123.4.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
174
+ sunholo-0.123.4.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
175
+ sunholo-0.123.4.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
176
+ sunholo-0.123.4.dist-info/RECORD,,