altcodepro-polydb-python 2.5.22__py3-none-any.whl → 2.5.24__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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: altcodepro-polydb-python
3
- Version: 2.5.22
3
+ Version: 2.5.24
4
4
  Summary: Production-ready multi-cloud database abstraction layer with connection pooling, retry logic, and thread safety
5
5
  Author: AltCodePro
6
6
  Project-URL: Homepage, https://github.com/altcodepro/polydb-python
@@ -1,12 +1,12 @@
1
- altcodepro_polydb_python-2.5.22.dist-info/licenses/LICENSE,sha256=9X8GLocsBwy-5aR5JGOt2SAMDDPs9Qv-YnqmHBHOXrw,1067
1
+ altcodepro_polydb_python-2.5.24.dist-info/licenses/LICENSE,sha256=9X8GLocsBwy-5aR5JGOt2SAMDDPs9Qv-YnqmHBHOXrw,1067
2
2
  polydb/PolyDB.py,sha256=Lp0QtG7D89Z6P6nt9fVoT8rVHAy8xlE2kFRSS70r-mk,23672
3
- polydb/__init__.py,sha256=5nO3ONrpIkzQDi4oka8UgcO4jAWVyAvt9gAmj7mPNdQ,1876
3
+ polydb/__init__.py,sha256=XuPMkOUcluxI8TIMNZCPyI1MZg77DC-10FKANEVobME,1876
4
4
  polydb/advanced_query.py,sha256=M9sKmdF2PsLZWSc-zKpXRcwaDumbYYTsibmL_IAjKP4,6931
5
5
  polydb/aio.py,sha256=0EQ6hXrf6N4If6pcht6L9B7qz0PU2yGahyGzEss2eQg,8340
6
6
  polydb/batch.py,sha256=ulvSdtVeofsOiVNVAQwrE9tXIIaP8fjiW1Sbpz3dcv0,4093
7
7
  polydb/cache.py,sha256=ArI0zRbuhAYd6kn4TPVMBHBptdRmuZyy05_hwIATUsQ,11784
8
8
  polydb/cloudDatabaseFactory.py,sha256=eJiNKycdaC9nO2BKWPjkig3GaNGkNjoJci6yVJC7A_c,25301
9
- polydb/databaseFactory.py,sha256=_faf37970W9T5z26q5IRuRUiXpnvABBkRX0H_5aV-jo,59746
9
+ polydb/databaseFactory.py,sha256=l0ODaR3HbTN4KNpC_oEPqN1ussorXGfKnRRq2r5xt6Q,60202
10
10
  polydb/errors.py,sha256=AtXCLdzkHE2ncUaE1P0wH5HmIyW3NXx9KHL-fCejjA4,1832
11
11
  polydb/json_safe.py,sha256=jj3ZA6gImGwgTO0dCZVcckjeUHtewa2HP6OA1-u6VZ0,137
12
12
  polydb/models.py,sha256=Pq_63FXu1IiTxl-RshZ2vmoe-5m5k6qft-tXpHLn-70,12600
@@ -27,7 +27,7 @@ polydb/adapters/AzureBlobStorageAdapter.py,sha256=ZTovSC_CVduGnIoIQUUeNxDQlf-IbF
27
27
  polydb/adapters/AzureFileStorageAdapter.py,sha256=VZNprqlBXCuWUgtqClNT-NrQmRf-XFYEiRA2BLbf-Sc,7046
28
28
  polydb/adapters/AzureKeyVaultAdapter.py,sha256=EtsrxI3X75nORnO0KbvKTVXJfliHd-gt3y9Mo8Npugs,3365
29
29
  polydb/adapters/AzureQueueAdapter.py,sha256=1e2HiFvkH1BI_JKS9fgays2J41kOfH6pUPbZDe1wmWA,13658
30
- polydb/adapters/AzureTableStorageAdapter.py,sha256=W0MU4Q2v9ArlI_wz-8stqGehstPJnPkQr8jz6zNTnV4,39218
30
+ polydb/adapters/AzureTableStorageAdapter.py,sha256=7nNSL1yX3EPDkLptDcUBExOf7sNroNXK4oTwSPDgUsg,40785
31
31
  polydb/adapters/BlockchainBlobAdapter.py,sha256=85H3PxiL9rGDtK-sTsW26jOuUQ_SGipLSPu3s-juZRA,3298
32
32
  polydb/adapters/BlockchainFileAdapter.py,sha256=lZbRyC18LghZcVh5QyIRP7tCftNF_Ep1FKG0KRkvMmk,8335
33
33
  polydb/adapters/BlockchainKVAdapter.py,sha256=pvpiPshDE5Z_IRcSBvBwgAXT--86lgEyIsEUeqcmoE8,5422
@@ -69,7 +69,7 @@ polydb/observability/logging.py,sha256=FWYky-Mg1IhLpwuaKuLIsTROBZc9bI_-AO-y53nvE
69
69
  polydb/services/__init__.py,sha256=Zs3PZbHutgPdPjJatygvtYvKPZMBt1qKSqESbFRPHJs,241
