TypeDAL 3.15.1__py3-none-any.whl → 3.15.3__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.

Potentially problematic release.


This version of TypeDAL might be problematic. Click here for more details.

typedal/__about__.py CHANGED
@@ -5,4 +5,4 @@ This file contains the Version info for this package.
5
5
  # SPDX-FileCopyrightText: 2023-present Robin van der Noord <robinvandernoord@gmail.com>
6
6
  #
7
7
  # SPDX-License-Identifier: MIT
8
- __version__ = "3.15.1"
8
+ __version__ = "3.15.3"
typedal/core.py CHANGED
@@ -9,6 +9,7 @@ import functools
9
9
  import inspect
10
10
  import json
11
11
  import math
12
+ import re
12
13
  import sys
13
14
  import types
14
15
  import typing
@@ -1608,6 +1609,7 @@ class TypedTable(_TypedTable, metaclass=TableMeta):
1608
1609
 
1609
1610
  # set up by 'new':
1610
1611
  _row: Row | None = None
1612
+ _rows: tuple[Row, ...] = ()
1611
1613
 
1612
1614
  _with: list[str]
1613
1615
 
@@ -1695,6 +1697,14 @@ class TypedTable(_TypedTable, metaclass=TableMeta):
1695
1697
 
1696
1698
  raise AttributeError(item)
1697
1699
 
1700
+ def keys(self):
1701
+ """
1702
+ Return the combination of row + relationship keys.
1703
+
1704
+ Used by dict(row).
1705
+ """
1706
+ return list(self._row.keys()) + getattr(self, "_with", [])
1707
+
1698
1708
  def get(self, item: str, default: Any = None) -> Any:
1699
1709
  """
1700
1710
  Try to get a column from this instance, else return default.
@@ -1980,6 +1990,7 @@ class TypedRows(typing.Collection[T_MetaInstance], Rows):
1980
1990
  model: Type[T_MetaInstance],
1981
1991
  records: dict[int, T_MetaInstance] = None,
1982
1992
  metadata: Metadata = None,
1993
+ raw: dict[int, list[Row]] = None,
1983
1994
  ) -> None:
1984
1995
  """
1985
1996
  Should not be called manually!
@@ -2005,6 +2016,11 @@ class TypedRows(typing.Collection[T_MetaInstance], Rows):
2005
2016
  raise NotImplementedError(f"`id` could not be found for {row}")
2006
2017
 
2007
2018
  records = records or {_get_id(row): model(row) for row in rows}
2019
+ raw = raw or {}
2020
+
2021
+ for idx, entity in records.items():
2022
+ entity._rows = tuple(raw.get(idx, []))
2023
+
2008
2024
  super().__init__(rows.db, records, rows.colnames, rows.compact, rows.response, rows.fields)
2009
2025
  self.model = model
2010
2026
  self.metadata = metadata or {}
@@ -2321,6 +2337,29 @@ from .caching import ( # noqa: E402
2321
2337
  )
2322
2338
 
2323
2339
 
2340
+ def normalize_table_keys(row: Row, pattern: re.Pattern = re.compile(r"^([a-zA-Z_]+)_(\d{5,})$")) -> Row:
2341
+ """
2342
+ Normalize table keys in a PyDAL Row object by stripping numeric hash suffixes
2343
+ from table names, only if the suffix is 5 or more digits.
2344
+
2345
+ For example:
2346
+ Row({'articles_12345': {...}}) -> Row({'articles': {...}})
2347
+ Row({'articles_123': {...}}) -> unchanged
2348
+
2349
+ Returns:
2350
+ Row: A new Row object with normalized keys.
2351
+ """
2352
+ new_data: dict[str, Any] = {}
2353
+ for key, value in row.items():
2354
+ if match := pattern.match(key):
2355
+ base, _suffix = match.groups()
2356
+ normalized_key = base
2357
+ new_data[normalized_key] = value
2358
+ else:
2359
+ new_data[key] = value
2360
+ return Row(new_data)
2361
+
2362
+
2324
2363
  class QueryBuilder(typing.Generic[T_MetaInstance]):
