plain.models 0.49.2__tar.gz → 0.50.0__tar.gz
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-0.49.2 → plain_models-0.50.0}/PKG-INFO +1 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/CHANGELOG.md +13 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/aggregates.py +42 -19
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/base/base.py +125 -105
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/base/client.py +11 -3
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/base/creation.py +22 -12
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/base/features.py +10 -4
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/base/introspection.py +29 -16
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/base/operations.py +187 -91
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/base/schema.py +267 -165
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/base/validation.py +12 -3
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/ddl_references.py +85 -43
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/mysql/base.py +29 -26
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/mysql/client.py +7 -2
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/mysql/compiler.py +12 -3
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/mysql/creation.py +5 -2
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/mysql/features.py +24 -22
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/mysql/introspection.py +22 -13
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/mysql/operations.py +106 -39
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/mysql/schema.py +48 -24
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/mysql/validation.py +13 -6
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/postgresql/base.py +41 -34
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/postgresql/client.py +7 -2
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/postgresql/creation.py +10 -5
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/postgresql/introspection.py +15 -8
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/postgresql/operations.py +109 -42
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/postgresql/schema.py +85 -46
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/sqlite3/_functions.py +151 -115
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/sqlite3/base.py +37 -23
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/sqlite3/client.py +7 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/sqlite3/creation.py +9 -5
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/sqlite3/features.py +5 -3
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/sqlite3/introspection.py +32 -16
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/sqlite3/operations.py +125 -42
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/sqlite3/schema.py +82 -58
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/utils.py +52 -29
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backups/cli.py +8 -6
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backups/clients.py +16 -7
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backups/core.py +24 -13
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/base.py +113 -74
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/cli.py +94 -63
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/config.py +1 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/connections.py +23 -7
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/constraints.py +65 -47
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/database_url.py +1 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/db.py +6 -2
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/deletion.py +66 -43
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/entrypoints.py +1 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/enums.py +22 -11
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/exceptions.py +23 -8
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/expressions.py +440 -257
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/fields/__init__.py +253 -202
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/fields/json.py +120 -54
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/fields/mixins.py +12 -8
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/fields/related.py +284 -252
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/fields/related_descriptors.py +31 -22
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/fields/related_lookups.py +23 -11
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/fields/related_managers.py +81 -47
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/fields/reverse_related.py +58 -55
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/forms.py +89 -63
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/functions/comparison.py +71 -18
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/functions/datetime.py +79 -29
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/functions/math.py +43 -10
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/functions/mixins.py +24 -7
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/functions/text.py +104 -25
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/functions/window.py +12 -6
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/indexes.py +52 -28
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/lookups.py +228 -153
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/autodetector.py +86 -43
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/exceptions.py +7 -3
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/executor.py +33 -7
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/graph.py +79 -50
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/loader.py +45 -22
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/migration.py +23 -18
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/operations/base.py +37 -19
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/operations/fields.py +89 -42
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/operations/models.py +245 -143
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/operations/special.py +82 -25
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/optimizer.py +7 -2
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/questioner.py +58 -31
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/recorder.py +18 -11
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/serializer.py +50 -39
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/state.py +220 -133
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/utils.py +29 -13
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/writer.py +17 -14
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/options.py +63 -56
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/otel.py +16 -6
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/preflight.py +35 -12
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/query.py +323 -228
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/query_utils.py +93 -58
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/registry.py +34 -16
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/sql/compiler.py +146 -97
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/sql/datastructures.py +38 -25
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/sql/query.py +255 -169
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/sql/subqueries.py +32 -21
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/sql/where.py +54 -29
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/test/pytest.py +15 -11
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/test/utils.py +4 -2
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/transaction.py +20 -7
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/utils.py +13 -5
- {plain_models-0.49.2 → plain_models-0.50.0}/pyproject.toml +1 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/test_delete_behaviors.py +1 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/test_exceptions.py +1 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/test_manager_assignment.py +1 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/test_models.py +1 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/test_related_descriptors.py +1 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/test_related_manager_api.py +1 -1
- {plain_models-0.49.2 → plain_models-0.50.0}/.gitignore +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/LICENSE +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/README.md +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/AGENTS.md +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/README.md +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/base/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/mysql/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/postgresql/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/postgresql/features.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backends/sqlite3/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/backups/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/constants.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/default_settings.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/functions/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/migrations/operations/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/sql/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/sql/constants.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/plain/models/test/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/app/examples/migrations/0001_initial.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/app/examples/migrations/0002_test_field_removed.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/app/examples/migrations/0003_deleteparent_childsetnull_childsetdefault_and_more.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/app/examples/migrations/__init__.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/app/examples/models.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/app/settings.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/app/urls.py +0 -0
- {plain_models-0.49.2 → plain_models-0.50.0}/tests/test_database_url.py +0 -0
@@ -1,5 +1,18 @@
|
|
1
1
|
# plain-models changelog
|
2
2
|
|
3
|
+
## [0.50.0](https://github.com/dropseed/plain/releases/plain-models@0.50.0) (2025-10-06)
|
4
|
+
|
5
|
+
### What's changed
|
6
|
+
|
7
|
+
- Added comprehensive type annotations throughout plain-models, improving IDE support and type checking capabilities ([ea1a7df](https://github.com/dropseed/plain/commit/ea1a7df622), [f49ee32](https://github.com/dropseed/plain/commit/f49ee32a90), [369353f](https://github.com/dropseed/plain/commit/369353f9d6), [13b7d16](https://github.com/dropseed/plain/commit/13b7d16f8d), [e23a0ca](https://github.com/dropseed/plain/commit/e23a0cae7c), [02d8551](https://github.com/dropseed/plain/commit/02d85518f0))
|
8
|
+
- The `QuerySet` class is now generic and the `model` parameter is now required in the `__init__` method ([719e792](https://github.com/dropseed/plain/commit/719e792c96))
|
9
|
+
- Database wrapper classes have been renamed for consistency: `DatabaseWrapper` classes are now named `MySQLDatabaseWrapper`, `PostgreSQLDatabaseWrapper`, and `SQLiteDatabaseWrapper` ([5a39e85](https://github.com/dropseed/plain/commit/5a39e851e5))
|
10
|
+
- The plain-models package now has 100% type annotation coverage and is validated in CI to prevent regressions
|
11
|
+
|
12
|
+
### Upgrade instructions
|
13
|
+
|
14
|
+
- No changes required
|
15
|
+
|
3
16
|
## [0.49.2](https://github.com/dropseed/plain/releases/plain-models@0.49.2) (2025-10-02)
|
4
17
|
|
5
18
|
### What's changed
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Any
|
4
4
|
|
5
5
|
from plain.models.exceptions import FieldError, FullResultSet
|
6
6
|
from plain.models.expressions import Case, Func, Star, Value, When
|
@@ -11,6 +11,12 @@ from plain.models.functions.mixins import (
|
|
11
11
|
NumericOutputFieldMixin,
|
12
12
|
)
|
13
13
|
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from plain.models.backends.base.base import BaseDatabaseWrapper
|
16
|
+
from plain.models.expressions import Expression
|
17
|
+
from plain.models.query_utils import Q
|
18
|
+
from plain.models.sql.compiler import SQLCompiler
|
19
|
+
|
14
20
|
__all__ = [
|
15
21
|
"Aggregate",
|
16
22
|
"Avg",
|
@@ -33,8 +39,13 @@ class Aggregate(Func):
|
|
33
39
|
empty_result_set_value = None
|
34
40
|
|
35
41
|
def __init__(
|
36
|
-
self,
|
37
|
-
|
42
|
+
self,
|
43
|
+
*expressions: Any,
|
44
|
+
distinct: bool = False,
|
45
|
+
filter: Q | Expression | None = None,
|
46
|
+
default: Any = None,
|
47
|
+
**extra: Any,
|
48
|
+
) -> None:
|
38
49
|
if distinct and not self.allow_distinct:
|
39
50
|
raise TypeError(f"{self.__class__.__name__} does not allow distinct.")
|
40
51
|
if default is not None and self.empty_result_set_value is not None:
|
@@ -44,23 +55,28 @@ class Aggregate(Func):
|
|
44
55
|
self.default = default
|
45
56
|
super().__init__(*expressions, **extra)
|
46
57
|
|
47
|
-
def get_source_fields(self):
|
58
|
+
def get_source_fields(self) -> list[Any]:
|
48
59
|
# Don't return the filter expression since it's not a source field.
|
49
60
|
return [e._output_field_or_none for e in super().get_source_expressions()]
|
50
61
|
|
51
|
-
def get_source_expressions(self):
|
62
|
+
def get_source_expressions(self) -> list[Expression]:
|
52
63
|
source_expressions = super().get_source_expressions()
|
53
64
|
if self.filter:
|
54
65
|
return source_expressions + [self.filter]
|
55
66
|
return source_expressions
|
56
67
|
|
57
|
-
def set_source_expressions(self, exprs):
|
68
|
+
def set_source_expressions(self, exprs: list[Expression]) -> list[Expression]:
|
58
69
|
self.filter = self.filter and exprs.pop()
|
59
70
|
return super().set_source_expressions(exprs)
|
60
71
|
|
61
72
|
def resolve_expression(
|
62
|
-
self,
|
63
|
-
|
73
|
+
self,
|
74
|
+
query: Any = None,
|
75
|
+
allow_joins: bool = True,
|
76
|
+
reuse: Any = None,
|
77
|
+
summarize: bool = False,
|
78
|
+
for_save: bool = False,
|
79
|
+
) -> Expression:
|
64
80
|
# Aggregates are not allowed in UPDATE queries, so ignore for_save
|
65
81
|
c = super().resolve_expression(query, allow_joins, reuse, summarize)
|
66
82
|
c.filter = c.filter and c.filter.resolve_expression(
|
@@ -95,16 +111,21 @@ class Aggregate(Func):
|
|
95
111
|
return coalesce
|
96
112
|
|
97
113
|
@property
|
98
|
-
def default_alias(self):
|
114
|
+
def default_alias(self) -> str:
|
99
115
|
expressions = self.get_source_expressions()
|
100
116
|
if len(expressions) == 1 and hasattr(expressions[0], "name"):
|
101
117
|
return f"{expressions[0].name}__{self.name.lower()}"
|
102
118
|
raise TypeError("Complex expressions require an alias")
|
103
119
|
|
104
|
-
def get_group_by_cols(self):
|
120
|
+
def get_group_by_cols(self) -> list[Any]:
|
105
121
|
return []
|
106
122
|
|
107
|
-
def as_sql(
|
123
|
+
def as_sql(
|
124
|
+
self,
|
125
|
+
compiler: SQLCompiler,
|
126
|
+
connection: BaseDatabaseWrapper,
|
127
|
+
**extra_context: Any,
|
128
|
+
) -> tuple[str, tuple[Any, ...]]:
|
108
129
|
extra_context["distinct"] = "DISTINCT " if self.distinct else ""
|
109
130
|
if self.filter:
|
110
131
|
if connection.features.supports_aggregate_filter_clause:
|
@@ -135,7 +156,7 @@ class Aggregate(Func):
|
|
135
156
|
)
|
136
157
|
return super().as_sql(compiler, connection, **extra_context)
|
137
158
|
|
138
|
-
def _get_repr_options(self):
|
159
|
+
def _get_repr_options(self) -> dict[str, Any]:
|
139
160
|
options = super()._get_repr_options()
|
140
161
|
if self.distinct:
|
141
162
|
options["distinct"] = self.distinct
|
@@ -157,7 +178,9 @@ class Count(Aggregate):
|
|
157
178
|
allow_distinct = True
|
158
179
|
empty_result_set_value = 0
|
159
180
|
|
160
|
-
def __init__(
|
181
|
+
def __init__(
|
182
|
+
self, expression: Any, filter: Q | Expression | None = None, **extra: Any
|
183
|
+
) -> None:
|
161
184
|
if expression == "*":
|
162
185
|
expression = Star()
|
163
186
|
if isinstance(expression, Star) and filter is not None:
|
@@ -178,11 +201,11 @@ class Min(Aggregate):
|
|
178
201
|
class StdDev(NumericOutputFieldMixin, Aggregate):
|
179
202
|
name = "StdDev"
|
180
203
|
|
181
|
-
def __init__(self, expression, sample=False, **extra):
|
204
|
+
def __init__(self, expression: Any, sample: bool = False, **extra: Any) -> None:
|
182
205
|
self.function = "STDDEV_SAMP" if sample else "STDDEV_POP"
|
183
206
|
super().__init__(expression, **extra)
|
184
207
|
|
185
|
-
def _get_repr_options(self):
|
208
|
+
def _get_repr_options(self) -> dict[str, Any]:
|
186
209
|
return {**super()._get_repr_options(), "sample": self.function == "STDDEV_SAMP"}
|
187
210
|
|
188
211
|
|
@@ -195,9 +218,9 @@ class Sum(FixDurationInputMixin, Aggregate):
|
|
195
218
|
class Variance(NumericOutputFieldMixin, Aggregate):
|
196
219
|
name = "Variance"
|
197
220
|
|
198
|
-
def __init__(self, expression, sample=False, **extra):
|
221
|
+
def __init__(self, expression: Any, sample: bool = False, **extra: Any) -> None:
|
199
222
|
self.function = "VAR_SAMP" if sample else "VAR_POP"
|
200
223
|
super().__init__(expression, **extra)
|
201
224
|
|
202
|
-
def _get_repr_options(self):
|
225
|
+
def _get_repr_options(self) -> dict[str, Any]:
|
203
226
|
return {**super()._get_repr_options(), "sample": self.function == "VAR_SAMP"}
|