plain.models 0.33.1__py3-none-any.whl → 0.34.1__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 +27 -0
- plain/models/README.md +8 -10
- plain/models/__init__.py +2 -6
- plain/models/backends/base/base.py +10 -18
- plain/models/backends/base/creation.py +3 -4
- plain/models/backends/base/introspection.py +2 -3
- plain/models/backends/base/schema.py +3 -9
- plain/models/backends/mysql/validation.py +1 -1
- plain/models/backends/postgresql/base.py +15 -23
- plain/models/backends/postgresql/schema.py +0 -2
- plain/models/backends/sqlite3/base.py +1 -1
- plain/models/backends/sqlite3/creation.py +2 -2
- plain/models/backends/sqlite3/features.py +1 -1
- plain/models/backends/sqlite3/schema.py +1 -1
- plain/models/backends/utils.py +2 -6
- plain/models/backups/core.py +15 -22
- plain/models/base.py +179 -225
- plain/models/cli.py +25 -62
- plain/models/connections.py +48 -165
- plain/models/constraints.py +10 -10
- plain/models/db.py +7 -15
- plain/models/default_settings.py +13 -20
- plain/models/deletion.py +14 -16
- plain/models/expressions.py +7 -10
- plain/models/fields/__init__.py +56 -76
- plain/models/fields/json.py +9 -12
- plain/models/fields/related.py +5 -17
- plain/models/fields/related_descriptors.py +43 -95
- plain/models/forms.py +2 -4
- plain/models/indexes.py +2 -3
- plain/models/lookups.py +0 -7
- plain/models/manager.py +1 -14
- plain/models/migrations/executor.py +0 -16
- plain/models/migrations/loader.py +1 -1
- plain/models/migrations/migration.py +1 -1
- plain/models/migrations/operations/base.py +4 -11
- plain/models/migrations/operations/fields.py +4 -4
- plain/models/migrations/operations/models.py +10 -10
- plain/models/migrations/operations/special.py +6 -14
- plain/models/migrations/recorder.py +1 -1
- plain/models/options.py +4 -7
- plain/models/preflight.py +25 -44
- plain/models/query.py +47 -102
- plain/models/query_utils.py +4 -4
- plain/models/sql/compiler.py +7 -11
- plain/models/sql/query.py +32 -42
- plain/models/sql/subqueries.py +6 -8
- plain/models/sql/where.py +1 -1
- plain/models/test/pytest.py +21 -32
- plain/models/test/utils.py +7 -143
- plain/models/transaction.py +66 -164
- {plain_models-0.33.1.dist-info → plain_models-0.34.1.dist-info}/METADATA +9 -11
- {plain_models-0.33.1.dist-info → plain_models-0.34.1.dist-info}/RECORD +56 -55
- {plain_models-0.33.1.dist-info → plain_models-0.34.1.dist-info}/WHEEL +0 -0
- {plain_models-0.33.1.dist-info → plain_models-0.34.1.dist-info}/entry_points.txt +0 -0
- {plain_models-0.33.1.dist-info → plain_models-0.34.1.dist-info}/licenses/LICENSE +0 -0
@@ -92,7 +92,7 @@ class CreateModel(ModelOperation):
|
|
92
92
|
|
93
93
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
94
94
|
model = to_state.models_registry.get_model(package_label, self.name)
|
95
|
-
if self.allow_migrate_model(schema_editor.connection
|
95
|
+
if self.allow_migrate_model(schema_editor.connection, model):
|
96
96
|
schema_editor.create_model(model)
|
97
97
|
|
98
98
|
def describe(self):
|
@@ -249,7 +249,7 @@ class DeleteModel(ModelOperation):
|
|
249
249
|
|
250
250
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
251
251
|
model = from_state.models_registry.get_model(package_label, self.name)
|
252
|
-
if self.allow_migrate_model(schema_editor.connection
|
252
|
+
if self.allow_migrate_model(schema_editor.connection, model):
|
253
253
|
schema_editor.delete_model(model)
|
254
254
|
|
255
255
|
def references_model(self, name, package_label):
|
@@ -293,7 +293,7 @@ class RenameModel(ModelOperation):
|
|
293
293
|
|
294
294
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
295
295
|
new_model = to_state.models_registry.get_model(package_label, self.new_name)
|
296
|
-
if self.allow_migrate_model(schema_editor.connection
|
296
|
+
if self.allow_migrate_model(schema_editor.connection, new_model):
|
297
297
|
old_model = from_state.models_registry.get_model(
|
298
298
|
package_label, self.old_name
|
299
299
|
)
|
@@ -384,7 +384,7 @@ class AlterModelTable(ModelOptionOperation):
|
|
384
384
|
|
385
385
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
386
386
|
new_model = to_state.models_registry.get_model(package_label, self.name)
|
387
|
-
if self.allow_migrate_model(schema_editor.connection
|
387
|
+
if self.allow_migrate_model(schema_editor.connection, new_model):
|
388
388
|
old_model = from_state.models_registry.get_model(package_label, self.name)
|
389
389
|
schema_editor.alter_db_table(
|
390
390
|
new_model,
|
@@ -422,7 +422,7 @@ class AlterModelTableComment(ModelOptionOperation):
|
|
422
422
|
|
423
423
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
424
424
|
new_model = to_state.models_registry.get_model(package_label, self.name)
|
425
|
-
if self.allow_migrate_model(schema_editor.connection
|
425
|
+
if self.allow_migrate_model(schema_editor.connection, new_model):
|
426
426
|
old_model = from_state.models_registry.get_model(package_label, self.name)
|
427
427
|
schema_editor.alter_db_table_comment(
|
428
428
|
new_model,
|
@@ -535,7 +535,7 @@ class AddIndex(IndexOperation):
|
|
535
535
|
|
536
536
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
537
537
|
model = to_state.models_registry.get_model(package_label, self.model_name)
|
538
|
-
if self.allow_migrate_model(schema_editor.connection
|
538
|
+
if self.allow_migrate_model(schema_editor.connection, model):
|
539
539
|
schema_editor.add_index(model, self.index)
|
540
540
|
|
541
541
|
def deconstruct(self):
|
@@ -579,7 +579,7 @@ class RemoveIndex(IndexOperation):
|
|
579
579
|
|
580
580
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
581
581
|
model = from_state.models_registry.get_model(package_label, self.model_name)
|
582
|
-
if self.allow_migrate_model(schema_editor.connection
|
582
|
+
if self.allow_migrate_model(schema_editor.connection, model):
|
583
583
|
from_model_state = from_state.models[package_label, self.model_name_lower]
|
584
584
|
index = from_model_state.get_index_by_name(self.name)
|
585
585
|
schema_editor.remove_index(model, index)
|
@@ -654,7 +654,7 @@ class RenameIndex(IndexOperation):
|
|
654
654
|
|
655
655
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
656
656
|
model = to_state.models_registry.get_model(package_label, self.model_name)
|
657
|
-
if not self.allow_migrate_model(schema_editor.connection
|
657
|
+
if not self.allow_migrate_model(schema_editor.connection, model):
|
658
658
|
return
|
659
659
|
|
660
660
|
if self.old_fields:
|
@@ -740,7 +740,7 @@ class AddConstraint(IndexOperation):
|
|
740
740
|
|
741
741
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
742
742
|
model = to_state.models_registry.get_model(package_label, self.model_name)
|
743
|
-
if self.allow_migrate_model(schema_editor.connection
|
743
|
+
if self.allow_migrate_model(schema_editor.connection, model):
|
744
744
|
schema_editor.add_constraint(model, self.constraint)
|
745
745
|
|
746
746
|
def deconstruct(self):
|
@@ -773,7 +773,7 @@ class RemoveConstraint(IndexOperation):
|
|
773
773
|
|
774
774
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
775
775
|
model = to_state.models_registry.get_model(package_label, self.model_name)
|
776
|
-
if self.allow_migrate_model(schema_editor.connection
|
776
|
+
if self.allow_migrate_model(schema_editor.connection, model):
|
777
777
|
from_model_state = from_state.models[package_label, self.model_name_lower]
|
778
778
|
constraint = from_model_state.get_constraint_by_name(self.name)
|
779
779
|
schema_editor.remove_constraint(model, constraint)
|
@@ -1,5 +1,3 @@
|
|
1
|
-
from plain.models.db import router
|
2
|
-
|
3
1
|
from .base import Operation
|
4
2
|
|
5
3
|
|
@@ -72,10 +70,7 @@ class RunSQL(Operation):
|
|
72
70
|
state_operation.state_forwards(package_label, state)
|
73
71
|
|
74
72
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
75
|
-
|
76
|
-
schema_editor.connection.alias, package_label, **self.hints
|
77
|
-
):
|
78
|
-
self._run_sql(schema_editor, self.sql)
|
73
|
+
self._run_sql(schema_editor, self.sql)
|
79
74
|
|
80
75
|
def describe(self):
|
81
76
|
return "Raw SQL operation"
|
@@ -132,14 +127,11 @@ class RunPython(Operation):
|
|
132
127
|
# RunPython has access to all models. Ensure that all models are
|
133
128
|
# reloaded in case any are delayed.
|
134
129
|
from_state.clear_delayed_models_cache()
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
# We could try to override the global cache, but then people will still
|
141
|
-
# use direct imports, so we go with a documentation approach instead.
|
142
|
-
self.code(from_state.models_registry, schema_editor)
|
130
|
+
# We now execute the Python code in a context that contains a 'models'
|
131
|
+
# object, representing the versioned models as an app registry.
|
132
|
+
# We could try to override the global cache, but then people will still
|
133
|
+
# use direct imports, so we go with a documentation approach instead.
|
134
|
+
self.code(from_state.models_registry, schema_editor)
|
143
135
|
|
144
136
|
def describe(self):
|
145
137
|
return "Raw Python operation"
|
plain/models/options.py
CHANGED
@@ -7,7 +7,7 @@ from functools import cached_property
|
|
7
7
|
from plain.exceptions import FieldDoesNotExist
|
8
8
|
from plain.models import models_registry
|
9
9
|
from plain.models.constraints import UniqueConstraint
|
10
|
-
from plain.models.db import
|
10
|
+
from plain.models.db import db_connection
|
11
11
|
from plain.models.fields import BigAutoField
|
12
12
|
from plain.models.manager import Manager
|
13
13
|
from plain.utils.datastructures import ImmutableList
|
@@ -105,7 +105,6 @@ class Options:
|
|
105
105
|
|
106
106
|
def contribute_to_class(self, cls, name):
|
107
107
|
from plain.models.backends.utils import truncate_name
|
108
|
-
from plain.models.db import connections
|
109
108
|
|
110
109
|
cls._meta = self
|
111
110
|
self.model = cls
|
@@ -155,7 +154,7 @@ class Options:
|
|
155
154
|
self.db_table = f"{self.package_label}_{self.model_name}"
|
156
155
|
self.db_table = truncate_name(
|
157
156
|
self.db_table,
|
158
|
-
|
157
|
+
db_connection.ops.max_name_length(),
|
159
158
|
)
|
160
159
|
|
161
160
|
def _format_names_with_class(self, cls, objs):
|
@@ -223,11 +222,9 @@ class Options:
|
|
223
222
|
|
224
223
|
def can_migrate(self, connection):
|
225
224
|
"""
|
226
|
-
Return True if the model can/should be migrated on the
|
227
|
-
`connection`
|
225
|
+
Return True if the model can/should be migrated on the given
|
226
|
+
`connection` object.
|
228
227
|
"""
|
229
|
-
if isinstance(connection, str):
|
230
|
-
connection = connections[connection]
|
231
228
|
if self.required_db_vendor:
|
232
229
|
return self.required_db_vendor == connection.vendor
|
233
230
|
if self.required_db_features:
|
plain/models/preflight.py
CHANGED
@@ -5,21 +5,16 @@ from itertools import chain
|
|
5
5
|
from plain.models.registry import models_registry
|
6
6
|
from plain.packages import packages_registry
|
7
7
|
from plain.preflight import Error, Warning, register_check
|
8
|
-
from plain.runtime import settings
|
9
8
|
|
10
9
|
|
11
10
|
@register_check
|
12
|
-
def check_database_backends(
|
13
|
-
if
|
11
|
+
def check_database_backends(database=False, **kwargs):
|
12
|
+
if not database:
|
14
13
|
return []
|
15
14
|
|
16
|
-
from plain.models.db import
|
15
|
+
from plain.models.db import db_connection
|
17
16
|
|
18
|
-
|
19
|
-
for alias in databases:
|
20
|
-
conn = connections[alias]
|
21
|
-
issues.extend(conn.validation.check(**kwargs))
|
22
|
-
return issues
|
17
|
+
return db_connection.validation.check(**kwargs)
|
23
18
|
|
24
19
|
|
25
20
|
@register_check
|
@@ -51,24 +46,14 @@ def check_all_models(package_configs=None, **kwargs):
|
|
51
46
|
indexes[model_index.name].append(model._meta.label)
|
52
47
|
for model_constraint in model._meta.constraints:
|
53
48
|
constraints[model_constraint.name].append(model._meta.label)
|
54
|
-
if settings.DATABASE_ROUTERS:
|
55
|
-
error_class, error_id = Warning, "models.W035"
|
56
|
-
error_hint = (
|
57
|
-
"You have configured settings.DATABASE_ROUTERS. Verify that %s "
|
58
|
-
"are correctly routed to separate databases."
|
59
|
-
)
|
60
|
-
else:
|
61
|
-
error_class, error_id = Error, "models.E028"
|
62
|
-
error_hint = None
|
63
49
|
for db_table, model_labels in db_table_models.items():
|
64
50
|
if len(model_labels) != 1:
|
65
51
|
model_labels_str = ", ".join(model_labels)
|
66
52
|
errors.append(
|
67
|
-
|
53
|
+
Error(
|
68
54
|
f"db_table '{db_table}' is used by multiple models: {model_labels_str}.",
|
69
55
|
obj=db_table,
|
70
|
-
|
71
|
-
id=error_id,
|
56
|
+
id="models.E028",
|
72
57
|
)
|
73
58
|
)
|
74
59
|
for index_name, model_labels in indexes.items():
|
@@ -200,34 +185,30 @@ def check_lazy_references(package_configs=None, **kwargs):
|
|
200
185
|
|
201
186
|
@register_check
|
202
187
|
def check_database_tables(package_configs, **kwargs):
|
203
|
-
from plain.models.db import
|
188
|
+
from plain.models.db import db_connection
|
204
189
|
|
205
|
-
|
206
|
-
if not databases:
|
190
|
+
if not kwargs.get("database", False):
|
207
191
|
return []
|
208
192
|
|
209
193
|
errors = []
|
210
194
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
unknown_tables.
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
f"(ex. `{specific_hint}`)."
|
228
|
-
),
|
229
|
-
id="plain.models.W001",
|
230
|
-
)
|
195
|
+
db_tables = db_connection.introspection.table_names()
|
196
|
+
model_tables = db_connection.introspection.plain_table_names()
|
197
|
+
unknown_tables = set(db_tables) - set(model_tables)
|
198
|
+
unknown_tables.discard("plainmigrations") # Know this could be there
|
199
|
+
if unknown_tables:
|
200
|
+
table_names = ", ".join(unknown_tables)
|
201
|
+
specific_hint = f'echo "DROP TABLE IF EXISTS {unknown_tables.pop()}" | plain models db-shell'
|
202
|
+
errors.append(
|
203
|
+
Warning(
|
204
|
+
f"Unknown tables in default database: {table_names}",
|
205
|
+
hint=(
|
206
|
+
"Tables may be from packages/models that have been uninstalled. "
|
207
|
+
"Make sure you have a backup and delete the tables manually "
|
208
|
+
f"(ex. `{specific_hint}`)."
|
209
|
+
),
|
210
|
+
id="plain.models.W001",
|
231
211
|
)
|
212
|
+
)
|
232
213
|
|
233
214
|
return errors
|