piccolo 1.27.0__py3-none-any.whl → 1.28.0__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.
Files changed (122) hide show
  1. piccolo/__init__.py +1 -1
  2. piccolo/apps/app/commands/new.py +3 -3
  3. piccolo/apps/asgi/commands/new.py +1 -2
  4. piccolo/apps/fixtures/commands/dump.py +8 -8
  5. piccolo/apps/fixtures/commands/load.py +5 -5
  6. piccolo/apps/fixtures/commands/shared.py +9 -9
  7. piccolo/apps/migrations/auto/diffable_table.py +12 -12
  8. piccolo/apps/migrations/auto/migration_manager.py +59 -66
  9. piccolo/apps/migrations/auto/operations.py +14 -14
  10. piccolo/apps/migrations/auto/schema_differ.py +35 -34
  11. piccolo/apps/migrations/auto/schema_snapshot.py +3 -4
  12. piccolo/apps/migrations/auto/serialisation.py +27 -24
  13. piccolo/apps/migrations/auto/serialisation_legacy.py +2 -2
  14. piccolo/apps/migrations/commands/backwards.py +1 -2
  15. piccolo/apps/migrations/commands/base.py +12 -12
  16. piccolo/apps/migrations/commands/check.py +2 -3
  17. piccolo/apps/migrations/commands/clean.py +3 -3
  18. piccolo/apps/migrations/commands/forwards.py +1 -2
  19. piccolo/apps/migrations/commands/new.py +6 -6
  20. piccolo/apps/migrations/tables.py +3 -3
  21. piccolo/apps/playground/commands/run.py +29 -13
  22. piccolo/apps/schema/commands/generate.py +49 -49
  23. piccolo/apps/schema/commands/graph.py +5 -5
  24. piccolo/apps/shell/commands/run.py +1 -2
  25. piccolo/apps/sql_shell/commands/run.py +4 -4
  26. piccolo/apps/tester/commands/run.py +3 -3
  27. piccolo/apps/user/commands/change_permissions.py +6 -6
  28. piccolo/apps/user/commands/create.py +7 -7
  29. piccolo/apps/user/commands/list.py +2 -2
  30. piccolo/apps/user/tables.py +8 -8
  31. piccolo/columns/base.py +84 -52
  32. piccolo/columns/choices.py +2 -2
  33. piccolo/columns/column_types.py +297 -175
  34. piccolo/columns/combination.py +15 -12
  35. piccolo/columns/defaults/base.py +4 -4
  36. piccolo/columns/defaults/date.py +4 -3
  37. piccolo/columns/defaults/interval.py +4 -3
  38. piccolo/columns/defaults/time.py +4 -3
  39. piccolo/columns/defaults/timestamp.py +4 -3
  40. piccolo/columns/defaults/timestamptz.py +4 -3
  41. piccolo/columns/defaults/uuid.py +3 -2
  42. piccolo/columns/m2m.py +28 -35
  43. piccolo/columns/readable.py +4 -3
  44. piccolo/columns/reference.py +9 -9
  45. piccolo/conf/apps.py +53 -54
  46. piccolo/custom_types.py +28 -6
  47. piccolo/engine/base.py +14 -14
  48. piccolo/engine/cockroach.py +5 -4
  49. piccolo/engine/finder.py +2 -2
  50. piccolo/engine/postgres.py +20 -19
  51. piccolo/engine/sqlite.py +23 -22
  52. piccolo/query/base.py +30 -29
  53. piccolo/query/functions/__init__.py +12 -0
  54. piccolo/query/functions/aggregate.py +4 -3
  55. piccolo/query/functions/array.py +151 -0
  56. piccolo/query/functions/base.py +3 -3
  57. piccolo/query/functions/datetime.py +22 -22
  58. piccolo/query/functions/string.py +4 -4
  59. piccolo/query/functions/type_conversion.py +30 -15
  60. piccolo/query/methods/alter.py +47 -46
  61. piccolo/query/methods/count.py +11 -10
  62. piccolo/query/methods/create.py +6 -5
  63. piccolo/query/methods/create_index.py +9 -8
  64. piccolo/query/methods/delete.py +7 -6
  65. piccolo/query/methods/drop_index.py +7 -6
  66. piccolo/query/methods/exists.py +6 -5
  67. piccolo/query/methods/indexes.py +4 -4
  68. piccolo/query/methods/insert.py +21 -14
  69. piccolo/query/methods/objects.py +60 -50
  70. piccolo/query/methods/raw.py +7 -6
  71. piccolo/query/methods/refresh.py +8 -7
  72. piccolo/query/methods/select.py +56 -49
  73. piccolo/query/methods/table_exists.py +5 -5
  74. piccolo/query/methods/update.py +8 -7
  75. piccolo/query/mixins.py +56 -61
  76. piccolo/query/operators/json.py +11 -11
  77. piccolo/query/proxy.py +8 -9
  78. piccolo/querystring.py +14 -15
  79. piccolo/schema.py +10 -10
  80. piccolo/table.py +93 -94
  81. piccolo/table_reflection.py +9 -9
  82. piccolo/testing/model_builder.py +12 -11
  83. piccolo/testing/random_builder.py +2 -2
  84. piccolo/testing/test_case.py +4 -4
  85. piccolo/utils/dictionary.py +3 -3
  86. piccolo/utils/encoding.py +5 -5
  87. piccolo/utils/lazy_loader.py +3 -3
  88. piccolo/utils/list.py +7 -8
  89. piccolo/utils/objects.py +4 -6
  90. piccolo/utils/pydantic.py +21 -24
  91. piccolo/utils/sql_values.py +3 -3
  92. piccolo/utils/sync.py +4 -3
  93. piccolo/utils/warnings.py +1 -2
  94. {piccolo-1.27.0.dist-info → piccolo-1.28.0.dist-info}/METADATA +1 -1
  95. {piccolo-1.27.0.dist-info → piccolo-1.28.0.dist-info}/RECORD +122 -121
  96. tests/apps/fixtures/commands/test_dump_load.py +1 -2
  97. tests/apps/migrations/auto/integration/test_migrations.py +32 -7
  98. tests/apps/migrations/auto/test_migration_manager.py +2 -2
  99. tests/apps/migrations/auto/test_schema_differ.py +22 -23
  100. tests/apps/migrations/commands/test_forwards_backwards.py +3 -3
  101. tests/columns/m2m/base.py +2 -2
  102. tests/columns/test_array.py +176 -10
  103. tests/columns/test_boolean.py +2 -4
  104. tests/columns/test_combination.py +29 -1
  105. tests/columns/test_db_column_name.py +2 -2
  106. tests/engine/test_extra_nodes.py +2 -2
  107. tests/engine/test_pool.py +3 -3
  108. tests/engine/test_transaction.py +4 -4
  109. tests/query/test_freeze.py +4 -4
  110. tests/table/instance/test_get_related.py +2 -2
  111. tests/table/test_alter.py +4 -4
  112. tests/table/test_indexes.py +1 -2
  113. tests/table/test_refresh.py +2 -2
  114. tests/table/test_select.py +58 -0
  115. tests/table/test_update.py +3 -3
  116. tests/testing/test_model_builder.py +1 -2
  117. tests/utils/test_pydantic.py +36 -36
  118. tests/utils/test_table_reflection.py +1 -2
  119. {piccolo-1.27.0.dist-info → piccolo-1.28.0.dist-info}/WHEEL +0 -0
  120. {piccolo-1.27.0.dist-info → piccolo-1.28.0.dist-info}/entry_points.txt +0 -0
  121. {piccolo-1.27.0.dist-info → piccolo-1.28.0.dist-info}/licenses/LICENSE +0 -0
  122. {piccolo-1.27.0.dist-info → piccolo-1.28.0.dist-info}/top_level.txt +0 -0
