kailash 0.9.11__py3-none-any.whl → 0.9.13__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.
kailash/__init__.py CHANGED
@@ -50,7 +50,7 @@ except ImportError:
50
50
  # For backward compatibility
51
51
  WorkflowGraph = Workflow
52
52
 
53
- __version__ = "0.9.11"
53
+ __version__ = "0.9.13"
54
54
 
55
55
  __all__ = [
56
56
  # Core workflow components
@@ -434,22 +434,63 @@ class PostgreSQLAdapter(DatabaseAdapter):
434
434
  parameter_types: Optional[dict[str, str]] = None,
435
435
  ) -> Any:
436
436
  """Execute query and return results."""
437
+
438
+ import logging
439
+
440
+ logger = logging.getLogger(__name__)
441
+
437
442
  # Convert dict params to positional for asyncpg
438
443
  if isinstance(params, dict):
439
444
  # Simple parameter substitution for named params
440
- # In production, use a proper SQL parser
445
+ # Fix: Use proper ordering and safe replacement to avoid collisions
441
446
  import json
447
+ import logging
448
+
449
+ logger = logging.getLogger(__name__)
442
450
 
443
451
  query_params = []
444
452
  param_names = [] # Track parameter names for type mapping
445
- for i, (key, value) in enumerate(params.items(), 1):
446
- query = query.replace(f":{key}", f"${i}")
453
+
454
+ # Keep original order for parameter values, but do replacements safely
455
+ original_items = list(params.items())
456
+
457
+ # Create parameter values in original order
458
+ for key, value in original_items:
447
459
  param_names.append(key)
448
460
  # For PostgreSQL, lists should remain as lists for array operations
449
461
  # Only convert dicts to JSON strings
450
462
  if isinstance(value, dict):
451
463
  value = json.dumps(value)
464
+ # Fix for parameter $11 issue: Handle ambiguous integer values
465
+ # AsyncPG has trouble with certain integer values (especially 0)
466
+ # where it can't determine the PostgreSQL type automatically
467
+ elif isinstance(value, int) and value == 0:
468
+ # Keep as int but we'll add explicit casting in the query later
469
+ pass
452
470
  query_params.append(value)
471
+
472
+ # Replace parameters in the query, processing longer keys first to avoid collision
473
+ # Sort keys by length (descending) for replacement order only
474
+ keys_by_length = sorted(params.keys(), key=len, reverse=True)
475
+
476
+ for key in keys_by_length:
477
+ # Find the position of this key in the original order
478
+ position = (
479
+ next(i for i, (k, v) in enumerate(original_items) if k == key) + 1
480
+ )
481
+ value = original_items[position - 1][1] # Get the actual value
482
+
483
+ # Fix for parameter $11 issue: Add explicit type casting for ambiguous values
484
+ # Note: Check boolean first since bool is a subclass of int in Python
485
+ if isinstance(value, bool):
486
+ # Cast boolean parameters to avoid type ambiguity
487
+ query = query.replace(f":{key}", f"${position}::boolean")
488
+ elif isinstance(value, int):
489
+ # Cast integer parameters to avoid PostgreSQL type determination issues
490
+ query = query.replace(f":{key}", f"${position}::integer")
491
+ else:
492
+ query = query.replace(f":{key}", f"${position}")
493
+
453
494
  params = query_params
454
495
 
455
496
  # Apply parameter type casts if provided
@@ -462,6 +503,8 @@ class PostgreSQLAdapter(DatabaseAdapter):
462
503
  query = query.replace(f"${i}", f"${i}::{pg_type}")
463
504
 
464
505
  else:
506
+ # Parameters are not dict - they might be list/tuple
507
+
465
508
  # For positional params, apply type casts if provided
466
509
  if parameter_types and isinstance(params, (list, tuple)):
467
510
  # Build query with type casts for positional parameters
@@ -2049,6 +2092,9 @@ class AsyncSQLDatabaseNode(AsyncNode):
2049
2092
  except Exception as e:
2050
2093
  last_error = e
2051
2094
 
2095
+ # Parameter type determination is now handled during dict-to-positional conversion
2096
+ # No special retry logic needed for parameter $11
2097
+
2052
2098
  # Check if error is retryable
2053
2099
  if not self._retry_config.should_retry(e):
2054
2100
  raise
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kailash
3
- Version: 0.9.11
3
+ Version: 0.9.13
4
4
  Summary: Python SDK for the Kailash container-node architecture
5
5
  Home-page: https://github.com/integrum/kailash-python-sdk
6
6
  Author: Integrum
@@ -1,4 +1,4 @@
1
- kailash/__init__.py,sha256=Nm6AU7y6IWWdXr9CuNwAH60wuVULzQpPUy5cLLTPgQ4,2772
1
+ kailash/__init__.py,sha256=uwuUF8NkGdTevuagVlf9p88uWxySPRKyHTJ1iehlDRg,2772
2
2
  kailash/__main__.py,sha256=vr7TVE5o16V6LsTmRFKG6RDKUXHpIWYdZ6Dok2HkHnI,198
