piccolo 1.27.1__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.
- piccolo/__init__.py +1 -1
- piccolo/apps/app/commands/new.py +3 -3
- piccolo/apps/asgi/commands/new.py +1 -2
- piccolo/apps/fixtures/commands/dump.py +8 -8
- piccolo/apps/fixtures/commands/load.py +5 -5
- piccolo/apps/fixtures/commands/shared.py +9 -9
- piccolo/apps/migrations/auto/diffable_table.py +12 -12
- piccolo/apps/migrations/auto/migration_manager.py +59 -66
- piccolo/apps/migrations/auto/operations.py +14 -14
- piccolo/apps/migrations/auto/schema_differ.py +35 -34
- piccolo/apps/migrations/auto/schema_snapshot.py +3 -4
- piccolo/apps/migrations/auto/serialisation.py +27 -24
- piccolo/apps/migrations/auto/serialisation_legacy.py +2 -2
- piccolo/apps/migrations/commands/backwards.py +1 -2
- piccolo/apps/migrations/commands/base.py +12 -12
- piccolo/apps/migrations/commands/check.py +2 -3
- piccolo/apps/migrations/commands/clean.py +3 -3
- piccolo/apps/migrations/commands/forwards.py +1 -2
- piccolo/apps/migrations/commands/new.py +6 -6
- piccolo/apps/migrations/tables.py +3 -3
- piccolo/apps/playground/commands/run.py +29 -13
- piccolo/apps/schema/commands/generate.py +49 -49
- piccolo/apps/schema/commands/graph.py +5 -5
- piccolo/apps/shell/commands/run.py +1 -2
- piccolo/apps/sql_shell/commands/run.py +4 -4
- piccolo/apps/tester/commands/run.py +3 -3
- piccolo/apps/user/commands/change_permissions.py +6 -6
- piccolo/apps/user/commands/create.py +7 -7
- piccolo/apps/user/commands/list.py +2 -2
- piccolo/apps/user/tables.py +8 -8
- piccolo/columns/base.py +84 -52
- piccolo/columns/choices.py +2 -2
- piccolo/columns/column_types.py +297 -175
- piccolo/columns/combination.py +15 -12
- piccolo/columns/defaults/base.py +4 -4
- piccolo/columns/defaults/date.py +4 -3
- piccolo/columns/defaults/interval.py +4 -3
- piccolo/columns/defaults/time.py +4 -3
- piccolo/columns/defaults/timestamp.py +4 -3
- piccolo/columns/defaults/timestamptz.py +4 -3
- piccolo/columns/defaults/uuid.py +3 -2
- piccolo/columns/m2m.py +28 -35
- piccolo/columns/readable.py +4 -3
- piccolo/columns/reference.py +9 -9
- piccolo/conf/apps.py +53 -54
- piccolo/custom_types.py +28 -6
- piccolo/engine/base.py +14 -14
- piccolo/engine/cockroach.py +5 -4
- piccolo/engine/finder.py +2 -2
- piccolo/engine/postgres.py +20 -19
- piccolo/engine/sqlite.py +23 -22
- piccolo/query/base.py +30 -29
- piccolo/query/functions/__init__.py +12 -0
- piccolo/query/functions/aggregate.py +4 -3
- piccolo/query/functions/array.py +151 -0
- piccolo/query/functions/base.py +3 -3
- piccolo/query/functions/datetime.py +22 -22
- piccolo/query/functions/string.py +4 -4
- piccolo/query/functions/type_conversion.py +30 -15
- piccolo/query/methods/alter.py +47 -46
- piccolo/query/methods/count.py +11 -10
- piccolo/query/methods/create.py +6 -5
- piccolo/query/methods/create_index.py +9 -8
- piccolo/query/methods/delete.py +7 -6
- piccolo/query/methods/drop_index.py +7 -6
- piccolo/query/methods/exists.py +6 -5
- piccolo/query/methods/indexes.py +4 -4
- piccolo/query/methods/insert.py +21 -14
- piccolo/query/methods/objects.py +60 -50
- piccolo/query/methods/raw.py +7 -6
- piccolo/query/methods/refresh.py +8 -7
- piccolo/query/methods/select.py +56 -49
- piccolo/query/methods/table_exists.py +5 -5
- piccolo/query/methods/update.py +8 -7
- piccolo/query/mixins.py +56 -61
- piccolo/query/operators/json.py +11 -11
- piccolo/query/proxy.py +8 -9
- piccolo/querystring.py +14 -15
- piccolo/schema.py +10 -10
- piccolo/table.py +93 -94
- piccolo/table_reflection.py +9 -9
- piccolo/testing/model_builder.py +12 -11
- piccolo/testing/random_builder.py +2 -2
- piccolo/testing/test_case.py +4 -4
- piccolo/utils/dictionary.py +3 -3
- piccolo/utils/encoding.py +5 -5
- piccolo/utils/lazy_loader.py +3 -3
- piccolo/utils/list.py +7 -8
- piccolo/utils/objects.py +4 -6
- piccolo/utils/pydantic.py +21 -24
- piccolo/utils/sql_values.py +3 -3
- piccolo/utils/sync.py +4 -3
- piccolo/utils/warnings.py +1 -2
- {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/METADATA +1 -1
- {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/RECORD +122 -121
- tests/apps/fixtures/commands/test_dump_load.py +1 -2
- tests/apps/migrations/auto/integration/test_migrations.py +32 -7
- tests/apps/migrations/auto/test_migration_manager.py +2 -2
- tests/apps/migrations/auto/test_schema_differ.py +22 -23
- tests/apps/migrations/commands/test_forwards_backwards.py +3 -3
- tests/columns/m2m/base.py +2 -2
- tests/columns/test_array.py +176 -10
- tests/columns/test_boolean.py +2 -4
- tests/columns/test_combination.py +29 -1
- tests/columns/test_db_column_name.py +2 -2
- tests/engine/test_extra_nodes.py +2 -2
- tests/engine/test_pool.py +3 -3
- tests/engine/test_transaction.py +4 -4
- tests/query/test_freeze.py +4 -4
- tests/table/instance/test_get_related.py +2 -2
- tests/table/test_alter.py +4 -4
- tests/table/test_indexes.py +1 -2
- tests/table/test_refresh.py +2 -2
- tests/table/test_select.py +58 -0
- tests/table/test_update.py +3 -3
- tests/testing/test_model_builder.py +1 -2
- tests/utils/test_pydantic.py +36 -36
- tests/utils/test_table_reflection.py +1 -2
- {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/WHEEL +0 -0
- {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/entry_points.txt +0 -0
- {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/licenses/LICENSE +0 -0
- {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
from typing import Literal, Optional, Union, get_args
|
2
2
|
|
3
3
|
from piccolo.columns.base import Column
|
4
4
|
from piccolo.columns.column_types import (
|
@@ -15,7 +15,7 @@ from .type_conversion import Cast
|
|
15
15
|
###############################################################################
|
16
16
|
# Postgres / Cockroach
|
17
17
|
|
18
|
-
ExtractComponent =
|
18
|
+
ExtractComponent = Literal[
|
19
19
|
"century",
|
20
20
|
"day",
|
21
21
|
"decade",
|
@@ -44,9 +44,9 @@ ExtractComponent = t.Literal[
|
|
44
44
|
class Extract(QueryString):
|
45
45
|
def __init__(
|
46
46
|
self,
|
47
|
-
identifier:
|
47
|
+
identifier: Union[Date, Time, Timestamp, Timestamptz, QueryString],
|
48
48
|
datetime_component: ExtractComponent,
|
49
|
-
alias:
|
49
|
+
alias: Optional[str] = None,
|
50
50
|
):
|
51
51
|
"""
|
52
52
|
.. note:: This is for Postgres / Cockroach only.
|
@@ -69,7 +69,7 @@ class Extract(QueryString):
|
|
69
69
|
The date or time component to extract from the column.
|
70
70
|
|
71
71
|
"""
|
72
|
-
if datetime_component.lower() not in
|
72
|
+
if datetime_component.lower() not in get_args(ExtractComponent):
|
73
73
|
raise ValueError("The date time component isn't recognised.")
|
74
74
|
|
75
75
|
super().__init__(
|
@@ -86,9 +86,9 @@ class Extract(QueryString):
|
|
86
86
|
class Strftime(QueryString):
|
87
87
|
def __init__(
|
88
88
|
self,
|
89
|
-
identifier:
|
89
|
+
identifier: Union[Date, Time, Timestamp, Timestamptz, QueryString],
|
90
90
|
datetime_format: str,
|
91
|
-
alias:
|
91
|
+
alias: Optional[str] = None,
|
92
92
|
):
|
93
93
|
"""
|
94
94
|
.. note:: This is for SQLite only.
|
@@ -122,7 +122,7 @@ class Strftime(QueryString):
|
|
122
122
|
# Database agnostic
|
123
123
|
|
124
124
|
|
125
|
-
def _get_engine_type(identifier:
|
125
|
+
def _get_engine_type(identifier: Union[Column, QueryString]) -> str:
|
126
126
|
if isinstance(identifier, Column):
|
127
127
|
return identifier._meta.engine_type
|
128
128
|
elif isinstance(identifier, QueryString) and (
|
@@ -134,10 +134,10 @@ def _get_engine_type(identifier: t.Union[Column, QueryString]) -> str:
|
|
134
134
|
|
135
135
|
|
136
136
|
def _extract_component(
|
137
|
-
identifier:
|
137
|
+
identifier: Union[Date, Time, Timestamp, Timestamptz, QueryString],
|
138
138
|
sqlite_format: str,
|
139
139
|
postgres_format: ExtractComponent,
|
140
|
-
alias:
|
140
|
+
alias: Optional[str],
|
141
141
|
) -> QueryString:
|
142
142
|
engine_type = _get_engine_type(identifier=identifier)
|
143
143
|
|
@@ -159,8 +159,8 @@ def _extract_component(
|
|
159
159
|
|
160
160
|
|
161
161
|
def Year(
|
162
|
-
identifier:
|
163
|
-
alias:
|
162
|
+
identifier: Union[Date, Timestamp, Timestamptz, QueryString],
|
163
|
+
alias: Optional[str] = None,
|
164
164
|
) -> QueryString:
|
165
165
|
"""
|
166
166
|
Extract the year as an integer.
|
@@ -174,8 +174,8 @@ def Year(
|
|
174
174
|
|
175
175
|
|
176
176
|
def Month(
|
177
|
-
identifier:
|
178
|
-
alias:
|
177
|
+
identifier: Union[Date, Timestamp, Timestamptz, QueryString],
|
178
|
+
alias: Optional[str] = None,
|
179
179
|
) -> QueryString:
|
180
180
|
"""
|
181
181
|
Extract the month as an integer.
|
@@ -189,8 +189,8 @@ def Month(
|
|
189
189
|
|
190
190
|
|
191
191
|
def Day(
|
192
|
-
identifier:
|
193
|
-
alias:
|
192
|
+
identifier: Union[Date, Timestamp, Timestamptz, QueryString],
|
193
|
+
alias: Optional[str] = None,
|
194
194
|
) -> QueryString:
|
195
195
|
"""
|
196
196
|
Extract the day as an integer.
|
@@ -204,8 +204,8 @@ def Day(
|
|
204
204
|
|
205
205
|
|
206
206
|
def Hour(
|
207
|
-
identifier:
|
208
|
-
alias:
|
207
|
+
identifier: Union[Time, Timestamp, Timestamptz, QueryString],
|
208
|
+
alias: Optional[str] = None,
|
209
209
|
) -> QueryString:
|
210
210
|
"""
|
211
211
|
Extract the hour as an integer.
|
@@ -219,8 +219,8 @@ def Hour(
|
|
219
219
|
|
220
220
|
|
221
221
|
def Minute(
|
222
|
-
identifier:
|
223
|
-
alias:
|
222
|
+
identifier: Union[Time, Timestamp, Timestamptz, QueryString],
|
223
|
+
alias: Optional[str] = None,
|
224
224
|
) -> QueryString:
|
225
225
|
"""
|
226
226
|
Extract the minute as an integer.
|
@@ -234,8 +234,8 @@ def Minute(
|
|
234
234
|
|
235
235
|
|
236
236
|
def Second(
|
237
|
-
identifier:
|
238
|
-
alias:
|
237
|
+
identifier: Union[Time, Timestamp, Timestamptz, QueryString],
|
238
|
+
alias: Optional[str] = None,
|
239
239
|
) -> QueryString:
|
240
240
|
"""
|
241
241
|
Extract the second as an integer.
|
@@ -5,7 +5,7 @@ https://www.postgresql.org/docs/current/functions-string.html
|
|
5
5
|
|
6
6
|
"""
|
7
7
|
|
8
|
-
|
8
|
+
from typing import Optional, Union
|
9
9
|
|
10
10
|
from piccolo.columns.base import Column
|
11
11
|
from piccolo.columns.column_types import Text, Varchar
|
@@ -72,8 +72,8 @@ class Upper(Function):
|
|
72
72
|
class Concat(QueryString):
|
73
73
|
def __init__(
|
74
74
|
self,
|
75
|
-
*args:
|
76
|
-
alias:
|
75
|
+
*args: Union[Column, QueryString, str],
|
76
|
+
alias: Optional[str] = None,
|
77
77
|
):
|
78
78
|
"""
|
79
79
|
Concatenate multiple values into a single string.
|
@@ -91,7 +91,7 @@ class Concat(QueryString):
|
|
91
91
|
|
92
92
|
placeholders = ", ".join("{}" for _ in args)
|
93
93
|
|
94
|
-
processed_args:
|
94
|
+
processed_args: list[Union[QueryString, Column]] = []
|
95
95
|
|
96
96
|
for arg in args:
|
97
97
|
if isinstance(arg, str) or (
|
@@ -1,15 +1,18 @@
|
|
1
|
-
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import Optional, Union
|
2
4
|
|
3
5
|
from piccolo.columns.base import Column
|
6
|
+
from piccolo.custom_types import BasicTypes
|
4
7
|
from piccolo.querystring import QueryString
|
5
8
|
|
6
9
|
|
7
10
|
class Cast(QueryString):
|
8
11
|
def __init__(
|
9
12
|
self,
|
10
|
-
identifier:
|
13
|
+
identifier: Union[Column, QueryString, BasicTypes],
|
11
14
|
as_type: Column,
|
12
|
-
alias:
|
15
|
+
alias: Optional[str] = None,
|
13
16
|
):
|
14
17
|
"""
|
15
18
|
Cast a value to a different type. For example::
|
@@ -17,25 +20,36 @@ class Cast(QueryString):
|
|
17
20
|
>>> from piccolo.query.functions import Cast
|
18
21
|
|
19
22
|
>>> await Concert.select(
|
20
|
-
... Cast(Concert.starts, Time(), "start_time")
|
23
|
+
... Cast(Concert.starts, Time(), alias="start_time")
|
21
24
|
... )
|
22
25
|
[{"start_time": datetime.time(19, 0)}]
|
23
26
|
|
27
|
+
You may also need ``Cast`` to explicitly tell the database which type
|
28
|
+
you're sending in the query (though this is an edge case). Here is a
|
29
|
+
contrived example::
|
30
|
+
|
31
|
+
>>> from piccolo.query.functions.math import Count
|
32
|
+
|
33
|
+
# This fails with asyncpg:
|
34
|
+
>>> await Band.select(Count([1,2,3]))
|
35
|
+
|
36
|
+
If we explicitly specify the type of the array, then it works::
|
37
|
+
|
38
|
+
>>> await Band.select(
|
39
|
+
... Count(
|
40
|
+
... Cast(
|
41
|
+
... [1,2,3],
|
42
|
+
... Array(Integer())
|
43
|
+
... ),
|
44
|
+
... )
|
45
|
+
... )
|
46
|
+
|
24
47
|
:param identifier:
|
25
|
-
Identifies what is being converted (e.g. a column).
|
48
|
+
Identifies what is being converted (e.g. a column, or a raw value).
|
26
49
|
:param as_type:
|
27
50
|
The type to be converted to.
|
28
51
|
|
29
52
|
"""
|
30
|
-
# Make sure the identifier is a supported type.
|
31
|
-
|
32
|
-
if not isinstance(identifier, (Column, QueryString)):
|
33
|
-
raise ValueError(
|
34
|
-
"The identifier is an unsupported type - only Column and "
|
35
|
-
"QueryString instances are allowed."
|
36
|
-
)
|
37
|
-
|
38
|
-
#######################################################################
|
39
53
|
# Convert `as_type` to a string which can be used in the query.
|
40
54
|
|
41
55
|
if not isinstance(as_type, Column):
|
@@ -44,9 +58,10 @@ class Cast(QueryString):
|
|
44
58
|
# We need to give the column a reference to a table, and hence
|
45
59
|
# the database engine, as the column type is sometimes dependent
|
46
60
|
# on which database is being used.
|
61
|
+
|
47
62
|
from piccolo.table import Table, create_table_class
|
48
63
|
|
49
|
-
table:
|
64
|
+
table: Optional[type[Table]] = None
|
50
65
|
|
51
66
|
if isinstance(identifier, Column):
|
52
67
|
table = identifier._meta.table
|
piccolo/query/methods/alter.py
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import itertools
|
4
|
-
|
4
|
+
from collections.abc import Sequence
|
5
5
|
from dataclasses import dataclass
|
6
|
+
from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
|
6
7
|
|
7
8
|
from piccolo.columns.base import Column
|
8
9
|
from piccolo.columns.column_types import ForeignKey, Numeric, Varchar
|
9
10
|
from piccolo.query.base import DDL
|
10
11
|
from piccolo.utils.warnings import Level, colored_warning
|
11
12
|
|
12
|
-
if
|
13
|
+
if TYPE_CHECKING: # pragma: no cover
|
13
14
|
from piccolo.columns.base import OnDelete, OnUpdate
|
14
15
|
from piccolo.table import Table
|
15
16
|
|
@@ -52,7 +53,7 @@ class RenameConstraint(AlterStatement):
|
|
52
53
|
class AlterColumnStatement(AlterStatement):
|
53
54
|
__slots__ = ("column",)
|
54
55
|
|
55
|
-
column:
|
56
|
+
column: Union[Column, str]
|
56
57
|
|
57
58
|
@property
|
58
59
|
def column_name(self) -> str:
|
@@ -114,7 +115,7 @@ class SetColumnType(AlterStatement):
|
|
114
115
|
|
115
116
|
old_column: Column
|
116
117
|
new_column: Column
|
117
|
-
using_expression:
|
118
|
+
using_expression: Optional[str] = None
|
118
119
|
|
119
120
|
@property
|
120
121
|
def ddl(self) -> str:
|
@@ -135,7 +136,7 @@ class SetDefault(AlterColumnStatement):
|
|
135
136
|
__slots__ = ("value",)
|
136
137
|
|
137
138
|
column: Column
|
138
|
-
value:
|
139
|
+
value: Any
|
139
140
|
|
140
141
|
@property
|
141
142
|
def ddl(self) -> str:
|
@@ -215,8 +216,8 @@ class AddForeignKeyConstraint(AlterStatement):
|
|
215
216
|
foreign_key_column_name: str
|
216
217
|
referenced_table_name: str
|
217
218
|
referenced_column_name: str
|
218
|
-
on_delete:
|
219
|
-
on_update:
|
219
|
+
on_delete: Optional[OnDelete]
|
220
|
+
on_update: Optional[OnUpdate]
|
220
221
|
|
221
222
|
@property
|
222
223
|
def ddl(self) -> str:
|
@@ -236,7 +237,7 @@ class AddForeignKeyConstraint(AlterStatement):
|
|
236
237
|
class SetDigits(AlterColumnStatement):
|
237
238
|
__slots__ = ("digits", "column_type")
|
238
239
|
|
239
|
-
digits:
|
240
|
+
digits: Optional[tuple[int, int]]
|
240
241
|
column_type: str
|
241
242
|
|
242
243
|
@property
|
@@ -265,7 +266,7 @@ class SetSchema(AlterStatement):
|
|
265
266
|
|
266
267
|
@dataclass
|
267
268
|
class DropTable:
|
268
|
-
table:
|
269
|
+
table: type[Table]
|
269
270
|
cascade: bool
|
270
271
|
if_exists: bool
|
271
272
|
|
@@ -304,24 +305,24 @@ class Alter(DDL):
|
|
304
305
|
"_rename_constraint",
|
305
306
|
)
|
306
307
|
|
307
|
-
def __init__(self, table:
|
308
|
+
def __init__(self, table: type[Table], **kwargs):
|
308
309
|
super().__init__(table, **kwargs)
|
309
|
-
self._add_foreign_key_constraint:
|
310
|
-
self._add:
|
311
|
-
self._drop_constraint:
|
312
|
-
self._drop_default:
|
313
|
-
self._drop_table:
|
314
|
-
self._drop:
|
315
|
-
self._rename_columns:
|
316
|
-
self._rename_table:
|
317
|
-
self._set_column_type:
|
318
|
-
self._set_default:
|
319
|
-
self._set_digits:
|
320
|
-
self._set_length:
|
321
|
-
self._set_null:
|
322
|
-
self._set_schema:
|
323
|
-
self._set_unique:
|
324
|
-
self._rename_constraint:
|
310
|
+
self._add_foreign_key_constraint: list[AddForeignKeyConstraint] = []
|
311
|
+
self._add: list[AddColumn] = []
|
312
|
+
self._drop_constraint: list[DropConstraint] = []
|
313
|
+
self._drop_default: list[DropDefault] = []
|
314
|
+
self._drop_table: Optional[DropTable] = None
|
315
|
+
self._drop: list[DropColumn] = []
|
316
|
+
self._rename_columns: list[RenameColumn] = []
|
317
|
+
self._rename_table: list[RenameTable] = []
|
318
|
+
self._set_column_type: list[SetColumnType] = []
|
319
|
+
self._set_default: list[SetDefault] = []
|
320
|
+
self._set_digits: list[SetDigits] = []
|
321
|
+
self._set_length: list[SetLength] = []
|
322
|
+
self._set_null: list[SetNull] = []
|
323
|
+
self._set_schema: list[SetSchema] = []
|
324
|
+
self._set_unique: list[SetUnique] = []
|
325
|
+
self._rename_constraint: list[RenameConstraint] = []
|
325
326
|
|
326
327
|
def add_column(self: Self, name: str, column: Column) -> Self:
|
327
328
|
"""
|
@@ -340,7 +341,7 @@ class Alter(DDL):
|
|
340
341
|
self._add.append(AddColumn(column, name))
|
341
342
|
return self
|
342
343
|
|
343
|
-
def drop_column(self, column:
|
344
|
+
def drop_column(self, column: Union[str, Column]) -> Alter:
|
344
345
|
"""
|
345
346
|
Drop a column from the table::
|
346
347
|
|
@@ -350,7 +351,7 @@ class Alter(DDL):
|
|
350
351
|
self._drop.append(DropColumn(column))
|
351
352
|
return self
|
352
353
|
|
353
|
-
def drop_default(self, column:
|
354
|
+
def drop_default(self, column: Union[str, Column]) -> Alter:
|
354
355
|
"""
|
355
356
|
Drop the default from a column::
|
356
357
|
|
@@ -406,7 +407,7 @@ class Alter(DDL):
|
|
406
407
|
return self
|
407
408
|
|
408
409
|
def rename_column(
|
409
|
-
self, column:
|
410
|
+
self, column: Union[str, Column], new_name: str
|
410
411
|
) -> Alter:
|
411
412
|
"""
|
412
413
|
Rename a column on the table::
|
@@ -425,7 +426,7 @@ class Alter(DDL):
|
|
425
426
|
self,
|
426
427
|
old_column: Column,
|
427
428
|
new_column: Column,
|
428
|
-
using_expression:
|
429
|
+
using_expression: Optional[str] = None,
|
429
430
|
) -> Alter:
|
430
431
|
"""
|
431
432
|
Change the type of a column::
|
@@ -448,7 +449,7 @@ class Alter(DDL):
|
|
448
449
|
)
|
449
450
|
return self
|
450
451
|
|
451
|
-
def set_default(self, column: Column, value:
|
452
|
+
def set_default(self, column: Column, value: Any) -> Alter:
|
452
453
|
"""
|
453
454
|
Set the default for a column::
|
454
455
|
|
@@ -459,7 +460,7 @@ class Alter(DDL):
|
|
459
460
|
return self
|
460
461
|
|
461
462
|
def set_null(
|
462
|
-
self, column:
|
463
|
+
self, column: Union[str, Column], boolean: bool = True
|
463
464
|
) -> Alter:
|
464
465
|
"""
|
465
466
|
Change a column to be nullable or not::
|
@@ -475,7 +476,7 @@ class Alter(DDL):
|
|
475
476
|
return self
|
476
477
|
|
477
478
|
def set_unique(
|
478
|
-
self, column:
|
479
|
+
self, column: Union[str, Column], boolean: bool = True
|
479
480
|
) -> Alter:
|
480
481
|
"""
|
481
482
|
Make a column unique or not::
|
@@ -490,7 +491,7 @@ class Alter(DDL):
|
|
490
491
|
self._set_unique.append(SetUnique(column, boolean))
|
491
492
|
return self
|
492
493
|
|
493
|
-
def set_length(self, column:
|
494
|
+
def set_length(self, column: Union[str, Varchar], length: int) -> Alter:
|
494
495
|
"""
|
495
496
|
Change the max length of a varchar column. Unfortunately, this isn't
|
496
497
|
supported by SQLite, but SQLite also doesn't enforce any length limits
|
@@ -518,7 +519,7 @@ class Alter(DDL):
|
|
518
519
|
self._set_length.append(SetLength(column, length))
|
519
520
|
return self
|
520
521
|
|
521
|
-
def _get_constraint_name(self, column:
|
522
|
+
def _get_constraint_name(self, column: Union[str, ForeignKey]) -> str:
|
522
523
|
column_name = AlterColumnStatement(column=column).column_name
|
523
524
|
tablename = self.table._meta.tablename
|
524
525
|
return f"{tablename}_{column_name}_fkey"
|
@@ -530,7 +531,7 @@ class Alter(DDL):
|
|
530
531
|
return self
|
531
532
|
|
532
533
|
def drop_foreign_key_constraint(
|
533
|
-
self, column:
|
534
|
+
self, column: Union[str, ForeignKey]
|
534
535
|
) -> Alter:
|
535
536
|
constraint_name = self._get_constraint_name(column=column)
|
536
537
|
self._drop_constraint.append(
|
@@ -540,12 +541,12 @@ class Alter(DDL):
|
|
540
541
|
|
541
542
|
def add_foreign_key_constraint(
|
542
543
|
self,
|
543
|
-
column:
|
544
|
-
referenced_table_name:
|
545
|
-
referenced_column_name:
|
546
|
-
constraint_name:
|
547
|
-
on_delete:
|
548
|
-
on_update:
|
544
|
+
column: Union[str, ForeignKey],
|
545
|
+
referenced_table_name: Optional[str] = None,
|
546
|
+
referenced_column_name: Optional[str] = None,
|
547
|
+
constraint_name: Optional[str] = None,
|
548
|
+
on_delete: Optional[OnDelete] = None,
|
549
|
+
on_update: Optional[OnUpdate] = None,
|
549
550
|
) -> Alter:
|
550
551
|
"""
|
551
552
|
Add a new foreign key constraint::
|
@@ -591,8 +592,8 @@ class Alter(DDL):
|
|
591
592
|
|
592
593
|
def set_digits(
|
593
594
|
self,
|
594
|
-
column:
|
595
|
-
digits:
|
595
|
+
column: Union[str, Numeric],
|
596
|
+
digits: Optional[tuple[int, int]],
|
596
597
|
) -> Alter:
|
597
598
|
"""
|
598
599
|
Alter the precision and scale for a ``Numeric`` column.
|
@@ -623,7 +624,7 @@ class Alter(DDL):
|
|
623
624
|
return self
|
624
625
|
|
625
626
|
@property
|
626
|
-
def default_ddl(self) ->
|
627
|
+
def default_ddl(self) -> Sequence[str]:
|
627
628
|
if self._drop_table is not None:
|
628
629
|
return [self._drop_table.ddl]
|
629
630
|
|
@@ -660,4 +661,4 @@ class Alter(DDL):
|
|
660
661
|
return [query]
|
661
662
|
|
662
663
|
|
663
|
-
Self =
|
664
|
+
Self = TypeVar("Self", bound=Alter)
|
piccolo/query/methods/count.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
|
3
|
+
from collections.abc import Sequence
|
4
|
+
from typing import TYPE_CHECKING, Optional, TypeVar, Union
|
4
5
|
|
5
6
|
from piccolo.custom_types import Combinable
|
6
7
|
from piccolo.query.base import Query
|
@@ -8,7 +9,7 @@ from piccolo.query.functions.aggregate import Count as CountFunction
|
|
8
9
|
from piccolo.query.mixins import WhereDelegate
|
9
10
|
from piccolo.querystring import QueryString
|
10
11
|
|
11
|
-
if
|
12
|
+
if TYPE_CHECKING: # pragma: no cover
|
12
13
|
from piccolo.columns import Column
|
13
14
|
from piccolo.table import Table
|
14
15
|
|
@@ -19,9 +20,9 @@ class Count(Query):
|
|
19
20
|
|
20
21
|
def __init__(
|
21
22
|
self,
|
22
|
-
table:
|
23
|
-
column:
|
24
|
-
distinct:
|
23
|
+
table: type[Table],
|
24
|
+
column: Optional[Column] = None,
|
25
|
+
distinct: Optional[Sequence[Column]] = None,
|
25
26
|
**kwargs,
|
26
27
|
):
|
27
28
|
super().__init__(table, **kwargs)
|
@@ -32,11 +33,11 @@ class Count(Query):
|
|
32
33
|
###########################################################################
|
33
34
|
# Clauses
|
34
35
|
|
35
|
-
def where(self: Self, *where:
|
36
|
+
def where(self: Self, *where: Union[Combinable, QueryString]) -> Self:
|
36
37
|
self.where_delegate.where(*where)
|
37
38
|
return self
|
38
39
|
|
39
|
-
def distinct(self: Self, columns:
|
40
|
+
def distinct(self: Self, columns: Optional[Sequence[Column]]) -> Self:
|
40
41
|
self._distinct = columns
|
41
42
|
return self
|
42
43
|
|
@@ -46,8 +47,8 @@ class Count(Query):
|
|
46
47
|
return response[0]["count"]
|
47
48
|
|
48
49
|
@property
|
49
|
-
def default_querystrings(self) ->
|
50
|
-
table:
|
50
|
+
def default_querystrings(self) -> Sequence[QueryString]:
|
51
|
+
table: type[Table] = self.table
|
51
52
|
|
52
53
|
query = table.select(
|
53
54
|
CountFunction(column=self.column, distinct=self._distinct)
|
@@ -58,4 +59,4 @@ class Count(Query):
|
|
58
59
|
return query.querystrings
|
59
60
|
|
60
61
|
|
61
|
-
Self =
|
62
|
+
Self = TypeVar("Self", bound=Count)
|
piccolo/query/methods/create.py
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
|
3
|
+
from collections.abc import Sequence
|
4
|
+
from typing import TYPE_CHECKING
|
4
5
|
|
5
6
|
from piccolo.query.base import DDL
|
6
7
|
from piccolo.query.methods.create_index import CreateIndex
|
7
8
|
|
8
|
-
if
|
9
|
+
if TYPE_CHECKING: # pragma: no cover
|
9
10
|
from piccolo.table import Table
|
10
11
|
|
11
12
|
|
@@ -18,7 +19,7 @@ class Create(DDL):
|
|
18
19
|
|
19
20
|
def __init__(
|
20
21
|
self,
|
21
|
-
table:
|
22
|
+
table: type[Table],
|
22
23
|
if_not_exists: bool = False,
|
23
24
|
only_default_columns: bool = False,
|
24
25
|
auto_create_schema: bool = True,
|
@@ -43,8 +44,8 @@ class Create(DDL):
|
|
43
44
|
self.auto_create_schema = auto_create_schema
|
44
45
|
|
45
46
|
@property
|
46
|
-
def default_ddl(self) ->
|
47
|
-
ddl:
|
47
|
+
def default_ddl(self) -> Sequence[str]:
|
48
|
+
ddl: list[str] = []
|
48
49
|
|
49
50
|
schema_name = self.table._meta.schema
|
50
51
|
if (
|
@@ -1,20 +1,21 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
|
3
|
+
from collections.abc import Sequence
|
4
|
+
from typing import TYPE_CHECKING, Union
|
4
5
|
|
5
6
|
from piccolo.columns import Column
|
6
7
|
from piccolo.columns.indexes import IndexMethod
|
7
8
|
from piccolo.query.base import DDL
|
8
9
|
|
9
|
-
if
|
10
|
+
if TYPE_CHECKING: # pragma: no cover
|
10
11
|
from piccolo.table import Table
|
11
12
|
|
12
13
|
|
13
14
|
class CreateIndex(DDL):
|
14
15
|
def __init__(
|
15
16
|
self,
|
16
|
-
table:
|
17
|
-
columns:
|
17
|
+
table: type[Table],
|
18
|
+
columns: Union[list[Column], list[str]],
|
18
19
|
method: IndexMethod = IndexMethod.btree,
|
19
20
|
if_not_exists: bool = False,
|
20
21
|
**kwargs,
|
@@ -25,7 +26,7 @@ class CreateIndex(DDL):
|
|
25
26
|
super().__init__(table, **kwargs)
|
26
27
|
|
27
28
|
@property
|
28
|
-
def column_names(self) ->
|
29
|
+
def column_names(self) -> list[str]:
|
29
30
|
return [
|
30
31
|
i._meta.db_column_name if isinstance(i, Column) else i
|
31
32
|
for i in self.columns
|
@@ -39,7 +40,7 @@ class CreateIndex(DDL):
|
|
39
40
|
return prefix
|
40
41
|
|
41
42
|
@property
|
42
|
-
def postgres_ddl(self) ->
|
43
|
+
def postgres_ddl(self) -> Sequence[str]:
|
43
44
|
column_names = self.column_names
|
44
45
|
index_name = self.table._get_index_name(column_names)
|
45
46
|
tablename = self.table._meta.get_formatted_tablename()
|
@@ -53,11 +54,11 @@ class CreateIndex(DDL):
|
|
53
54
|
]
|
54
55
|
|
55
56
|
@property
|
56
|
-
def cockroach_ddl(self) ->
|
57
|
+
def cockroach_ddl(self) -> Sequence[str]:
|
57
58
|
return self.postgres_ddl
|
58
59
|
|
59
60
|
@property
|
60
|
-
def sqlite_ddl(self) ->
|
61
|
+
def sqlite_ddl(self) -> Sequence[str]:
|
61
62
|
column_names = self.column_names
|
62
63
|
index_name = self.table._get_index_name(column_names)
|
63
64
|
tablename = self.table._meta.get_formatted_tablename()
|
piccolo/query/methods/delete.py
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
|
3
|
+
from collections.abc import Sequence
|
4
|
+
from typing import TYPE_CHECKING, TypeVar, Union
|
4
5
|
|
5
6
|
from piccolo.custom_types import Combinable
|
6
7
|
from piccolo.query.base import Query
|
7
8
|
from piccolo.query.mixins import ReturningDelegate, WhereDelegate
|
8
9
|
from piccolo.querystring import QueryString
|
9
10
|
|
10
|
-
if
|
11
|
+
if TYPE_CHECKING: # pragma: no cover
|
11
12
|
from piccolo.columns import Column
|
12
13
|
from piccolo.table import Table
|
13
14
|
|
@@ -24,13 +25,13 @@ class Delete(Query):
|
|
24
25
|
"where_delegate",
|
25
26
|
)
|
26
27
|
|
27
|
-
def __init__(self, table:
|
28
|
+
def __init__(self, table: type[Table], force: bool = False, **kwargs):
|
28
29
|
super().__init__(table, **kwargs)
|
29
30
|
self.force = force
|
30
31
|
self.returning_delegate = ReturningDelegate()
|
31
32
|
self.where_delegate = WhereDelegate()
|
32
33
|
|
33
|
-
def where(self: Self, *where:
|
34
|
+
def where(self: Self, *where: Union[Combinable, QueryString]) -> Self:
|
34
35
|
self.where_delegate.where(*where)
|
35
36
|
return self
|
36
37
|
|
@@ -52,7 +53,7 @@ class Delete(Query):
|
|
52
53
|
)
|
53
54
|
|
54
55
|
@property
|
55
|
-
def default_querystrings(self) ->
|
56
|
+
def default_querystrings(self) -> Sequence[QueryString]:
|
56
57
|
query = f"DELETE FROM {self.table._meta.get_formatted_tablename()}"
|
57
58
|
|
58
59
|
querystring = QueryString(query)
|
@@ -74,4 +75,4 @@ class Delete(Query):
|
|
74
75
|
return [querystring]
|
75
76
|
|
76
77
|
|
77
|
-
Self =
|
78
|
+
Self = TypeVar("Self", bound=Delete)
|