plain.models 0.33.1__py3-none-any.whl → 0.34.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 (56) hide show
  1. plain/models/CHANGELOG.md +17 -0
  2. plain/models/README.md +8 -10
  3. plain/models/__init__.py +2 -6
  4. plain/models/backends/base/base.py +10 -18
  5. plain/models/backends/base/creation.py +3 -4
  6. plain/models/backends/base/introspection.py +2 -3
  7. plain/models/backends/base/schema.py +3 -9
  8. plain/models/backends/mysql/validation.py +1 -1
  9. plain/models/backends/postgresql/base.py +15 -23
  10. plain/models/backends/postgresql/schema.py +0 -2
  11. plain/models/backends/sqlite3/base.py +1 -1
  12. plain/models/backends/sqlite3/creation.py +2 -2
  13. plain/models/backends/sqlite3/features.py +1 -1
  14. plain/models/backends/sqlite3/schema.py +1 -1
  15. plain/models/backends/utils.py +2 -6
  16. plain/models/backups/core.py +15 -22
  17. plain/models/base.py +179 -225
  18. plain/models/cli.py +25 -62
  19. plain/models/connections.py +48 -165
  20. plain/models/constraints.py +10 -10
  21. plain/models/db.py +7 -15
  22. plain/models/default_settings.py +13 -20
  23. plain/models/deletion.py +14 -16
  24. plain/models/expressions.py +7 -10
  25. plain/models/fields/__init__.py +56 -76
  26. plain/models/fields/json.py +9 -12
  27. plain/models/fields/related.py +5 -17
  28. plain/models/fields/related_descriptors.py +43 -95
  29. plain/models/forms.py +2 -4
  30. plain/models/indexes.py +2 -3
  31. plain/models/lookups.py +0 -7
  32. plain/models/manager.py +1 -14
  33. plain/models/migrations/executor.py +0 -16
  34. plain/models/migrations/loader.py +1 -1
  35. plain/models/migrations/migration.py +1 -1
  36. plain/models/migrations/operations/base.py +4 -11
  37. plain/models/migrations/operations/fields.py +4 -4
  38. plain/models/migrations/operations/models.py +10 -10
  39. plain/models/migrations/operations/special.py +6 -14
  40. plain/models/migrations/recorder.py +1 -1
  41. plain/models/options.py +4 -7
  42. plain/models/preflight.py +25 -44
  43. plain/models/query.py +47 -102
  44. plain/models/query_utils.py +4 -4
  45. plain/models/sql/compiler.py +7 -11
  46. plain/models/sql/query.py +32 -42
  47. plain/models/sql/subqueries.py +6 -8
  48. plain/models/sql/where.py +1 -1
  49. plain/models/test/pytest.py +21 -32
  50. plain/models/test/utils.py +7 -143
  51. plain/models/transaction.py +66 -164
  52. {plain_models-0.33.1.dist-info → plain_models-0.34.0.dist-info}/METADATA +9 -11
  53. {plain_models-0.33.1.dist-info → plain_models-0.34.0.dist-info}/RECORD +56 -55
  54. {plain_models-0.33.1.dist-info → plain_models-0.34.0.dist-info}/WHEEL +0 -0
  55. {plain_models-0.33.1.dist-info → plain_models-0.34.0.dist-info}/entry_points.txt +0 -0
  56. {plain_models-0.33.1.dist-info → plain_models-0.34.0.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.alias, model):
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.alias, model):
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.alias, new_model):
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.alias, new_model):
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.alias, new_model):
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.alias, model):
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.alias, model):
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.alias, model):
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.alias, model):
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.alias, model):
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
- if router.allow_migrate(
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
- if router.allow_migrate(
136
- schema_editor.connection.alias, package_label, **self.hints
137
- ):
138
- # We now execute the Python code in a context that contains a 'models'
139
- # object, representing the versioned models as an app registry.
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"
@@ -53,7 +53,7 @@ class MigrationRecorder:
53
53
 
54
54
  @property
55
55
  def migration_qs(self):
56
- return self.Migration.objects.using(self.connection.alias)
56
+ return self.Migration.objects.all()
57
57
 
58
58
  def has_table(self):
59
59
  """Return True if the plainmigrations table exists."""
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 DEFAULT_DB_ALIAS, connections
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
- connections[DEFAULT_DB_ALIAS].ops.max_name_length(),
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 `connection`.
227
- `connection` can be either a real connection or a connection alias.
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(databases=None, **kwargs):
13
- if databases is None:
11
+ def check_database_backends(database=False, **kwargs):
12
+ if not database:
14
13
  return []
15
14
 
16
- from plain.models.db import connections
15
+ from plain.models.db import db_connection
17
16
 
18
- issues = []
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
- error_class(
53
+ Error(
68
54
  f"db_table '{db_table}' is used by multiple models: {model_labels_str}.",
69
55
  obj=db_table,
70
- hint=(error_hint % model_labels_str) if error_hint else None,
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 connections
188
+ from plain.models.db import db_connection
204
189
 
205
- databases = kwargs.get("databases", None)
206
- if not databases:
190
+ if not kwargs.get("database", False):
207
191
  return []
208
192
 
209
193
  errors = []
210
194
 
211
- for database in databases:
212
- conn = connections[database]
213
- db_tables = conn.introspection.table_names()
214
- model_tables = conn.introspection.plain_table_names()
215
-
216
- unknown_tables = set(db_tables) - set(model_tables)
217
- unknown_tables.discard("plainmigrations") # Know this could be there
218
- if unknown_tables:
219
- table_names = ", ".join(unknown_tables)
220
- specific_hint = f'echo "DROP TABLE IF EXISTS {unknown_tables.pop()}" | plain models db-shell'
221
- errors.append(
222
- Warning(
223
- f"Unknown tables in {database} database: {table_names}",
224
- hint=(
225
- "Tables may be from packages/models that have been uninstalled. "
226
- "Make sure you have a backup and delete the tables manually "
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