3
3
  kailash/access_control.py,sha256=MjKtkoQ2sg1Mgfe7ovGxVwhAbpJKvaepPWr8dxOueMA,26058
4
4
  kailash/access_control_abac.py,sha256=FPfa_8PuDP3AxTjdWfiH3ntwWO8NodA0py9W8SE5dno,30263
@@ -203,7 +203,7 @@ kailash/nodes/compliance/data_retention.py,sha256=90bH_eGwlcDzUdklAJeXQM-RcuLUGQ
203
203
  kailash/nodes/compliance/gdpr.py,sha256=ZMoHZjAo4QtGwtFCzGMrAUBFV3TbZOnJ5DZGZS87Bas,70548
204
204
  kailash/nodes/data/__init__.py,sha256=f0h4ysvXxlyFcNJLvDyXrgJ0ixwDF1cS0pJ2QNPakhg,5213
205
205
  kailash/nodes/data/async_connection.py,sha256=wfArHs9svU48bxGZIiixSV2YVn9cukNgEjagwTRu6J4,17250
206
- kailash/nodes/data/async_sql.py,sha256=EPyWTP9B1ws9mCGdcJYU37of-qBklEuXlAMHwJFoQMU,112110
206
+ kailash/nodes/data/async_sql.py,sha256=lVNbYaKnanK4Ejm6VZSPSUuPqBItlP7rAQ3Zvp-KeYg,114285
207
207
  kailash/nodes/data/async_vector.py,sha256=HtwQLO25IXu8Vq80qzU8rMkUAKPQ2qM0x8YxjXHlygU,21005
208
208
  kailash/nodes/data/bulk_operations.py,sha256=WVopmosVkIlweFxVt3boLdCPc93EqpYyQ1Ez9mCIt0c,34453
209
209
  kailash/nodes/data/directory.py,sha256=fbfLqD_ijRubk-4xew3604QntPsyDxqaF4k6TpfyjDg,9923
@@ -403,10 +403,10 @@ kailash/workflow/templates.py,sha256=XQMAKZXC2dlxgMMQhSEOWAF3hIbe9JJt9j_THchhAm8
403
403
  kailash/workflow/type_inference.py,sha256=i1F7Yd_Z3elTXrthsLpqGbOnQBIVVVEjhRpI0HrIjd0,24492
404
404
  kailash/workflow/validation.py,sha256=r2zApGiiG8UEn7p5Ji842l8OR1_KftzDkWc7gg0cac0,44675
405
405
  kailash/workflow/visualization.py,sha256=nHBW-Ai8QBMZtn2Nf3EE1_aiMGi9S6Ui_BfpA5KbJPU,23187
406
- kailash-0.9.11.dist-info/licenses/LICENSE,sha256=9GYZHXVUmx6FdFRNzOeE_w7a_aEGeYbqTVmFtJlrbGk,13438
407
- kailash-0.9.11.dist-info/licenses/NOTICE,sha256=9ssIK4LcHSTFqriXGdteMpBPTS1rSLlYtjppZ_bsjZ0,723
408
- kailash-0.9.11.dist-info/METADATA,sha256=mVyKebe-SSC9dsVrf3tIJCEVbq2Oz--W9AA59itYRP0,23528
409
- kailash-0.9.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
410
- kailash-0.9.11.dist-info/entry_points.txt,sha256=M_q3b8PG5W4XbhSgESzIJjh3_4OBKtZFYFsOdkr2vO4,45
411
- kailash-0.9.11.dist-info/top_level.txt,sha256=z7GzH2mxl66498pVf5HKwo5wwfPtt9Aq95uZUpH6JV0,8
412
- kailash-0.9.11.dist-info/RECORD,,
406
+ kailash-0.9.13.dist-info/licenses/LICENSE,sha256=9GYZHXVUmx6FdFRNzOeE_w7a_aEGeYbqTVmFtJlrbGk,13438
407
+ kailash-0.9.13.dist-info/licenses/NOTICE,sha256=9ssIK4LcHSTFqriXGdteMpBPTS1rSLlYtjppZ_bsjZ0,723
408
+ kailash-0.9.13.dist-info/METADATA,sha256=CaNC1Ph9fceyd9MOuukP4v7EQVuWNNI1AwCWSD-zV4Y,23528
409
+ kailash-0.9.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
410
+ kailash-0.9.13.dist-info/entry_points.txt,sha256=M_q3b8PG5W4XbhSgESzIJjh3_4OBKtZFYFsOdkr2vO4,45
411
+ kailash-0.9.13.dist-info/top_level.txt,sha256=z7GzH2mxl66498pVf5HKwo5wwfPtt9Aq95uZUpH6JV0,8
412
+ kailash-0.9.13.dist-info/RECORD,,