@@ -1,17 +1,17 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing as t
3
+ from typing import TYPE_CHECKING, Any, Union
4
4
 
5
5
  from piccolo.columns.operators.comparison import (
6
6
  ComparisonOperator,
7
7
  Equal,
8
8
  IsNull,
9
9
  )
10
- from piccolo.custom_types import Combinable, Iterable
10
+ from piccolo.custom_types import Combinable, CustomIterable
11
11
  from piccolo.querystring import QueryString
12
12
  from piccolo.utils.sql_values import convert_to_sql_value
13
13
 
14
- if t.TYPE_CHECKING:
14
+ if TYPE_CHECKING:
15
15
  from piccolo.columns.base import Column
16
16
 
17
17
 
@@ -59,7 +59,7 @@ class Combination(CombinableMixin):
59
59
  class And(Combination):
60
60
  operator = "AND"
61
61
 
62
- def get_column_values(self) -> t.Dict[Column, t.Any]:
62
+ def get_column_values(self) -> dict[Column, Any]:
63
63
  """
64
64
  This is used by `get_or_create` to know which values to assign if
65
65
  the row doesn't exist in the database.
@@ -109,7 +109,7 @@ UNDEFINED = Undefined()
109
109
  class WhereRaw(CombinableMixin):
110
110
  __slots__ = ("querystring",)
111
111
 
112
- def __init__(self, sql: str, *args: t.Any) -> None:
112
+ def __init__(self, sql: str, *args: Any) -> None:
113
113
  """
