TypeDAL 3.16.2__tar.gz → 3.16.4__tar.gz
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-3.16.2 → typedal-3.16.4}/CHANGELOG.md +12 -0
- {typedal-3.16.2 → typedal-3.16.4}/PKG-INFO +1 -1
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/__about__.py +1 -1
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/core.py +57 -32
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_row.py +39 -5
- {typedal-3.16.2 → typedal-3.16.4}/.github/workflows/su6.yml +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/.gitignore +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/.readthedocs.yml +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/README.md +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/coverage.svg +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/docs/1_getting_started.md +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/docs/2_defining_tables.md +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/docs/3_building_queries.md +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/docs/4_relationships.md +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/docs/5_py4web.md +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/docs/6_migrations.md +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/docs/7_mixins.md +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/docs/css/code_blocks.css +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/docs/index.md +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/docs/requirements.txt +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/example_new.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/example_old.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/mkdocs.yml +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/pyproject.toml +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/__init__.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/caching.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/cli.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/config.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/fields.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/for_py4web.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/for_web2py.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/helpers.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/mixins.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/py.typed +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/serializers/as_json.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/types.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/src/typedal/web2py_py4web_shared.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/__init__.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/configs/simple.toml +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/configs/valid.env +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/configs/valid.toml +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_cli.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_config.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_docs_examples.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_helpers.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_json.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_main.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_mixins.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_mypy.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_orm.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_py4web.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_query_builder.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_relationships.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_stats.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_table.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_web2py.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/test_xx_others.py +0 -0
- {typedal-3.16.2 → typedal-3.16.4}/tests/timings.py +0 -0
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
<!--next-version-placeholder-->
|
|
4
4
|
|
|
5
|
+
## v3.16.4 (2025-09-08)
|
|
6
|
+
|
|
7
|
+
### Fix
|
|
8
|
+
|
|
9
|
+
* Support `.render()` with list:str relationships ([`e7d6d82`](https://github.com/trialandsuccess/TypeDAL/commit/e7d6d82de82034eee882ab4bc4e1ebf8178f8639))
|
|
10
|
+
|
|
11
|
+
## v3.16.3 (2025-09-08)
|
|
12
|
+
|
|
13
|
+
### Fix
|
|
14
|
+
|
|
15
|
+
* Support `.render()` on individual row ([`200a64c`](https://github.com/trialandsuccess/TypeDAL/commit/200a64c0e0c2647c5036dee0476d9ad8ebb416e4))
|
|
16
|
+
|
|
5
17
|
## v3.16.2 (2025-09-08)
|
|
6
18
|
|
|
7
19
|
### Fix
|
|
@@ -2037,6 +2037,61 @@ class TypedTable(_TypedTable, metaclass=TableMeta):
|
|
|
2037
2037
|
|
|
2038
2038
|
return pydal2sql.generate_sql(cls)
|
|
2039
2039
|
|
|
2040
|
+
def render(self, fields=None, compact=False) -> Self:
|
|
2041
|
+
row = copy.deepcopy(self)
|
|
2042
|
+
keys = list(row)
|
|
2043
|
+
if not fields:
|
|
2044
|
+
fields = [self._table[f] for f in self._table._fields]
|
|
2045
|
+
fields = [f for f in fields if isinstance(f, Field) and f.represent]
|
|
2046
|
+
|
|
2047
|
+
for field in fields:
|
|
2048
|
+
if field._table == self._table:
|
|
2049
|
+
row[field.name] = self._db.represent(
|
|
2050
|
+
"rows_render",
|
|
2051
|
+
field,
|
|
2052
|
+
row[field.name],
|
|
2053
|
+
row,
|
|
2054
|
+
)
|
|
2055
|
+
# else: relationship, different logic:
|
|
2056
|
+
|
|
2057
|
+
for relation_name in getattr(row, "_with", []):
|
|
2058
|
+
if relation := self._relationships.get(relation_name):
|
|
2059
|
+
relation_table = relation.table
|
|
2060
|
+
|
|
2061
|
+
relation_row = row[relation_name]
|
|
2062
|
+
|
|
2063
|
+
if isinstance(relation_row, list):
|
|
2064
|
+
# list of rows
|
|
2065
|
+
combined = []
|
|
2066
|
+
|
|
2067
|
+
for related_og in relation_row:
|
|
2068
|
+
related = copy.deepcopy(related_og)
|
|
2069
|
+
for fieldname in related:
|
|
2070
|
+
field = relation_table[fieldname]
|
|
2071
|
+
related[field.name] = self._db.represent(
|
|
2072
|
+
"rows_render",
|
|
2073
|
+
field,
|
|
2074
|
+
related[field.name],
|
|
2075
|
+
related,
|
|
2076
|
+
)
|
|
2077
|
+
combined.append(related)
|
|
2078
|
+
|
|
2079
|
+
row[relation_name] = combined
|
|
2080
|
+
else:
|
|
2081
|
+
# 1 row
|
|
2082
|
+
for fieldname in relation_row:
|
|
2083
|
+
field = relation_table[fieldname]
|
|
2084
|
+
row[relation_name][fieldname] = self._db.represent(
|
|
2085
|
+
"rows_render",
|
|
2086
|
+
field,
|
|
2087
|
+
relation_row[field.name],
|
|
2088
|
+
relation_row,
|
|
2089
|
+
)
|
|
2090
|
+
|
|
2091
|
+
if compact and len(keys) == 1 and keys[0] != "_extra": # pragma: no cover
|
|
2092
|
+
return row[keys[0]]
|
|
2093
|
+
return row
|
|
2094
|
+
|
|
2040
2095
|
|
|
2041
2096
|
# backwards compat:
|
|
2042
2097
|
TypedRow = TypedTable
|
|
@@ -2431,38 +2486,8 @@ class TypedRows(typing.Collection[T_MetaInstance], Rows):
|
|
|
2431
2486
|
"Rows.render() needs a `rows_render` representer in DAL instance",
|
|
2432
2487
|
)
|
|
2433
2488
|
|
|
2434
|
-
row =
|
|
2435
|
-
|
|
2436
|
-
if not fields:
|
|
2437
|
-
fields = [f for f in self.fields if isinstance(f, Field) and f.represent]
|
|
2438
|
-
|
|
2439
|
-
for field in fields:
|
|
2440
|
-
if field._table == self.model._table:
|
|
2441
|
-
row[field.name] = self.db.represent(
|
|
2442
|
-
"rows_render",
|
|
2443
|
-
field,
|
|
2444
|
-
row[field.name],
|
|
2445
|
-
row,
|
|
2446
|
-
)
|
|
2447
|
-
# else: relationship, different logic:
|
|
2448
|
-
|
|
2449
|
-
for relation_name in row._with:
|
|
2450
|
-
if relation := self.model._relationships.get(relation_name):
|
|
2451
|
-
relation_table = relation.table
|
|
2452
|
-
|
|
2453
|
-
relation_row = row[relation_name]
|
|
2454
|
-
for fieldname in relation_row:
|
|
2455
|
-
field = relation_table[fieldname]
|
|
2456
|
-
row[relation_name][fieldname] = self.db.represent(
|
|
2457
|
-
"rows_render",
|
|
2458
|
-
field,
|
|
2459
|
-
relation_row[field.name],
|
|
2460
|
-
relation_row,
|
|
2461
|
-
)
|
|
2462
|
-
|
|
2463
|
-
if self.compact and len(keys) == 1 and keys[0] != "_extra": # pragma: no cover
|
|
2464
|
-
return row[keys[0]]
|
|
2465
|
-
return row
|
|
2489
|
+
row = self.records[i]
|
|
2490
|
+
return row.render(fields, compact=self.compact)
|
|
2466
2491
|
|
|
2467
2492
|
|
|
2468
2493
|
from .caching import ( # noqa: E402
|
|
@@ -240,16 +240,50 @@ def test_render():
|
|
|
240
240
|
condition=lambda this, that: this.normal == that.also_normal,
|
|
241
241
|
)
|
|
242
242
|
|
|
243
|
+
related_list = relationship(
|
|
244
|
+
list[RelatedTable],
|
|
245
|
+
condition=lambda this, that: this.normal == that.also_normal,
|
|
246
|
+
)
|
|
247
|
+
|
|
243
248
|
RelatedTable.insert(also_normal="123")
|
|
244
249
|
RenderTable.insert(normal="123", list_field=["abc", "def"])
|
|
245
250
|
|
|
246
251
|
rows = RenderTable.select().join("related").collect()
|
|
247
252
|
|
|
248
|
-
|
|
253
|
+
first = rows.first()
|
|
254
|
+
|
|
255
|
+
assert first.related
|
|
256
|
+
|
|
257
|
+
iterator = rows.render()
|
|
258
|
+
rendered_one = next(iterator)
|
|
259
|
+
|
|
260
|
+
assert rendered_one.normal == "123"
|
|
261
|
+
assert rendered_one.list_field == "abc, def"
|
|
262
|
+
assert rendered_one.related.also_normal == "321"
|
|
263
|
+
|
|
264
|
+
# .render() on one row:
|
|
265
|
+
rendered_two = first.render()
|
|
266
|
+
assert rendered_two.normal == "123"
|
|
267
|
+
assert rendered_two.list_field == "abc, def"
|
|
268
|
+
assert rendered_two.related.also_normal == "321"
|
|
269
|
+
|
|
270
|
+
# test list:
|
|
271
|
+
|
|
272
|
+
rows = RenderTable.select().join("related_list").collect()
|
|
273
|
+
|
|
274
|
+
second = rows.first()
|
|
275
|
+
|
|
276
|
+
assert second.related_list
|
|
249
277
|
|
|
250
278
|
iterator = rows.render()
|
|
251
|
-
|
|
279
|
+
rendered_three = next(iterator)
|
|
280
|
+
|
|
281
|
+
assert rendered_three.normal == "123"
|
|
282
|
+
assert rendered_three.list_field == "abc, def"
|
|
283
|
+
assert rendered_three.related_list[0].also_normal == "321"
|
|
284
|
+
|
|
285
|
+
rendered_four = second.render()
|
|
252
286
|
|
|
253
|
-
assert
|
|
254
|
-
assert
|
|
255
|
-
assert
|
|
287
|
+
assert rendered_four.normal == "123"
|
|
288
|
+
assert rendered_four.list_field == "abc, def"
|
|
289
|
+
assert rendered_four.related_list[0].also_normal == "321"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|