2325
2364
  """
2326
2365
  Abstration on top of pydal's query system.
@@ -2864,13 +2903,20 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
2864
2903
  db = self._get_db()
2865
2904
  main_table = self.model._ensure_table_defined()
2866
2905
 
2906
+ # id: Model
2867
2907
  records = {}
2908
+
2909
+ # id: [Row]
2910
+ raw_per_id = defaultdict(list)
2911
+
2868
2912
  seen_relations: dict[str, set[str]] = defaultdict(set) # main id -> set of col + id for relation
2869
2913
 
2870
2914
  for row in rows:
2871
2915
  main = row[main_table]
2872
2916
  main_id = main.id
2873
2917
 
2918
+ raw_per_id[main_id].append(normalize_table_keys(row))
2919
+
2874
2920
  if main_id not in records:
2875
2921
  records[main_id] = self.model(main)
2876
2922
  records[main_id]._with = list(self.relationships.keys())
@@ -2915,7 +2961,7 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
2915
2961
  # create single T
2916
2962
  records[main_id][column] = instance
2917
2963
 
2918
- return _to(rows, self.model, records, metadata=metadata)
2964
+ return _to(rows, self.model, records, metadata=metadata, raw=raw_per_id)
2919
2965
 
2920
2966
  def collect_or_fail(self, exception: typing.Optional[Exception] = None) -> "TypedRows[T_MetaInstance]":
2921
2967
  """
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: TypeDAL
3
- Version: 3.15.1
3
+ Version: 3.15.3
4
4
  Summary: Typing support for PyDAL
5
5
  Project-URL: Documentation, https://typedal.readthedocs.io/
6
6
  Project-URL: Issues, https://github.com/trialandsuccess/TypeDAL/issues
@@ -1,9 +1,9 @@
1
- typedal/__about__.py,sha256=Xso865lLoa6uJvYh9ngF2KTTM3rcjIC6XYtR4N1ioLk,207
1
+ typedal/__about__.py,sha256=62cP7HMo3c0nBogw4zgAclTNfv9zwu1wgsckXO6IfWI,207
2
2
  typedal/__init__.py,sha256=Y6LT5UE3HrfWND_drJddYFbDjfnvqQER8MxZiEREFGw,366
3
3
  typedal/caching.py,sha256=6YUzUMpan56nSy3D-Jl0FS-8V4LbTnpRSoDJHj6yPYo,11782
4
4
  typedal/cli.py,sha256=SnWceLPDd-t90VPHAV9O3RR7JZtpVniT55TqtrRv3VM,19255
5
5
  typedal/config.py,sha256=0qy1zrTUdtmXPM9jHzFnSR1DJsqGJqcdG6pvhzKQHe0,11625
6
- typedal/core.py,sha256=kC6CBUPExNAytOUggcPb1jIv_X1LrHayCEAkcT80GjY,109332
6
+ typedal/core.py,sha256=vcbCmQntNUvUWl_DP-0hflss3OronMqIAh_P0GdfqGQ,110674
7
7
  typedal/fields.py,sha256=oOmTonXG-g4Lpj5_gSr8GJ-EZIEqO435Fm8-MS_cmoc,7356
8
8
  typedal/for_py4web.py,sha256=KIIu8XgnAfRQCJfZCra79k8SInOHiFuLDKUv3hzTJng,1908
9
9
  typedal/for_web2py.py,sha256=xn7zo6ImsmTkH6LacbjLQl2oqyBvP0zLqRxEJvMQk1w,1929
@@ -13,7 +13,7 @@ typedal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  typedal/types.py,sha256=1FIgv1s0be0E8r5Wd9E1nvDvK4ETV8u2NlfI7_P6UUY,6752
14
14
  typedal/web2py_py4web_shared.py,sha256=VK9T8P5UwVLvfNBsY4q79ANcABv-jX76YKADt1Zz_co,1539
15
15
  typedal/serializers/as_json.py,sha256=3JZlFhPrdvZVFAmH7P5DUAz8-TIk-br0F1CjKG3PFDM,2246
16
- typedal-3.15.1.dist-info/METADATA,sha256=-pJVFoXvP9KrqiyAvXxDkhqQ3hE7eVRLdtcgMNNEis4,10461
17
- typedal-3.15.1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
18
- typedal-3.15.1.dist-info/entry_points.txt,sha256=m1wqcc_10rHWPdlQ71zEkmJDADUAnZtn7Jac_6mbyUc,44
19
- typedal-3.15.1.dist-info/RECORD,,
16
+ typedal-3.15.3.dist-info/METADATA,sha256=zhGdjr7WGvQXGxabXqtJyl1gUHdbh0UGc7uLVYShIxY,10461
17
+ typedal-3.15.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
18
+ typedal-3.15.3.dist-info/entry_points.txt,sha256=m1wqcc_10rHWPdlQ71zEkmJDADUAnZtn7Jac_6mbyUc,44
19
+ typedal-3.15.3.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.25.0
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any