114
114
  Execute raw SQL queries in your where clause. Use with caution!
115
115
 
@@ -145,9 +145,9 @@ class Where(CombinableMixin):
145
145
  def __init__(
146
146
  self,
147
147
  column: Column,
148
- value: t.Any = UNDEFINED,
149
- values: t.Union[Iterable, Undefined] = UNDEFINED,
150
- operator: t.Type[ComparisonOperator] = ComparisonOperator,
148
+ value: Any = UNDEFINED,
149
+ values: Union[CustomIterable, Undefined, QueryString] = UNDEFINED,
150
+ operator: type[ComparisonOperator] = ComparisonOperator,
151
151
  ) -> None:
152
152
  """
153
153
  We use the UNDEFINED value to show the value was deliberately
@@ -156,14 +156,14 @@ class Where(CombinableMixin):
156
156
  self.column = column
157
157
 
158
158
  self.value = value if value == UNDEFINED else self.clean_value(value)
159
- if values == UNDEFINED:
159
+ if (values == UNDEFINED) or isinstance(values, QueryString):
160
160
  self.values = values
161
161
  else:
162
162
  self.values = [self.clean_value(i) for i in values] # type: ignore
163
163
 
164
164
  self.operator = operator
165
165
 
166
- def clean_value(self, value: t.Any) -> t.Any:
166
+ def clean_value(self, value: Any) -> Any:
167
167
  """
168
168
  If a where clause contains a ``Table`` instance, we should convert that
169
169
  to a column reference. For example:
@@ -192,6 +192,9 @@ class Where(CombinableMixin):
192
192
  def values_querystring(self) -> QueryString:
193
193
  values = self.values
194
194
 
195
+ if isinstance(values, QueryString):
196
+ return values
197
+
195
198
  if isinstance(values, Undefined):
196
199
  raise ValueError("values is undefined")
197
200
 
@@ -200,7 +203,7 @@ class Where(CombinableMixin):
200
203
 
201
204
  @property
202
205
  def querystring(self) -> QueryString:
203
- args: t.List[t.Any] = []
206
+ args: list[Any] = []
204
207
  if self.value != UNDEFINED:
205
208
  args.append(self.value)
206
209
 
@@ -219,7 +222,7 @@ class Where(CombinableMixin):
219
222
 
220
223
  @property
221
224
  def querystring_for_update_and_delete(self) -> QueryString:
222
- args: t.List[t.Any] = []
225
+ args: list[Any] = []
223
226
  if self.value != UNDEFINED:
224
227
  args.append(self.value)
