TypeDAL 3.8.3__py3-none-any.whl → 3.8.5__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.
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.8.3"
8
+ __version__ = "3.8.5"
typedal/core.py CHANGED
@@ -1500,7 +1500,14 @@ class TypedTable(_TypedTable, metaclass=TableMeta):
1500
1500
  return None # type: ignore
1501
1501
 
1502
1502
  inst._row = row
1503
- inst.__dict__.update(row)
1503
+
1504
+ if hasattr(row, "id"):
1505
+ inst.__dict__.update(row)
1506
+ else:
1507
+ # deal with _extra (and possibly others?)
1508
+ # Row <{actual: {}, _extra: ...}>
1509
+ inst.__dict__.update(row[str(cls)])
1510
+
1504
1511
  inst._setup_instance_methods()
1505
1512
  return inst
1506
1513
 
@@ -1828,7 +1835,22 @@ class TypedRows(typing.Collection[T_MetaInstance], Rows):
1828
1835
  `metadata` can be any (un)structured data
1829
1836
  `model` is a Typed Table class
1830
1837
  """
1831
- records = records or {row.id: model(row) for row in rows}
1838
+
1839
+ def _get_id(row: Row) -> int:
1840
+ """
1841
+ Try to find the id field in a row.
1842
+
1843
+ If _extra exists, the row changes:
1844
+ <Row {'test_relationship': {'id': 1}, '_extra': {'COUNT("test_relationship"."querytable")': 8}}>
1845
+ """
1846
+ if idx := getattr(row, "id", None):
1847
+ return typing.cast(int, idx)
1848
+ elif main := getattr(row, str(model), None):
1849
+ return typing.cast(int, main.id)
1850
+ else: # pragma: no cover
1851
+ raise NotImplementedError(f"`id` could not be found for {row}")
1852
+
1853
+ records = records or {_get_id(row): model(row) for row in rows}
1832
1854
  super().__init__(rows.db, records, rows.colnames, rows.compact, rows.response, rows.fields)
1833
1855
  self.model = model
1834
1856
  self.metadata = metadata or {}
@@ -2721,7 +2743,7 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
2721
2743
  """
2722
2744
  yield from self.collect()
2723
2745
 
2724
- def count(self) -> int:
2746
+ def count(self, distinct: bool = None) -> int:
2725
2747
  """
2726
2748
  Return the amount of rows matching the current query.
2727
2749
  """
@@ -2730,25 +2752,27 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
2730
2752
  query = self.query
2731
2753
 
2732
2754
  for key, relation in self.relationships.items():
2733
- if not relation.condition or relation.join != "inner":
2755
+ if (not relation.condition or relation.join != "inner") and not distinct:
2734
2756
  continue
2735
2757
 
2736
2758
  other = relation.get_table(db)
2737
- other = other.with_alias(f"{key}_{hash(relation)}")
2759
+ if not distinct:
2760
+ # todo: can this lead to other issues?
2761
+ other = other.with_alias(f"{key}_{hash(relation)}")
2738
2762
  query &= relation.condition(model, other)
2739
2763
 
2740
- return db(query).count()
2764
+ return db(query).count(distinct)
2741
2765
 
2742
2766
  def __paginate(
2743
2767
  self,
2744
2768
  limit: int,
2745
2769
  page: int = 1,
2746
2770
  ) -> "QueryBuilder[T_MetaInstance]":
2747
- _from = limit * (page - 1)
2748
- _to = limit * page
2749
-
2750
2771
  available = self.count()
2751
2772
 
2773
+ _from = limit * (page - 1)
2774
+ _to = (limit * page) if limit else available
2775
+
2752
2776
  metadata: Metadata = {}
2753
2777
 
2754
2778
  metadata["pagination"] = {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: TypeDAL
3
- Version: 3.8.3
3
+ Version: 3.8.5
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=SarIMCiZlYmiG5KBKqJFOtLclRO1_iDhCaU4inLWXCU,206
1
+ typedal/__about__.py,sha256=bvQs_IhdRXwl5i7SVQ_hGOKt-LVVmnzTgIq29Sdi698,206
2
2
  typedal/__init__.py,sha256=QQpLiVl9w9hm2LBxey49Y_tCF_VB2bScVaS_mCjYy54,366
3
3
  typedal/caching.py,sha256=SMcJsahLlZ79yykWCveERFx1ZJUNEKhA9SPmCTIuLp8,11798
4
4
  typedal/cli.py,sha256=wzyId6YwRyqfuJ2byxvl6YecDNaKpkLmo-R5HvRuTok,19265
5
5
  typedal/config.py,sha256=0qy1zrTUdtmXPM9jHzFnSR1DJsqGJqcdG6pvhzKQHe0,11625
6
- typedal/core.py,sha256=UjaB36QLOor7O7mMpB7ofrr22yqDSER_-5x9Z0kzVDQ,100449
6
+ typedal/core.py,sha256=3puxKj57FvZjR4JUt2926e9eSPnOSaE9hbe2w2M7PyM,101411
7
7
  typedal/fields.py,sha256=A4qt0aK4F_-UeOY-xJ0ObVY-tFEoLFy7TYRMHnp4g6o,6516
8
8
  typedal/for_py4web.py,sha256=d07b8hL_PvNDUS26Z5fDH2OxWb-IETBuAFPSzrRwm04,1285
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=ffo152W-sARYXym4BzwX709rrO2-QwKk2KunWY8RNl4,2229
16
- typedal-3.8.3.dist-info/METADATA,sha256=XZ4R1WYyw0S9yXrFhpF2okaxYPw39BlzHzTrydBadQ4,10463
17
- typedal-3.8.3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
18
- typedal-3.8.3.dist-info/entry_points.txt,sha256=m1wqcc_10rHWPdlQ71zEkmJDADUAnZtn7Jac_6mbyUc,44
19
- typedal-3.8.3.dist-info/RECORD,,
16
+ typedal-3.8.5.dist-info/METADATA,sha256=z0OMhwDSKy8WskcYeYwrLtaGHv7GZzET7qENGoiv4PY,10463
17
+ typedal-3.8.5.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
18
+ typedal-3.8.5.dist-info/entry_points.txt,sha256=m1wqcc_10rHWPdlQ71zEkmJDADUAnZtn7Jac_6mbyUc,44
19
+ typedal-3.8.5.dist-info/RECORD,,