plain.models 0.49.2__py3-none-any.whl → 0.50.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.
- plain/models/CHANGELOG.md +13 -0
- plain/models/aggregates.py +42 -19
- plain/models/backends/base/base.py +125 -105
- plain/models/backends/base/client.py +11 -3
- plain/models/backends/base/creation.py +22 -12
- plain/models/backends/base/features.py +10 -4
- plain/models/backends/base/introspection.py +29 -16
- plain/models/backends/base/operations.py +187 -91
- plain/models/backends/base/schema.py +267 -165
- plain/models/backends/base/validation.py +12 -3
- plain/models/backends/ddl_references.py +85 -43
- plain/models/backends/mysql/base.py +29 -26
- plain/models/backends/mysql/client.py +7 -2
- plain/models/backends/mysql/compiler.py +12 -3
- plain/models/backends/mysql/creation.py +5 -2
- plain/models/backends/mysql/features.py +24 -22
- plain/models/backends/mysql/introspection.py +22 -13
- plain/models/backends/mysql/operations.py +106 -39
- plain/models/backends/mysql/schema.py +48 -24
- plain/models/backends/mysql/validation.py +13 -6
- plain/models/backends/postgresql/base.py +41 -34
- plain/models/backends/postgresql/client.py +7 -2
- plain/models/backends/postgresql/creation.py +10 -5
- plain/models/backends/postgresql/introspection.py +15 -8
- plain/models/backends/postgresql/operations.py +109 -42
- plain/models/backends/postgresql/schema.py +85 -46
- plain/models/backends/sqlite3/_functions.py +151 -115
- plain/models/backends/sqlite3/base.py +37 -23
- plain/models/backends/sqlite3/client.py +7 -1
- plain/models/backends/sqlite3/creation.py +9 -5
- plain/models/backends/sqlite3/features.py +5 -3
- plain/models/backends/sqlite3/introspection.py +32 -16
- plain/models/backends/sqlite3/operations.py +125 -42
- plain/models/backends/sqlite3/schema.py +82 -58
- plain/models/backends/utils.py +52 -29
- plain/models/backups/cli.py +8 -6
- plain/models/backups/clients.py +16 -7
- plain/models/backups/core.py +24 -13
- plain/models/base.py +113 -74
- plain/models/cli.py +94 -63
- plain/models/config.py +1 -1
- plain/models/connections.py +23 -7
- plain/models/constraints.py +65 -47
- plain/models/database_url.py +1 -1
- plain/models/db.py +6 -2
- plain/models/deletion.py +66 -43
- plain/models/entrypoints.py +1 -1
- plain/models/enums.py +22 -11
- plain/models/exceptions.py +23 -8
- plain/models/expressions.py +440 -257
- plain/models/fields/__init__.py +253 -202
- plain/models/fields/json.py +120 -54
- plain/models/fields/mixins.py +12 -8
- plain/models/fields/related.py +284 -252
- plain/models/fields/related_descriptors.py +31 -22
- plain/models/fields/related_lookups.py +23 -11
- plain/models/fields/related_managers.py +81 -47
- plain/models/fields/reverse_related.py +58 -55
- plain/models/forms.py +89 -63
- plain/models/functions/comparison.py +71 -18
- plain/models/functions/datetime.py +79 -29
- plain/models/functions/math.py +43 -10
- plain/models/functions/mixins.py +24 -7
- plain/models/functions/text.py +104 -25
- plain/models/functions/window.py +12 -6
- plain/models/indexes.py +52 -28
- plain/models/lookups.py +228 -153
- plain/models/migrations/autodetector.py +86 -43
- plain/models/migrations/exceptions.py +7 -3
- plain/models/migrations/executor.py +33 -7
- plain/models/migrations/graph.py +79 -50
- plain/models/migrations/loader.py +45 -22
- plain/models/migrations/migration.py +23 -18
- plain/models/migrations/operations/base.py +37 -19
- plain/models/migrations/operations/fields.py +89 -42
- plain/models/migrations/operations/models.py +245 -143
- plain/models/migrations/operations/special.py +82 -25
- plain/models/migrations/optimizer.py +7 -2
- plain/models/migrations/questioner.py +58 -31
- plain/models/migrations/recorder.py +18 -11
- plain/models/migrations/serializer.py +50 -39
- plain/models/migrations/state.py +220 -133
- plain/models/migrations/utils.py +29 -13
- plain/models/migrations/writer.py +17 -14
- plain/models/options.py +63 -56
- plain/models/otel.py +16 -6
- plain/models/preflight.py +35 -12
- plain/models/query.py +323 -228
- plain/models/query_utils.py +93 -58
- plain/models/registry.py +34 -16
- plain/models/sql/compiler.py +146 -97
- plain/models/sql/datastructures.py +38 -25
- plain/models/sql/query.py +255 -169
- plain/models/sql/subqueries.py +32 -21
- plain/models/sql/where.py +54 -29
- plain/models/test/pytest.py +15 -11
- plain/models/test/utils.py +4 -2
- plain/models/transaction.py +20 -7
- plain/models/utils.py +13 -5
- {plain_models-0.49.2.dist-info → plain_models-0.50.0.dist-info}/METADATA +1 -1
- plain_models-0.50.0.dist-info/RECORD +122 -0
- plain_models-0.49.2.dist-info/RECORD +0 -122
- {plain_models-0.49.2.dist-info → plain_models-0.50.0.dist-info}/WHEEL +0 -0
- {plain_models-0.49.2.dist-info → plain_models-0.50.0.dist-info}/entry_points.txt +0 -0
- {plain_models-0.49.2.dist-info → plain_models-0.50.0.dist-info}/licenses/LICENSE +0 -0
@@ -3,9 +3,18 @@ Useful auxiliary data structures for query construction. Not useful outside
|
|
3
3
|
the SQL domain.
|
4
4
|
"""
|
5
5
|
|
6
|
+
from __future__ import annotations
|
7
|
+
|
8
|
+
from typing import TYPE_CHECKING, Any
|
9
|
+
|
6
10
|
from plain.models.exceptions import FullResultSet
|
7
11
|
from plain.models.sql.constants import INNER, LOUTER
|
8
12
|
|
13
|
+
if TYPE_CHECKING:
|
14
|
+
from plain.models.backends.base.base import BaseDatabaseWrapper
|
15
|
+
from plain.models.fields import Field
|
16
|
+
from plain.models.sql.compiler import SQLCompiler
|
17
|
+
|
9
18
|
|
10
19
|
class MultiJoin(Exception):
|
11
20
|
"""
|
@@ -14,7 +23,7 @@ class MultiJoin(Exception):
|
|
14
23
|
exceptionally).
|
15
24
|
"""
|
16
25
|
|
17
|
-
def __init__(self, names_pos, path_with_names):
|
26
|
+
def __init__(self, names_pos: int, path_with_names: list[str]) -> None:
|
18
27
|
self.level = names_pos
|
19
28
|
# The path travelled, this includes the path to the multijoin.
|
20
29
|
self.names_with_path = path_with_names
|
@@ -45,14 +54,14 @@ class Join:
|
|
45
54
|
|
46
55
|
def __init__(
|
47
56
|
self,
|
48
|
-
table_name,
|
49
|
-
parent_alias,
|
50
|
-
table_alias,
|
51
|
-
join_type,
|
52
|
-
join_field,
|
53
|
-
nullable,
|
54
|
-
filtered_relation=None,
|
55
|
-
):
|
57
|
+
table_name: str,
|
58
|
+
parent_alias: str,
|
59
|
+
table_alias: str,
|
60
|
+
join_type: str,
|
61
|
+
join_field: Field,
|
62
|
+
nullable: bool,
|
63
|
+
filtered_relation: Any = None,
|
64
|
+
) -> None:
|
56
65
|
# Join table
|
57
66
|
self.table_name = table_name
|
58
67
|
self.parent_alias = parent_alias
|
@@ -62,14 +71,16 @@ class Join:
|
|
62
71
|
self.join_type = join_type
|
63
72
|
# A list of 2-tuples to use in the ON clause of the JOIN.
|
64
73
|
# Each 2-tuple will create one join condition in the ON clause.
|
65
|
-
self.join_cols = join_field.get_joining_columns()
|
74
|
+
self.join_cols = join_field.get_joining_columns() # type: ignore[attr-defined]
|
66
75
|
# Along which field (or ForeignObjectRel in the reverse join case)
|
67
76
|
self.join_field = join_field
|
68
77
|
# Is this join nullabled?
|
69
78
|
self.nullable = nullable
|
70
79
|
self.filtered_relation = filtered_relation
|
71
80
|
|
72
|
-
def as_sql(
|
81
|
+
def as_sql(
|
82
|
+
self, compiler: SQLCompiler, connection: BaseDatabaseWrapper
|
83
|
+
) -> tuple[str, list[Any]]:
|
73
84
|
"""
|
74
85
|
Generate the full
|
75
86
|
LEFT OUTER JOIN sometable ON sometable.somecol = othertable.othercol, params
|
@@ -117,7 +128,7 @@ class Join:
|
|
117
128
|
sql = f"{self.join_type} {qn(self.table_name)}{alias_str} ON ({on_clause_sql})"
|
118
129
|
return sql, params
|
119
130
|
|
120
|
-
def relabeled_clone(self, change_map):
|
131
|
+
def relabeled_clone(self, change_map: dict[str, str]) -> Join:
|
121
132
|
new_parent_alias = change_map.get(self.parent_alias, self.parent_alias)
|
122
133
|
new_table_alias = change_map.get(self.table_alias, self.table_alias)
|
123
134
|
if self.filtered_relation is not None:
|
@@ -138,7 +149,7 @@ class Join:
|
|
138
149
|
)
|
139
150
|
|
140
151
|
@property
|
141
|
-
def identity(self):
|
152
|
+
def identity(self) -> tuple[type[Join], str, str, Any, Any]:
|
142
153
|
return (
|
143
154
|
self.__class__,
|
144
155
|
self.table_name,
|
@@ -147,24 +158,24 @@ class Join:
|
|
147
158
|
self.filtered_relation,
|
148
159
|
)
|
149
160
|
|
150
|
-
def __eq__(self, other):
|
161
|
+
def __eq__(self, other: object) -> bool:
|
151
162
|
if not isinstance(other, Join):
|
152
163
|
return NotImplemented
|
153
164
|
return self.identity == other.identity
|
154
165
|
|
155
|
-
def __hash__(self):
|
166
|
+
def __hash__(self) -> int:
|
156
167
|
return hash(self.identity)
|
157
168
|
|
158
|
-
def equals(self, other):
|
169
|
+
def equals(self, other: Join) -> bool:
|
159
170
|
# Ignore filtered_relation in equality check.
|
160
171
|
return self.identity[:-1] == other.identity[:-1]
|
161
172
|
|
162
|
-
def demote(self):
|
173
|
+
def demote(self) -> Join:
|
163
174
|
new = self.relabeled_clone({})
|
164
175
|
new.join_type = INNER
|
165
176
|
return new
|
166
177
|
|
167
|
-
def promote(self):
|
178
|
+
def promote(self) -> Join:
|
168
179
|
new = self.relabeled_clone({})
|
169
180
|
new.join_type = LOUTER
|
170
181
|
return new
|
@@ -182,33 +193,35 @@ class BaseTable:
|
|
182
193
|
parent_alias = None
|
183
194
|
filtered_relation = None
|
184
195
|
|
185
|
-
def __init__(self, table_name, alias):
|
196
|
+
def __init__(self, table_name: str, alias: str) -> None:
|
186
197
|
self.table_name = table_name
|
187
198
|
self.table_alias = alias
|
188
199
|
|
189
|
-
def as_sql(
|
200
|
+
def as_sql(
|
201
|
+
self, compiler: SQLCompiler, connection: BaseDatabaseWrapper
|
202
|
+
) -> tuple[str, list[Any]]:
|
190
203
|
alias_str = (
|
191
204
|
"" if self.table_alias == self.table_name else (f" {self.table_alias}")
|
192
205
|
)
|
193
206
|
base_sql = compiler.quote_name_unless_alias(self.table_name)
|
194
207
|
return base_sql + alias_str, []
|
195
208
|
|
196
|
-
def relabeled_clone(self, change_map):
|
209
|
+
def relabeled_clone(self, change_map: dict[str, str]) -> BaseTable:
|
197
210
|
return self.__class__(
|
198
211
|
self.table_name, change_map.get(self.table_alias, self.table_alias)
|
199
212
|
)
|
200
213
|
|
201
214
|
@property
|
202
|
-
def identity(self):
|
215
|
+
def identity(self) -> tuple[type[BaseTable], str, str]:
|
203
216
|
return self.__class__, self.table_name, self.table_alias
|
204
217
|
|
205
|
-
def __eq__(self, other):
|
218
|
+
def __eq__(self, other: object) -> bool:
|
206
219
|
if not isinstance(other, BaseTable):
|
207
220
|
return NotImplemented
|
208
221
|
return self.identity == other.identity
|
209
222
|
|
210
|
-
def __hash__(self):
|
223
|
+
def __hash__(self) -> int:
|
211
224
|
return hash(self.identity)
|
212
225
|
|
213
|
-
def equals(self, other):
|
226
|
+
def equals(self, other: BaseTable) -> bool:
|
214
227
|
return self.identity == other.identity
|