225
228
 
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing as t
4
3
  from abc import ABC, abstractmethod
4
+ from typing import Any
5
5
 
6
6
  from piccolo.utils.repr import repr_class_instance
7
7
 
@@ -18,10 +18,10 @@ class Default(ABC):
18
18
  pass
19
19
 
20
20
  @abstractmethod
21
- def python(self) -> t.Any:
21
+ def python(self) -> Any:
22
22
  pass
23
23
 
24
- def get_postgres_interval_string(self, attributes: t.List[str]) -> str:
24
+ def get_postgres_interval_string(self, attributes: list[str]) -> str:
25
25
  """
26
26
  Returns a string usable as an interval argument in Postgres e.g.
27
27
  "1 day 2 hour".
@@ -39,7 +39,7 @@ class Default(ABC):
39
39
 
40
40
  return " ".join(interval_components)
41
41
 
42
- def get_sqlite_interval_string(self, attributes: t.List[str]) -> str:
42
+ def get_sqlite_interval_string(self, attributes: list[str]) -> str:
43
43
  """
44
44
  Returns a string usable as an interval argument in SQLite e.g.
45
45
  "'-2 hours', '1 days'".
@@ -1,8 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import datetime
4
- import typing as t
4
+ from collections.abc import Callable
5
5
  from enum import Enum
6
+ from typing import Union
6
7
 
7
8
  from .base import Default
8
9
 
@@ -102,14 +103,14 @@ class DateCustom(Default):
102
103
 
103
104
 
104
105
  # Might add an enum back which encapsulates all of the options.
