plain.models 0.49.1__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.
Files changed (105) hide show
  1. plain/models/CHANGELOG.md +23 -0
  2. plain/models/aggregates.py +42 -19
  3. plain/models/backends/base/base.py +125 -105
  4. plain/models/backends/base/client.py +11 -3
  5. plain/models/backends/base/creation.py +22 -12
  6. plain/models/backends/base/features.py +10 -4
  7. plain/models/backends/base/introspection.py +29 -16
  8. plain/models/backends/base/operations.py +187 -91
  9. plain/models/backends/base/schema.py +267 -165
  10. plain/models/backends/base/validation.py +12 -3
  11. plain/models/backends/ddl_references.py +85 -43
  12. plain/models/backends/mysql/base.py +29 -26
  13. plain/models/backends/mysql/client.py +7 -2
  14. plain/models/backends/mysql/compiler.py +12 -3
  15. plain/models/backends/mysql/creation.py +5 -2
  16. plain/models/backends/mysql/features.py +24 -22
  17. plain/models/backends/mysql/introspection.py +22 -13
  18. plain/models/backends/mysql/operations.py +106 -39
  19. plain/models/backends/mysql/schema.py +48 -24
  20. plain/models/backends/mysql/validation.py +13 -6
  21. plain/models/backends/postgresql/base.py +41 -34
  22. plain/models/backends/postgresql/client.py +7 -2
  23. plain/models/backends/postgresql/creation.py +10 -5
  24. plain/models/backends/postgresql/introspection.py +15 -8
  25. plain/models/backends/postgresql/operations.py +109 -42
  26. plain/models/backends/postgresql/schema.py +85 -46
  27. plain/models/backends/sqlite3/_functions.py +151 -115
  28. plain/models/backends/sqlite3/base.py +37 -23
  29. plain/models/backends/sqlite3/client.py +7 -1
  30. plain/models/backends/sqlite3/creation.py +9 -5
  31. plain/models/backends/sqlite3/features.py +5 -3
  32. plain/models/backends/sqlite3/introspection.py +32 -16
  33. plain/models/backends/sqlite3/operations.py +125 -42
  34. plain/models/backends/sqlite3/schema.py +82 -58
  35. plain/models/backends/utils.py +52 -29
  36. plain/models/backups/cli.py +8 -6
  37. plain/models/backups/clients.py +16 -7
  38. plain/models/backups/core.py +24 -13
  39. plain/models/base.py +113 -74
  40. plain/models/cli.py +94 -63
  41. plain/models/config.py +1 -1
  42. plain/models/connections.py +23 -7
  43. plain/models/constraints.py +65 -47
  44. plain/models/database_url.py +1 -1
  45. plain/models/db.py +6 -2
  46. plain/models/deletion.py +66 -43
  47. plain/models/entrypoints.py +1 -1
  48. plain/models/enums.py +22 -11
  49. plain/models/exceptions.py +23 -8
  50. plain/models/expressions.py +440 -257
  51. plain/models/fields/__init__.py +253 -202
  52. plain/models/fields/json.py +120 -54
  53. plain/models/fields/mixins.py +12 -8
  54. plain/models/fields/related.py +284 -252
  55. plain/models/fields/related_descriptors.py +34 -25
  56. plain/models/fields/related_lookups.py +23 -11
  57. plain/models/fields/related_managers.py +81 -47
  58. plain/models/fields/reverse_related.py +58 -55
  59. plain/models/forms.py +89 -63
  60. plain/models/functions/comparison.py +71 -18
  61. plain/models/functions/datetime.py +79 -29
  62. plain/models/functions/math.py +43 -10
  63. plain/models/functions/mixins.py +24 -7
  64. plain/models/functions/text.py +104 -25
  65. plain/models/functions/window.py +12 -6
  66. plain/models/indexes.py +52 -28
  67. plain/models/lookups.py +228 -153
  68. plain/models/migrations/autodetector.py +86 -43
  69. plain/models/migrations/exceptions.py +7 -3
  70. plain/models/migrations/executor.py +33 -7
  71. plain/models/migrations/graph.py +79 -50
  72. plain/models/migrations/loader.py +45 -22
  73. plain/models/migrations/migration.py +23 -18
  74. plain/models/migrations/operations/base.py +37 -19
  75. plain/models/migrations/operations/fields.py +89 -42
  76. plain/models/migrations/operations/models.py +245 -143
  77. plain/models/migrations/operations/special.py +82 -25
  78. plain/models/migrations/optimizer.py +7 -2
  79. plain/models/migrations/questioner.py +58 -31
  80. plain/models/migrations/recorder.py +18 -11
  81. plain/models/migrations/serializer.py +50 -39
  82. plain/models/migrations/state.py +220 -133
  83. plain/models/migrations/utils.py +29 -13
  84. plain/models/migrations/writer.py +17 -14
  85. plain/models/options.py +63 -56
  86. plain/models/otel.py +16 -6
  87. plain/models/preflight.py +35 -12
  88. plain/models/query.py +323 -228
  89. plain/models/query_utils.py +93 -58
  90. plain/models/registry.py +34 -16
  91. plain/models/sql/compiler.py +146 -97
  92. plain/models/sql/datastructures.py +38 -25
  93. plain/models/sql/query.py +255 -169
  94. plain/models/sql/subqueries.py +32 -21
  95. plain/models/sql/where.py +54 -29
  96. plain/models/test/pytest.py +15 -11
  97. plain/models/test/utils.py +4 -2
  98. plain/models/transaction.py +20 -7
  99. plain/models/utils.py +13 -5
  100. {plain_models-0.49.1.dist-info → plain_models-0.50.0.dist-info}/METADATA +1 -1
  101. plain_models-0.50.0.dist-info/RECORD +122 -0
  102. plain_models-0.49.1.dist-info/RECORD +0 -122
  103. {plain_models-0.49.1.dist-info → plain_models-0.50.0.dist-info}/WHEEL +0 -0
  104. {plain_models-0.49.1.dist-info → plain_models-0.50.0.dist-info}/entry_points.txt +0 -0
  105. {plain_models-0.49.1.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(self, compiler, connection):
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(self, compiler, connection):
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