TypeDAL 3.15.0__py3-none-any.whl → 3.15.2__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.0"
8
+ __version__ = "3.15.2"
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
@@ -120,7 +121,8 @@ OnQuery: typing.TypeAlias = typing.Optional[
120
121
  ]
121
122
  ]
122
123
 
123
- To_Type = typing.TypeVar("To_Type", type[Any], Type[Any], str)
124
+ # To_Type = typing.TypeVar("To_Type", type[Any], Type[Any], str)
125
+ To_Type = typing.TypeVar("To_Type")
124
126
 
125
127
 
126
128
  class Relationship(typing.Generic[To_Type]):
@@ -201,6 +203,7 @@ class Relationship(typing.Generic[To_Type]):
201
203
  Get the table this relationship is bound to.
202
204
  """
203
205
  table = self.table # can be a string because db wasn't available yet
206
+
204
207
  if isinstance(table, str):
205
208
  if mapped := db._class_map.get(table):
206
209
  # yay
@@ -249,7 +252,9 @@ class Relationship(typing.Generic[To_Type]):
249
252
  return None
250
253
 
251
254
 
252
- def relationship(_type: To_Type, condition: Condition = None, join: JOIN_OPTIONS = None, on: OnQuery = None) -> To_Type:
255
+ def relationship(
256
+ _type: typing.Type[To_Type], condition: Condition = None, join: JOIN_OPTIONS = None, on: OnQuery = None
257
+ ) -> To_Type:
253
258
  """
254
259
  Define a relationship to another table, when its id is not stored in the current table.
255
260
 
@@ -584,7 +589,9 @@ class TypeDAL(pydal.DAL): # type: ignore
584
589
  # by now, all relationships should be instances!
585
590
  relationships=typing.cast(dict[str, Relationship[Any]], relationships),
586
591
  )
592
+ # map both name and rname:
587
593
  self._class_map[str(table)] = cls
594
+ self._class_map[table._rname] = cls
588
595
  cls.__on_define__(self)
589
596
  else:
590
597
  warnings.warn("db.define used without inheriting TypedTable. This could lead to strange problems!")
@@ -713,7 +720,7 @@ class TypeDAL(pydal.DAL): # type: ignore
713
720
  table class matches the input name.
714
721
 
715
722
  Args:
716
- table_name: The name of the table to retrieve the mapped class for.
723
+ table_name: The rname of the table to retrieve the mapped class for.
717
724
 
718
725
  Returns:
719
726
  The mapped table class if it exists, otherwise None.
@@ -1602,6 +1609,7 @@ class TypedTable(_TypedTable, metaclass=TableMeta):
1602
1609
 
1603
1610
  # set up by 'new':
1604
1611
  _row: Row | None = None
1612
+ _rows: tuple[Row, ...] = ()
1605
1613
 
1606
1614
  _with: list[str]
1607
1615
 
@@ -1974,6 +1982,7 @@ class TypedRows(typing.Collection[T_MetaInstance], Rows):
1974
1982
  model: Type[T_MetaInstance],
1975
1983
  records: dict[int, T_MetaInstance] = None,
1976
1984
  metadata: Metadata = None,
1985
+ raw: dict[int, list[Row]] = None,
1977
1986
  ) -> None:
1978
1987
  """
1979
1988
  Should not be called manually!
@@ -1999,6 +2008,11 @@ class TypedRows(typing.Collection[T_MetaInstance], Rows):
1999
2008
  raise NotImplementedError(f"`id` could not be found for {row}")
2000
2009
 
2001
2010
  records = records or {_get_id(row): model(row) for row in rows}
2011
+ raw = raw or {}
2012
+
2013
+ for idx, entity in records.items():
2014
+ entity._rows = tuple(raw.get(idx, []))
2015
+
2002
2016
  super().__init__(rows.db, records, rows.colnames, rows.compact, rows.response, rows.fields)
2003
2017
  self.model = model
2004
2018
  self.metadata = metadata or {}
@@ -2315,6 +2329,29 @@ from .caching import ( # noqa: E402
2315
2329
  )
2316
2330
 
2317
2331
 
2332
+ def normalize_table_keys(row: Row, pattern: re.Pattern = re.compile(r"^([a-zA-Z_]+)_(\d{5,})$")) -> Row:
2333
+ """
2334
+ Normalize table keys in a PyDAL Row object by stripping numeric hash suffixes
2335
+ from table names, only if the suffix is 5 or more digits.
2336
+
2337
+ For example:
2338
+ Row({'articles_12345': {...}}) -> Row({'articles': {...}})
2339
+ Row({'articles_123': {...}}) -> unchanged
2340
+
2341
+ Returns:
2342
+ Row: A new Row object with normalized keys.
2343
+ """
2344
+ new_data: dict[str, Any] = {}
2345
+ for key, value in row.items():
2346
+ if match := pattern.match(key):
2347
+ base, _suffix = match.groups()
2348
+ normalized_key = base
2349
+ new_data[normalized_key] = value
2350
+ else:
2351
+ new_data[key] = value
2352
+ return Row(new_data)
2353
+
2354
+
2318
2355
  class QueryBuilder(typing.Generic[T_MetaInstance]):
2319
2356
  """
2320
2357
  Abstration on top of pydal's query system.
@@ -2858,13 +2895,20 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
2858
2895
  db = self._get_db()
2859
2896
  main_table = self.model._ensure_table_defined()
2860
2897
 
2898
+ # id: Model
2861
2899
  records = {}
2900
+
2901
+ # id: [Row]
2902
+ raw_per_id = defaultdict(list)
2903
+
2862
2904
  seen_relations: dict[str, set[str]] = defaultdict(set) # main id -> set of col + id for relation
2863
2905
 
2864
2906
  for row in rows:
2865
2907
  main = row[main_table]
2866
2908
  main_id = main.id
2867
2909
 
2910
+ raw_per_id[main_id].append(normalize_table_keys(row))
2911
+
2868
2912
  if main_id not in records:
2869
2913
  records[main_id] = self.model(main)
2870
2914
  records[main_id]._with = list(self.relationships.keys())
@@ -2909,7 +2953,7 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
2909
2953
  # create single T
2910
2954
  records[main_id][column] = instance
2911
2955
 
2912
- return _to(rows, self.model, records, metadata=metadata)
2956
+ return _to(rows, self.model, records, metadata=metadata, raw=raw_per_id)
2913
2957
 
2914
2958
  def collect_or_fail(self, exception: typing.Optional[Exception] = None) -> "TypedRows[T_MetaInstance]":
2915
2959
  """
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: TypeDAL
3
- Version: 3.15.0
3
+ Version: 3.15.2
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=tFYWLMmiY9IJaclhUwUG67qOTY5HFlDDVEQ-pJBZCAs,207
1
+ typedal/__about__.py,sha256=_Wc0Uuj2sQ5BxBqJ8uVpOrT2tOe6xuQkzzf-hTl9rXo,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=awjvORId3Dx3P8NlCMTvJ9q_paG_auGSRg4-n-hg7ao,109186
6
+ typedal/core.py,sha256=DbVUMUvFKFDSozyeylNnHdGqE-k6sduKuTsOu32YEsg,110475
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.0.dist-info/METADATA,sha256=yuhuXMX56Wr_RmrPUODadHclKmDnJjMnAOFfZuwQuMc,10461
17
- typedal-3.15.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
18
- typedal-3.15.0.dist-info/entry_points.txt,sha256=m1wqcc_10rHWPdlQ71zEkmJDADUAnZtn7Jac_6mbyUc,44
19
- typedal-3.15.0.dist-info/RECORD,,
16
+ typedal-3.15.2.dist-info/METADATA,sha256=IaoLwUjLcLPgsnt4UdBn_jk_TEoWzOzuHEnKhW4dl0w,10461
17
+ typedal-3.15.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
18
+ typedal-3.15.2.dist-info/entry_points.txt,sha256=m1wqcc_10rHWPdlQ71zEkmJDADUAnZtn7Jac_6mbyUc,44
19
+ typedal-3.15.2.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