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 +1 -1
- typedal/core.py +48 -4
- {typedal-3.15.0.dist-info → typedal-3.15.2.dist-info}/METADATA +2 -2
- {typedal-3.15.0.dist-info → typedal-3.15.2.dist-info}/RECORD +6 -6
- {typedal-3.15.0.dist-info → typedal-3.15.2.dist-info}/WHEEL +1 -1
- {typedal-3.15.0.dist-info → typedal-3.15.2.dist-info}/entry_points.txt +0 -0
typedal/__about__.py
CHANGED
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(
|
|
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
|
|
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.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: TypeDAL
|
|
3
|
-
Version: 3.15.
|
|
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=
|
|
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=
|
|
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.
|
|
17
|
-
typedal-3.15.
|
|
18
|
-
typedal-3.15.
|
|
19
|
-
typedal-3.15.
|
|
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,,
|
|
File without changes
|