70
70
  polydb/services/compliance_service.py,sha256=UMjCbQ4z13-w6pT4RLQpMi_u1zbShEpiz8kawA2WsSU,5075
71
71
  polydb/services/security_service.py,sha256=gGo_j9Ca_rgvxS7s6C5JUktugQBj1PV1DXpMnOYAGbI,4992
72
- altcodepro_polydb_python-2.5.22.dist-info/METADATA,sha256=26GBAk1iot-WHk6DimfIK7Lzshb77-_xsPPOKg0lWIQ,15599
73
- altcodepro_polydb_python-2.5.22.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
74
- altcodepro_polydb_python-2.5.22.dist-info/top_level.txt,sha256=WgLFWJoYjUhwvyPxJFl6jYLrVFuBJDX3OABf4ocwk_E,7
75
- altcodepro_polydb_python-2.5.22.dist-info/RECORD,,
72
+ altcodepro_polydb_python-2.5.24.dist-info/METADATA,sha256=6Osh8k039JDAzMEhKD7RIpHstGqXvw7rBgMVis9o8UM,15599
73
+ altcodepro_polydb_python-2.5.24.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
74
+ altcodepro_polydb_python-2.5.24.dist-info/top_level.txt,sha256=WgLFWJoYjUhwvyPxJFl6jYLrVFuBJDX3OABf4ocwk_E,7
75
+ altcodepro_polydb_python-2.5.24.dist-info/RECORD,,
polydb/__init__.py CHANGED
@@ -4,7 +4,7 @@ PolyDB - Enterprise Cloud-Independent Database Abstraction
4
4
  Full LINQ support, field-level audit, cache, soft delete, overflow storage
5
5
  """
6
6
 
7
- __version__ = "2.5.22"
7
+ __version__ = "2.5.24"
8
8
 
9
9
  from .aio import AsyncDatabaseFactory, AsyncPolyDB
10
10
  from .audit.context import AuditContext
@@ -750,11 +750,33 @@ class AzureTableStorageAdapter(NoSQLKVAdapter):
750
750
 
751
751
  eff_filters = dict(filters or {})
752
752
  parts: List[str] = []
753
+ # An equality on the model's own pk/rk FIELD is a key lookup: filtering the same value as an ordinary
754
+ # property made Azure scan the whole table (1.2s for one project's artifacts). Only valid when the key is
755
+ # built straight from that field (no partition_config template), which is how _get_pk_rk derives it.
756
+ pk_field = rk_field = None
757
+ declared = getattr(model, "__polydb__", None) or {}
758
+ if not getattr(self, "partition_config", None):
759
+ # Only fields the model declares itself; the defaults (tenant_id / id) are left as property filters
760
+ # so rows written before a model declared its keys keep matching.
761
+ pk_field = declared.get("pk_field") or None
762
+ rk_field = declared.get("rk_field") or None
753
763
  for orig_k, orig_v in eff_filters.items():
754
764
  if orig_v is None:
755
765
  continue
756
766
 
757
- if orig_k in ("partition_key", "PartitionKey"):
767
+ if (
768
+ (pk_field or rk_field)
769
+ and isinstance(orig_v, (str, int))
770
+ and not isinstance(orig_v, bool)
771
+ and orig_k in (pk_field, rk_field)
772
+ ):
773
+ # Keys are sanitized on write, so the key filter uses the sanitized value; the original
774
+ # property filter below is kept too because sanitizing can map two raw values to one key.
775
+ key_name = "PartitionKey" if orig_k == pk_field else "RowKey"
776
+ safe = self._sanitize_pk_rk(orig_v).replace("'", "''")
777
+ parts.append(f"{key_name} eq '{safe}'")
778
+ sk = self._sanitize_prop_name(orig_k)
779
+ elif orig_k in ("partition_key", "PartitionKey"):
758
780
  sk = "PartitionKey"
759
781
  elif orig_k in ("row_key", "RowKey"):
760
782
  sk = "RowKey"
polydb/databaseFactory.py CHANGED
@@ -457,6 +457,13 @@ class DatabaseFactory:
457
457
  conflict_cols = _parse_unique_violation_columns(exc)
458
458
  if not conflict_cols or not all(c in data for c in conflict_cols):
459
459
  raise
460
+ if not set(conflict_cols) <= {"id", "tenant_id"}:
461
+ # A declared-unique NON-key column: a second row with the same value is
462
+ # a violation, never a silent overwrite of the existing row.
463
+ from .base.constraints import UniqueConstraintError
464
+
465
+ col = conflict_cols[0]
466
+ raise UniqueConstraintError(col, data.get(col)) from exc
460
467
  where = {c: data[c] for c in conflict_cols}
461
468
  logger.warning(
462
469
  "insert %s hit unique violation on %s — falling through to update",