105
- DateArg = t.Union[
106
+ DateArg = Union[
106
107
  DateOffset,
107
108
  DateCustom,
108
109
  DateNow,
109
110
  Enum,
110
111
  None,
111
112
  datetime.date,
112
- t.Callable[[], datetime.date],
113
+ Callable[[], datetime.date],
113
114
  ]
114
115
 
115
116
 
@@ -1,8 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import datetime
4
- import typing as t
4
+ from collections.abc import Callable
5
5
  from enum import Enum
6
+ from typing import Union
6
7
 
7
8
  from .base import Default
8
9
 
@@ -75,12 +76,12 @@ class IntervalCustom(Default):
75
76
 
76
77
  ###############################################################################
77
78
 
78
- IntervalArg = t.Union[
79
+ IntervalArg = Union[
79
80
  IntervalCustom,
80
81
  Enum,
81
82
  None,
82
83
  datetime.timedelta,
83
- t.Callable[[], datetime.timedelta],
84
+ Callable[[], datetime.timedelta],
84
85
  ]
85
86
 
86
87
 
@@ -1,8 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import datetime
4
- import typing as t
4
+ from collections.abc import Callable
5
5
  from enum import Enum
6
+ from typing import Union
6
7
 
7
8
  from .base import Default
8
9
 
@@ -89,14 +90,14 @@ class TimeCustom(Default):
89
90
  )
90
91
 
91
92
 
92
- TimeArg = t.Union[
93
+ TimeArg = Union[
93
94
  TimeCustom,
94
95
  TimeNow,
95
96
  TimeOffset,
96
97
  Enum,
97
98
  None,
98
99
  datetime.time,
99
- t.Callable[[], datetime.time],
100
+ Callable[[], datetime.time],
100
101
  ]
101
102
 
102
103
 
@@ -1,8 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import datetime
4
- import typing as t
4
+ from collections.abc import Callable
5
5
  from enum import Enum
6
+ from typing import Union
6
7
 
7
8
  from .base import Default
8
9
 
@@ -134,7 +135,7 @@ class DatetimeDefault:
134
135
 
135
136
  ###############################################################################
136
137
 
137
- TimestampArg = t.Union[
138
+ TimestampArg = Union[
138
139
  TimestampCustom,
139
140
  TimestampNow,
140
141
  TimestampOffset,
@@ -142,7 +143,7 @@ TimestampArg = t.Union[
142
143
  None,
143
144
  datetime.datetime,
144
145
  DatetimeDefault,
145
- t.Callable[[], datetime.datetime],
146
+ Callable[[], datetime.datetime],
146
147
  ]
147
148
 
148
149
 
@@ -1,8 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import datetime
4
- import typing as t
4
+ from collections.abc import Callable
5
5
  from enum import Enum
6
+ from typing import Union
6
7
 
7
8
  from .timestamp import TimestampCustom, TimestampNow, TimestampOffset
8
9
 
@@ -68,14 +69,14 @@ class TimestamptzCustom(TimestampCustom):
68
69
  )
69
70
 
70
71
 
71
- TimestamptzArg = t.Union[
72
+ TimestamptzArg = Union[
72
73
  TimestamptzCustom,
73
74
  TimestamptzNow,
74
75
  TimestamptzOffset,
75
76
  Enum,
76
77
  None,
77
78
  datetime.datetime,
78
- t.Callable[[], datetime.datetime],
79
+ Callable[[], datetime.datetime],
79
80
  ]
80
81
 
81
82
 
@@ -1,6 +1,7 @@
1
- import typing as t
2
1
  import uuid
2
+ from collections.abc import Callable
3
3
  from enum import Enum
4
+ from typing import Union
4
5
 
5
6
  from .base import Default
6
7
 
@@ -22,7 +23,7 @@ class UUID4(Default):
22
23
  return uuid.uuid4()
23
24
 
24
25
 
25
- UUIDArg = t.Union[UUID4, uuid.UUID, str, Enum, None, t.Callable[[], uuid.UUID]]
26
+ UUIDArg = Union[UUID4, uuid.UUID, str, Enum, None, Callable[[], uuid.UUID]]
26
27
 
27
28
 
28
29
  __all__ = ["UUIDArg", "UUID4"]
piccolo/columns/m2m.py CHANGED
@@ -1,8 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import inspect
4
- import typing as t
4
+ from collections.abc import Sequence
5
5
  from dataclasses import dataclass
6
+ from typing import TYPE_CHECKING, Any, Optional, Union
6
7
 
7
8
  from piccolo.columns.column_types import (
8
9
  JSON,
@@ -15,7 +16,7 @@ from piccolo.querystring import QueryString, Selectable
15
16
  from piccolo.utils.list import flatten
16
17
  from piccolo.utils.sync import run_sync
17
18
 
18
- if t.TYPE_CHECKING:
19
+ if TYPE_CHECKING: # pragma: no cover
19
20
  from piccolo.table import Table
20
21
 
21
22
 
@@ -151,12 +152,12 @@ class M2MSelect(Selectable):
151
152
 
152
153
  @dataclass
153
154
  class M2MMeta:
154
- joining_table: t.Union[t.Type[Table], LazyTableReference]
155
- _foreign_key_columns: t.Optional[t.List[ForeignKey]] = None
155
+ joining_table: Union[type[Table], LazyTableReference]
156
+ _foreign_key_columns: Optional[list[ForeignKey]] = None
156
157
 
157
158
  # Set by the Table Metaclass:
158
- _name: t.Optional[str] = None
159
- _table: t.Optional[t.Type[Table]] = None
159
+ _name: Optional[str] = None
160
+ _table: Optional[type[Table]] = None
160
161
 
161
162
  @property
162
163
  def name(self) -> str:
@@ -167,7 +168,7 @@ class M2MMeta:
167
168
  return self._name
168
169
 
169
170
  @property
170
- def table(self) -> t.Type[Table]:
171
+ def table(self) -> type[Table]:
171
172
  if not self._table:
172
173
  raise ValueError(
173
174
  "`_table` isn't defined - the Table Metaclass should set it."
@@ -175,7 +176,7 @@ class M2MMeta:
175
176
  return self._table
176
177
 
177
178
  @property
178
- def resolved_joining_table(self) -> t.Type[Table]:
179
+ def resolved_joining_table(self) -> type[Table]:
179
180
  """
180
181
  Evaluates the ``joining_table`` attribute if it's a
181
182
  ``LazyTableReference``, raising a ``ValueError`` if it fails, otherwise
@@ -196,7 +197,7 @@ class M2MMeta:
196
197
  )
197
198
 
198
199
  @property
199
- def foreign_key_columns(self) -> t.List[ForeignKey]:
200
+ def foreign_key_columns(self) -> list[ForeignKey]:
200
201
  if not self._foreign_key_columns:
201
202
  self._foreign_key_columns = (
202
203
  self.resolved_joining_table._meta.foreign_key_columns[:2]
@@ -236,7 +237,7 @@ class M2MMeta:
236
237
  raise ValueError("No matching foreign key column found!")
237
238
 
238
239
  @property
239
- def primary_table(self) -> t.Type[Table]:
240
+ def primary_table(self) -> type[Table]:
240
241
  return self.primary_foreign_key._foreign_key_meta.resolved_references
241
242
 
242
243
  @property
@@ -251,7 +252,7 @@ class M2MMeta:
251
252
  raise ValueError("No matching foreign key column found!")
252
253
 
253
254
  @property
254
- def secondary_table(self) -> t.Type[Table]:
255
+ def secondary_table(self) -> type[Table]:
255
256
  return self.secondary_foreign_key._foreign_key_meta.resolved_references
256
257
 
257
258
 
@@ -259,11 +260,11 @@ class M2MMeta:
259
260
  class M2MAddRelated:
260
261
  target_row: Table
261
262
  m2m: M2M
262
- rows: t.Sequence[Table]
263
- extra_column_values: t.Dict[t.Union[Column, str], t.Any]
263
+ rows: Sequence[Table]
264
+ extra_column_values: dict[Union[Column, str], Any]
264
265
 
265
266
  @property
266
- def resolved_extra_column_values(self) -> t.Dict[str, t.Any]:
267
+ def resolved_extra_column_values(self) -> dict[str, Any]:
267
268
  return {
268
269
  i._meta.name if isinstance(i, Column) else i: j
269
270
  for i, j in self.extra_column_values.items()
@@ -327,7 +328,7 @@ class M2MAddRelated:
327
328
  class M2MRemoveRelated:
328
329
  target_row: Table
329
330
  m2m: M2M
330
- rows: t.Sequence[Table]
331
+ rows: Sequence[Table]
331
332
 
332
333
  async def run(self):
333
334
  fk = self.m2m._meta.secondary_foreign_key
@@ -372,24 +373,16 @@ class M2MGetRelated:
372
373
 
373
374
  secondary_table = self.m2m._meta.secondary_table
374
375
 
375
- # TODO - replace this with a subquery in the future.
376
- ids = (
377
- await joining_table.select(
378
- getattr(
379
- self.m2m._meta.secondary_foreign_key,
380
- secondary_table._meta.primary_key._meta.name,
381
- )
382
- )
383
- .where(self.m2m._meta.primary_foreign_key == self.row)
384
- .output(as_list=True)
385
- )
386
-
387
- results = (
388
- await secondary_table.objects().where(
389
- secondary_table._meta.primary_key.is_in(ids)
376
+ # use a subquery to make only one db query
377
+ results = await secondary_table.objects().where(
378
+ secondary_table._meta.primary_key.is_in(
379
+ joining_table.select(
380
+ getattr(
381
+ self.m2m._meta.secondary_foreign_key,
382
+ secondary_table._meta.primary_key._meta.name,
383
+ )
384
+ ).where(self.m2m._meta.primary_foreign_key == self.row)
390
385
  )
391
- if len(ids) > 0
392
- else []
393
386
  )
394
387
 
395
388
  return results
@@ -404,8 +397,8 @@ class M2MGetRelated:
404
397
  class M2M:
405
398
  def __init__(
406
399
  self,
407
- joining_table: t.Union[t.Type[Table], LazyTableReference],
408
- foreign_key_columns: t.Optional[t.List[ForeignKey]] = None,
400
+ joining_table: Union[type[Table], LazyTableReference],
401
+ foreign_key_columns: Optional[list[ForeignKey]] = None,
409
402
  ):
410
403
  """
411
404
  :param joining_table:
@@ -428,7 +421,7 @@ class M2M:
428
421
 
429
422
  def __call__(
430
423
  self,
431
- *columns: t.Union[Column, t.List[Column]],
424
+ *columns: Union[Column, list[Column]],
432
425
  as_list: bool = False,
433
426
  load_json: bool = False,
434
427
  ) -> M2MSelect:
@@ -1,11 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing as t
3
+ from collections.abc import Sequence
4
4
  from dataclasses import dataclass
5
+ from typing import TYPE_CHECKING
5
6
 
6
7
  from piccolo.querystring import QueryString, Selectable
7
8
 
8
- if t.TYPE_CHECKING: # pragma: no cover
9
+ if TYPE_CHECKING: # pragma: no cover
9
10
  from piccolo.columns.base import Column
10
11
 
11
12
 
@@ -18,7 +19,7 @@ class Readable(Selectable):
18
19
  """
19
20
 
20
21
  template: str
21
- columns: t.Sequence[Column]
22
+ columns: Sequence[Column]
22
23
  output_name: str = "readable"
23
24
 
24
25
  @property
@@ -6,10 +6,10 @@ from __future__ import annotations
6
6
 
7
7
  import importlib
8
8
  import inspect
9
- import typing as t
10
9
  from dataclasses import dataclass, field
10
+ from typing import TYPE_CHECKING, Optional
11
11
 
12
- if t.TYPE_CHECKING: # pragma: no cover
12
+ if TYPE_CHECKING: # pragma: no cover
13
13
  from piccolo.columns.column_types import ForeignKey
14
14
  from piccolo.table import Table
15
15
 
@@ -36,8 +36,8 @@ class LazyTableReference:
36
36
  """
37
37
 
38
38
  table_class_name: str
39
- app_name: t.Optional[str] = None
40
- module_path: t.Optional[str] = None
39
+ app_name: Optional[str] = None
40
+ module_path: Optional[str] = None
41
41
 
42
42
  def __post_init__(self):
43
43
  if self.app_name is None and self.module_path is None:
@@ -49,7 +49,7 @@ class LazyTableReference:
49
49
  "Specify either app_name or module_path - not both."
50
50
  )
51
51
 
52
- def resolve(self) -> t.Type[Table]:
52
+ def resolve(self) -> type[Table]:
53
53
  if self.app_name is not None:
54
54
  from piccolo.conf.apps import Finder
55
55
 
@@ -60,7 +60,7 @@ class LazyTableReference:
60
60
 
61
61
  if self.module_path:
62
62
  module = importlib.import_module(self.module_path)
63
- table: t.Optional[t.Type[Table]] = getattr(
63
+ table: Optional[type[Table]] = getattr(
64
64
  module, self.table_class_name, None
65
65
  )
66
66
 
@@ -91,9 +91,9 @@ class LazyTableReference:
91
91
 
92
92
  @dataclass
93
93
  class LazyColumnReferenceStore:
94
- foreign_key_columns: t.List[ForeignKey] = field(default_factory=list)
94
+ foreign_key_columns: list[ForeignKey] = field(default_factory=list)
95
95
 
96
- def for_table(self, table: t.Type[Table]) -> t.List[ForeignKey]:
96
+ def for_table(self, table: type[Table]) -> list[ForeignKey]:
97
97
  return [
98
98
  i
99
99
  for i in self.foreign_key_columns
@@ -101,7 +101,7 @@ class LazyColumnReferenceStore:
101
101
  and i._foreign_key_meta.references.resolve() is table
102
102
  ]
103
103
 
104
- def for_tablename(self, tablename: str) -> t.List[ForeignKey]:
104
+ def for_tablename(self, tablename: str) -> list[ForeignKey]:
105
105
  return [
106
106
  i
107
107
  for i in self.foreign_key_columns