plain.models 0.50.0__py3-none-any.whl → 0.51.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 +24 -0
- plain/models/README.md +26 -42
- plain/models/__init__.py +2 -0
- plain/models/backends/base/creation.py +2 -2
- plain/models/backends/base/introspection.py +8 -4
- plain/models/backends/base/schema.py +89 -71
- plain/models/backends/base/validation.py +1 -1
- plain/models/backends/mysql/compiler.py +1 -1
- plain/models/backends/mysql/operations.py +1 -1
- plain/models/backends/mysql/schema.py +4 -4
- plain/models/backends/postgresql/operations.py +1 -1
- plain/models/backends/postgresql/schema.py +3 -3
- plain/models/backends/sqlite3/operations.py +1 -1
- plain/models/backends/sqlite3/schema.py +61 -50
- plain/models/base.py +116 -163
- plain/models/cli.py +4 -4
- plain/models/constraints.py +14 -9
- plain/models/deletion.py +15 -14
- plain/models/expressions.py +21 -5
- plain/models/fields/__init__.py +20 -16
- plain/models/fields/json.py +3 -3
- plain/models/fields/related.py +73 -71
- plain/models/fields/related_descriptors.py +2 -2
- plain/models/fields/related_lookups.py +1 -1
- plain/models/fields/related_managers.py +21 -32
- plain/models/fields/reverse_related.py +8 -8
- plain/models/forms.py +12 -12
- plain/models/indexes.py +5 -4
- plain/models/meta.py +505 -0
- plain/models/migrations/operations/base.py +1 -1
- plain/models/migrations/operations/fields.py +6 -6
- plain/models/migrations/operations/models.py +18 -16
- plain/models/migrations/recorder.py +9 -5
- plain/models/migrations/state.py +35 -46
- plain/models/migrations/utils.py +1 -1
- plain/models/options.py +182 -518
- plain/models/preflight.py +7 -5
- plain/models/query.py +119 -65
- plain/models/query_utils.py +18 -13
- plain/models/registry.py +6 -5
- plain/models/sql/compiler.py +51 -37
- plain/models/sql/query.py +77 -68
- plain/models/sql/subqueries.py +4 -4
- plain/models/utils.py +4 -1
- {plain_models-0.50.0.dist-info → plain_models-0.51.1.dist-info}/METADATA +27 -43
- {plain_models-0.50.0.dist-info → plain_models-0.51.1.dist-info}/RECORD +49 -48
- {plain_models-0.50.0.dist-info → plain_models-0.51.1.dist-info}/WHEEL +0 -0
- {plain_models-0.50.0.dist-info → plain_models-0.51.1.dist-info}/entry_points.txt +0 -0
- {plain_models-0.50.0.dist-info → plain_models-0.51.1.dist-info}/licenses/LICENSE +0 -0
@@ -28,6 +28,8 @@ if TYPE_CHECKING:
|
|
28
28
|
from plain.models.base import Model
|
29
29
|
from plain.models.constraints import BaseConstraint
|
30
30
|
from plain.models.fields import Field
|
31
|
+
from plain.models.fields.related import ForeignKey, ManyToManyField
|
32
|
+
from plain.models.fields.reverse_related import ManyToManyRel
|
31
33
|
|
32
34
|
logger = logging.getLogger("plain.models.backends.schema")
|
33
35
|
|
@@ -51,7 +53,7 @@ def _is_relevant_relation(relation: Any, altered_field: Field) -> bool:
|
|
51
53
|
def _all_related_fields(model: type[Model]) -> list[Any]:
|
52
54
|
# Related fields must be returned in a deterministic order.
|
53
55
|
return sorted(
|
54
|
-
model.
|
56
|
+
model._model_meta._get_fields(
|
55
57
|
forward=False,
|
56
58
|
reverse=True,
|
57
59
|
include_hidden=True,
|
@@ -225,7 +227,7 @@ class BaseDatabaseSchemaEditor:
|
|
225
227
|
# Create column SQL, add FK deferreds if needed.
|
226
228
|
column_sqls = []
|
227
229
|
params = []
|
228
|
-
for field in model.
|
230
|
+
for field in model._model_meta.local_fields:
|
229
231
|
# SQL.
|
230
232
|
definition, extra_params = self.column_sql(model, field)
|
231
233
|
if definition is None:
|
@@ -241,8 +243,8 @@ class BaseDatabaseSchemaEditor:
|
|
241
243
|
params.extend(extra_params)
|
242
244
|
# FK.
|
243
245
|
if field.remote_field and field.db_constraint: # type: ignore[attr-defined]
|
244
|
-
to_table = field.remote_field.model.
|
245
|
-
to_column = field.remote_field.model.
|
246
|
+
to_table = field.remote_field.model.model_options.db_table
|
247
|
+
to_column = field.remote_field.model._model_meta.get_field(
|
246
248
|
field.remote_field.field_name
|
247
249
|
).column
|
248
250
|
if self.sql_create_inline_fk:
|
@@ -262,16 +264,16 @@ class BaseDatabaseSchemaEditor:
|
|
262
264
|
# variant).
|
263
265
|
if field.get_internal_type() in ("PrimaryKeyField",):
|
264
266
|
autoinc_sql = self.connection.ops.autoinc_sql(
|
265
|
-
model.
|
267
|
+
model.model_options.db_table, field.column
|
266
268
|
)
|
267
269
|
if autoinc_sql:
|
268
270
|
self.deferred_sql.extend(autoinc_sql)
|
269
271
|
constraints = [
|
270
272
|
constraint.constraint_sql(model, self)
|
271
|
-
for constraint in model.
|
273
|
+
for constraint in model.model_options.constraints
|
272
274
|
]
|
273
275
|
sql = self.sql_create_table % {
|
274
|
-
"table": self.quote_name(model.
|
276
|
+
"table": self.quote_name(model.model_options.db_table),
|
275
277
|
"definition": ", ".join(
|
276
278
|
str(constraint)
|
277
279
|
for constraint in (*column_sqls, *constraints)
|
@@ -442,11 +444,13 @@ class BaseDatabaseSchemaEditor:
|
|
442
444
|
|
443
445
|
if self.connection.features.supports_comments:
|
444
446
|
# Add table comment.
|
445
|
-
if model.
|
446
|
-
self.alter_db_table_comment(
|
447
|
+
if model.model_options.db_table_comment:
|
448
|
+
self.alter_db_table_comment(
|
449
|
+
model, None, model.model_options.db_table_comment
|
450
|
+
)
|
447
451
|
# Add column comments.
|
448
452
|
if not self.connection.features.supports_comments_inline:
|
449
|
-
for field in model.
|
453
|
+
for field in model._model_meta.local_fields:
|
450
454
|
if field.db_comment:
|
451
455
|
field_db_params = field.db_parameters(
|
452
456
|
connection=self.connection
|
@@ -467,13 +471,13 @@ class BaseDatabaseSchemaEditor:
|
|
467
471
|
self.execute(
|
468
472
|
self.sql_delete_table
|
469
473
|
% {
|
470
|
-
"table": self.quote_name(model.
|
474
|
+
"table": self.quote_name(model.model_options.db_table),
|
471
475
|
}
|
472
476
|
)
|
473
477
|
# Remove all deferred statements referencing the deleted table.
|
474
478
|
for sql in list(self.deferred_sql):
|
475
479
|
if isinstance(sql, Statement) and sql.references_table(
|
476
|
-
model.
|
480
|
+
model.model_options.db_table
|
477
481
|
):
|
478
482
|
self.deferred_sql.remove(sql)
|
479
483
|
|
@@ -553,7 +557,7 @@ class BaseDatabaseSchemaEditor:
|
|
553
557
|
self.execute(
|
554
558
|
self.sql_alter_table_comment
|
555
559
|
% {
|
556
|
-
"table": self.quote_name(model.
|
560
|
+
"table": self.quote_name(model.model_options.db_table),
|
557
561
|
"comment": self.quote_value(new_db_table_comment or ""),
|
558
562
|
}
|
559
563
|
)
|
@@ -582,11 +586,11 @@ class BaseDatabaseSchemaEditor:
|
|
582
586
|
constraint_suffix = "_fk_%(to_table)s_%(to_column)s"
|
583
587
|
# Add FK constraint inline, if supported.
|
584
588
|
if self.sql_create_column_inline_fk:
|
585
|
-
to_table = field.remote_field.model.
|
586
|
-
to_column = field.remote_field.model.
|
589
|
+
to_table = field.remote_field.model.model_options.db_table
|
590
|
+
to_column = field.remote_field.model._model_meta.get_field(
|
587
591
|
field.remote_field.field_name
|
588
592
|
).column
|
589
|
-
namespace, _ = split_identifier(model.
|
593
|
+
namespace, _ = split_identifier(model.model_options.db_table)
|
590
594
|
definition += " " + self.sql_create_column_inline_fk % {
|
591
595
|
"name": self._fk_constraint_name(model, field, constraint_suffix),
|
592
596
|
"namespace": f"{self.quote_name(namespace)}." if namespace else "",
|
@@ -602,7 +606,7 @@ class BaseDatabaseSchemaEditor:
|
|
602
606
|
)
|
603
607
|
# Build the SQL and run it
|
604
608
|
sql = self.sql_create_column % {
|
605
|
-
"table": self.quote_name(model.
|
609
|
+
"table": self.quote_name(model.model_options.db_table),
|
606
610
|
"column": self.quote_name(field.column),
|
607
611
|
"definition": definition,
|
608
612
|
}
|
@@ -617,7 +621,7 @@ class BaseDatabaseSchemaEditor:
|
|
617
621
|
model, None, field, drop=True
|
618
622
|
)
|
619
623
|
sql = self.sql_alter_column % {
|
620
|
-
"table": self.quote_name(model.
|
624
|
+
"table": self.quote_name(model.model_options.db_table),
|
621
625
|
"changes": changes_sql,
|
622
626
|
}
|
623
627
|
self.execute(sql, params)
|
@@ -654,7 +658,7 @@ class BaseDatabaseSchemaEditor:
|
|
654
658
|
self.execute(self._delete_fk_sql(model, fk_name))
|
655
659
|
# Delete the column
|
656
660
|
sql = self.sql_delete_column % {
|
657
|
-
"table": self.quote_name(model.
|
661
|
+
"table": self.quote_name(model.model_options.db_table),
|
658
662
|
"column": self.quote_name(field.column),
|
659
663
|
}
|
660
664
|
self.execute(sql)
|
@@ -664,7 +668,7 @@ class BaseDatabaseSchemaEditor:
|
|
664
668
|
# Remove all deferred statements referencing the deleted column.
|
665
669
|
for sql in list(self.deferred_sql):
|
666
670
|
if isinstance(sql, Statement) and sql.references_column(
|
667
|
-
model.
|
671
|
+
model.model_options.db_table, field.column
|
668
672
|
):
|
669
673
|
self.deferred_sql.remove(sql)
|
670
674
|
|
@@ -763,7 +767,7 @@ class BaseDatabaseSchemaEditor:
|
|
763
767
|
)
|
764
768
|
if strict and len(fk_names) != 1:
|
765
769
|
raise ValueError(
|
766
|
-
f"Found wrong number ({len(fk_names)}) of foreign key constraints for {model.
|
770
|
+
f"Found wrong number ({len(fk_names)}) of foreign key constraints for {model.model_options.db_table}.{old_field.column}"
|
767
771
|
)
|
768
772
|
for fk_name in fk_names:
|
769
773
|
fks_dropped.add((old_field.column,))
|
@@ -775,7 +779,7 @@ class BaseDatabaseSchemaEditor:
|
|
775
779
|
):
|
776
780
|
# Find the unique constraint for this field
|
777
781
|
meta_constraint_names = {
|
778
|
-
constraint.name for constraint in model.
|
782
|
+
constraint.name for constraint in model.model_options.constraints
|
779
783
|
}
|
780
784
|
constraint_names = self._constraint_names(
|
781
785
|
model,
|
@@ -786,7 +790,7 @@ class BaseDatabaseSchemaEditor:
|
|
786
790
|
)
|
787
791
|
if strict and len(constraint_names) != 1:
|
788
792
|
raise ValueError(
|
789
|
-
f"Found wrong number ({len(constraint_names)}) of unique constraints for {model.
|
793
|
+
f"Found wrong number ({len(constraint_names)}) of unique constraints for {model.model_options.db_table}.{old_field.column}"
|
790
794
|
)
|
791
795
|
for constraint_name in constraint_names:
|
792
796
|
self.execute(self._delete_unique_sql(model, constraint_name))
|
@@ -800,7 +804,7 @@ class BaseDatabaseSchemaEditor:
|
|
800
804
|
and ((old_type != new_type) or (old_collation != new_collation))
|
801
805
|
)
|
802
806
|
if drop_foreign_keys:
|
803
|
-
# '
|
807
|
+
# '_model_meta.related_field' also contains M2M reverse fields, these
|
804
808
|
# will be filtered out
|
805
809
|
for _old_rel, new_rel in _related_non_m2m_objects(old_field, new_field):
|
806
810
|
rel_fk_names = self._constraint_names(
|
@@ -827,7 +831,7 @@ class BaseDatabaseSchemaEditor:
|
|
827
831
|
)
|
828
832
|
):
|
829
833
|
# Find the index for this field
|
830
|
-
meta_index_names = {index.name for index in model.
|
834
|
+
meta_index_names = {index.name for index in model.model_options.indexes}
|
831
835
|
# Retrieve only BTREE indexes since this is what's created with
|
832
836
|
# db_index=True.
|
833
837
|
index_names = self._constraint_names(
|
@@ -847,7 +851,7 @@ class BaseDatabaseSchemaEditor:
|
|
847
851
|
new_db_check = self._field_db_check(new_field, new_db_params)
|
848
852
|
if old_db_check != new_db_check and old_db_check:
|
849
853
|
meta_constraint_names = {
|
850
|
-
constraint.name for constraint in model.
|
854
|
+
constraint.name for constraint in model.model_options.constraints
|
851
855
|
}
|
852
856
|
constraint_names = self._constraint_names(
|
853
857
|
model,
|
@@ -857,7 +861,7 @@ class BaseDatabaseSchemaEditor:
|
|
857
861
|
)
|
858
862
|
if strict and len(constraint_names) != 1:
|
859
863
|
raise ValueError(
|
860
|
-
f"Found wrong number ({len(constraint_names)}) of check constraints for {model.
|
864
|
+
f"Found wrong number ({len(constraint_names)}) of check constraints for {model.model_options.db_table}.{old_field.column}"
|
861
865
|
)
|
862
866
|
for constraint_name in constraint_names:
|
863
867
|
self.execute(self._delete_check_sql(model, constraint_name))
|
@@ -865,14 +869,14 @@ class BaseDatabaseSchemaEditor:
|
|
865
869
|
if old_field.column != new_field.column:
|
866
870
|
self.execute(
|
867
871
|
self._rename_field_sql(
|
868
|
-
model.
|
872
|
+
model.model_options.db_table, old_field, new_field, new_type
|
869
873
|
)
|
870
874
|
)
|
871
875
|
# Rename all references to the renamed column.
|
872
876
|
for sql in self.deferred_sql:
|
873
877
|
if isinstance(sql, Statement):
|
874
878
|
sql.rename_column_references(
|
875
|
-
model.
|
879
|
+
model.model_options.db_table, old_field.column, new_field.column
|
876
880
|
)
|
877
881
|
# Next, start accumulating actions to do
|
878
882
|
actions = []
|
@@ -939,7 +943,7 @@ class BaseDatabaseSchemaEditor:
|
|
939
943
|
self.execute(
|
940
944
|
self.sql_alter_column
|
941
945
|
% {
|
942
|
-
"table": self.quote_name(model.
|
946
|
+
"table": self.quote_name(model.model_options.db_table),
|
943
947
|
"changes": sql,
|
944
948
|
},
|
945
949
|
params,
|
@@ -949,7 +953,7 @@ class BaseDatabaseSchemaEditor:
|
|
949
953
|
self.execute(
|
950
954
|
self.sql_update_with_default
|
951
955
|
% {
|
952
|
-
"table": self.quote_name(model.
|
956
|
+
"table": self.quote_name(model.model_options.db_table),
|
953
957
|
"column": self.quote_name(new_field.column),
|
954
958
|
"default": "%s",
|
955
959
|
},
|
@@ -961,7 +965,7 @@ class BaseDatabaseSchemaEditor:
|
|
961
965
|
self.execute(
|
962
966
|
self.sql_alter_column
|
963
967
|
% {
|
964
|
-
"table": self.quote_name(model.
|
968
|
+
"table": self.quote_name(model.model_options.db_table),
|
965
969
|
"changes": sql,
|
966
970
|
},
|
967
971
|
params,
|
@@ -1020,7 +1024,9 @@ class BaseDatabaseSchemaEditor:
|
|
1020
1024
|
self.execute(
|
1021
1025
|
self.sql_alter_column
|
1022
1026
|
% {
|
1023
|
-
"table": self.quote_name(
|
1027
|
+
"table": self.quote_name(
|
1028
|
+
new_rel.related_model.model_options.db_table
|
1029
|
+
),
|
1024
1030
|
"changes": fragment[0],
|
1025
1031
|
},
|
1026
1032
|
fragment[1],
|
@@ -1049,7 +1055,7 @@ class BaseDatabaseSchemaEditor:
|
|
1049
1055
|
# Does it have check constraints we need to add?
|
1050
1056
|
if old_db_check != new_db_check and new_db_check:
|
1051
1057
|
constraint_name = self._create_index_name(
|
1052
|
-
model.
|
1058
|
+
model.model_options.db_table, [new_field.column], suffix="_check"
|
1053
1059
|
)
|
1054
1060
|
self.execute(
|
1055
1061
|
self._create_check_sql(model, constraint_name, new_db_params["check"])
|
@@ -1061,7 +1067,7 @@ class BaseDatabaseSchemaEditor:
|
|
1061
1067
|
model, old_field, new_field, drop=True
|
1062
1068
|
)
|
1063
1069
|
sql = self.sql_alter_column % {
|
1064
|
-
"table": self.quote_name(model.
|
1070
|
+
"table": self.quote_name(model.model_options.db_table),
|
1065
1071
|
"changes": changes_sql,
|
1066
1072
|
}
|
1067
1073
|
self.execute(sql, params)
|
@@ -1157,7 +1163,7 @@ class BaseDatabaseSchemaEditor:
|
|
1157
1163
|
"""
|
1158
1164
|
other_actions = []
|
1159
1165
|
if collate_sql := self._collate_sql(
|
1160
|
-
new_collation, old_collation, model.
|
1166
|
+
new_collation, old_collation, model.model_options.db_table
|
1161
1167
|
):
|
1162
1168
|
collate_sql = f" {collate_sql}"
|
1163
1169
|
else:
|
@@ -1199,7 +1205,7 @@ class BaseDatabaseSchemaEditor:
|
|
1199
1205
|
return (
|
1200
1206
|
self.sql_alter_column_comment
|
1201
1207
|
% {
|
1202
|
-
"table": self.quote_name(model.
|
1208
|
+
"table": self.quote_name(model.model_options.db_table),
|
1203
1209
|
"column": self.quote_name(new_field.column),
|
1204
1210
|
"comment": self._comment_sql(new_db_comment),
|
1205
1211
|
},
|
@@ -1210,37 +1216,45 @@ class BaseDatabaseSchemaEditor:
|
|
1210
1216
|
return self.quote_value(comment or "")
|
1211
1217
|
|
1212
1218
|
def _alter_many_to_many(
|
1213
|
-
self,
|
1219
|
+
self,
|
1220
|
+
model: type[Model],
|
1221
|
+
old_field: ManyToManyField,
|
1222
|
+
new_field: ManyToManyField,
|
1223
|
+
strict: bool,
|
1214
1224
|
) -> None:
|
1215
1225
|
"""Alter M2Ms to repoint their to= endpoints."""
|
1226
|
+
# Type narrow for ManyToManyField.remote_field
|
1227
|
+
old_rel: ManyToManyRel = old_field.remote_field # type: ignore[assignment]
|
1228
|
+
new_rel: ManyToManyRel = new_field.remote_field # type: ignore[assignment]
|
1229
|
+
|
1216
1230
|
# Rename the through table
|
1217
1231
|
if (
|
1218
|
-
|
1219
|
-
!=
|
1232
|
+
old_rel.through.model_options.db_table
|
1233
|
+
!= new_rel.through.model_options.db_table
|
1220
1234
|
):
|
1221
1235
|
self.alter_db_table(
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1236
|
+
old_rel.through,
|
1237
|
+
old_rel.through.model_options.db_table,
|
1238
|
+
new_rel.through.model_options.db_table,
|
1225
1239
|
)
|
1226
1240
|
# Repoint the FK to the other side
|
1227
1241
|
self.alter_field(
|
1228
|
-
|
1242
|
+
new_rel.through,
|
1229
1243
|
# The field that points to the target model is needed, so we can
|
1230
1244
|
# tell alter_field to change it - this is m2m_reverse_field_name()
|
1231
1245
|
# (as opposed to m2m_field_name(), which points to our model).
|
1232
|
-
|
1246
|
+
old_rel.through._model_meta.get_field(
|
1233
1247
|
old_field.m2m_reverse_field_name() # type: ignore[attr-defined]
|
1234
1248
|
),
|
1235
|
-
|
1249
|
+
new_rel.through._model_meta.get_field(
|
1236
1250
|
new_field.m2m_reverse_field_name() # type: ignore[attr-defined]
|
1237
1251
|
),
|
1238
1252
|
)
|
1239
1253
|
self.alter_field(
|
1240
|
-
|
1254
|
+
new_rel.through,
|
1241
1255
|
# for self-referential models we need to alter field from the other end too
|
1242
|
-
|
1243
|
-
|
1256
|
+
old_rel.through._model_meta.get_field(old_field.m2m_field_name()),
|
1257
|
+
new_rel.through._model_meta.get_field(new_field.m2m_field_name()),
|
1244
1258
|
)
|
1245
1259
|
|
1246
1260
|
def _create_index_name(
|
@@ -1290,7 +1304,7 @@ class BaseDatabaseSchemaEditor:
|
|
1290
1304
|
return ""
|
1291
1305
|
return Statement(
|
1292
1306
|
" INCLUDE (%(columns)s)",
|
1293
|
-
columns=Columns(model.
|
1307
|
+
columns=Columns(model.model_options.db_table, columns, self.quote_name),
|
1294
1308
|
)
|
1295
1309
|
|
1296
1310
|
def _create_index_sql(
|
@@ -1318,7 +1332,7 @@ class BaseDatabaseSchemaEditor:
|
|
1318
1332
|
compiler = Query(model, alias_cols=False).get_compiler()
|
1319
1333
|
columns = [field.column for field in fields]
|
1320
1334
|
sql_create_index = sql or self.sql_create_index
|
1321
|
-
table = model.
|
1335
|
+
table = model.model_options.db_table
|
1322
1336
|
|
1323
1337
|
def create_index_name(*args: Any, **kwargs: Any) -> str:
|
1324
1338
|
nonlocal name
|
@@ -1346,7 +1360,7 @@ class BaseDatabaseSchemaEditor:
|
|
1346
1360
|
) -> Statement:
|
1347
1361
|
return Statement(
|
1348
1362
|
sql or self.sql_delete_index,
|
1349
|
-
table=Table(model.
|
1363
|
+
table=Table(model.model_options.db_table, self.quote_name),
|
1350
1364
|
name=self.quote_name(name),
|
1351
1365
|
)
|
1352
1366
|
|
@@ -1355,7 +1369,7 @@ class BaseDatabaseSchemaEditor:
|
|
1355
1369
|
) -> Statement:
|
1356
1370
|
return Statement(
|
1357
1371
|
self.sql_rename_index,
|
1358
|
-
table=Table(model.
|
1372
|
+
table=Table(model.model_options.db_table, self.quote_name),
|
1359
1373
|
old_name=self.quote_name(old_name),
|
1360
1374
|
new_name=self.quote_name(new_name),
|
1361
1375
|
)
|
@@ -1374,10 +1388,10 @@ class BaseDatabaseSchemaEditor:
|
|
1374
1388
|
Return a list of all index SQL statements (field indexes, Meta.indexes) for the specified model.
|
1375
1389
|
"""
|
1376
1390
|
output: list[Statement | None] = []
|
1377
|
-
for field in model.
|
1391
|
+
for field in model._model_meta.local_fields:
|
1378
1392
|
output.extend(self._field_indexes_sql(model, field))
|
1379
1393
|
|
1380
|
-
for index in model.
|
1394
|
+
for index in model.model_options.indexes:
|
1381
1395
|
if (
|
1382
1396
|
not index.contains_expressions
|
1383
1397
|
or self.connection.features.supports_expression_indexes
|
@@ -1430,14 +1444,16 @@ class BaseDatabaseSchemaEditor:
|
|
1430
1444
|
}
|
1431
1445
|
|
1432
1446
|
def _create_fk_sql(
|
1433
|
-
self, model: type[Model], field:
|
1447
|
+
self, model: type[Model], field: ForeignKey, suffix: str
|
1434
1448
|
) -> Statement:
|
1435
|
-
table = Table(model.
|
1449
|
+
table = Table(model.model_options.db_table, self.quote_name)
|
1436
1450
|
name = self._fk_constraint_name(model, field, suffix)
|
1437
|
-
column = Columns(model.
|
1438
|
-
to_table = Table(
|
1451
|
+
column = Columns(model.model_options.db_table, [field.column], self.quote_name)
|
1452
|
+
to_table = Table(
|
1453
|
+
field.target_field.model.model_options.db_table, self.quote_name
|
1454
|
+
)
|
1439
1455
|
to_column = Columns(
|
1440
|
-
field.target_field.model.
|
1456
|
+
field.target_field.model.model_options.db_table,
|
1441
1457
|
[field.target_field.column], # type: ignore[attr-defined]
|
1442
1458
|
self.quote_name,
|
1443
1459
|
)
|
@@ -1453,15 +1469,15 @@ class BaseDatabaseSchemaEditor:
|
|
1453
1469
|
)
|
1454
1470
|
|
1455
1471
|
def _fk_constraint_name(
|
1456
|
-
self, model: type[Model], field:
|
1472
|
+
self, model: type[Model], field: ForeignKey, suffix: str
|
1457
1473
|
) -> ForeignKeyName:
|
1458
1474
|
def create_fk_name(*args: Any, **kwargs: Any) -> str:
|
1459
1475
|
return self.quote_name(self._create_index_name(*args, **kwargs))
|
1460
1476
|
|
1461
1477
|
return ForeignKeyName(
|
1462
|
-
model.
|
1478
|
+
model.model_options.db_table,
|
1463
1479
|
[field.column],
|
1464
|
-
split_identifier(field.target_field.model.
|
1480
|
+
split_identifier(field.target_field.model.model_options.db_table)[1],
|
1465
1481
|
[field.target_field.column], # type: ignore[attr-defined]
|
1466
1482
|
suffix,
|
1467
1483
|
create_fk_name,
|
@@ -1544,7 +1560,7 @@ class BaseDatabaseSchemaEditor:
|
|
1544
1560
|
return None
|
1545
1561
|
|
1546
1562
|
compiler = Query(model, alias_cols=False).get_compiler()
|
1547
|
-
table = model.
|
1563
|
+
table = model.model_options.db_table
|
1548
1564
|
columns = [field.column for field in fields]
|
1549
1565
|
if name is None:
|
1550
1566
|
name = self._unique_constraint_name(table, columns, quote=True)
|
@@ -1624,7 +1640,7 @@ class BaseDatabaseSchemaEditor:
|
|
1624
1640
|
return None
|
1625
1641
|
return Statement(
|
1626
1642
|
self.sql_create_check,
|
1627
|
-
table=Table(model.
|
1643
|
+
table=Table(model.model_options.db_table, self.quote_name),
|
1628
1644
|
name=self.quote_name(name),
|
1629
1645
|
check=check,
|
1630
1646
|
)
|
@@ -1639,7 +1655,7 @@ class BaseDatabaseSchemaEditor:
|
|
1639
1655
|
) -> Statement:
|
1640
1656
|
return Statement(
|
1641
1657
|
template,
|
1642
|
-
table=Table(model.
|
1658
|
+
table=Table(model.model_options.db_table, self.quote_name),
|
1643
1659
|
name=self.quote_name(name),
|
1644
1660
|
)
|
1645
1661
|
|
@@ -1667,7 +1683,7 @@ class BaseDatabaseSchemaEditor:
|
|
1667
1683
|
]
|
1668
1684
|
with self.connection.cursor() as cursor:
|
1669
1685
|
constraints = self.connection.introspection.get_constraints(
|
1670
|
-
cursor, model.
|
1686
|
+
cursor, model.model_options.db_table
|
1671
1687
|
)
|
1672
1688
|
result: list[str] = []
|
1673
1689
|
for name, infodict in constraints.items():
|
@@ -1692,7 +1708,7 @@ class BaseDatabaseSchemaEditor:
|
|
1692
1708
|
constraint_names = self._constraint_names(model, primary_key=True)
|
1693
1709
|
if strict and len(constraint_names) != 1:
|
1694
1710
|
raise ValueError(
|
1695
|
-
f"Found wrong number ({len(constraint_names)}) of PK constraints for {model.
|
1711
|
+
f"Found wrong number ({len(constraint_names)}) of PK constraints for {model.model_options.db_table}"
|
1696
1712
|
)
|
1697
1713
|
for constraint_name in constraint_names:
|
1698
1714
|
self.execute(self._delete_primary_key_sql(model, constraint_name))
|
@@ -1700,13 +1716,15 @@ class BaseDatabaseSchemaEditor:
|
|
1700
1716
|
def _create_primary_key_sql(self, model: type[Model], field: Field) -> Statement:
|
1701
1717
|
return Statement(
|
1702
1718
|
self.sql_create_pk,
|
1703
|
-
table=Table(model.
|
1719
|
+
table=Table(model.model_options.db_table, self.quote_name),
|
1704
1720
|
name=self.quote_name(
|
1705
1721
|
self._create_index_name(
|
1706
|
-
model.
|
1722
|
+
model.model_options.db_table, [field.column], suffix="_pk"
|
1707
1723
|
)
|
1708
1724
|
),
|
1709
|
-
columns=Columns(
|
1725
|
+
columns=Columns(
|
1726
|
+
model.model_options.db_table, [field.column], self.quote_name
|
1727
|
+
),
|
1710
1728
|
)
|
1711
1729
|
|
1712
1730
|
def _delete_primary_key_sql(self, model: type[Model], name: str) -> Statement:
|
@@ -28,7 +28,7 @@ class BaseDatabaseValidation:
|
|
28
28
|
# Ignore fields with unsupported features.
|
29
29
|
db_supports_all_required_features = all(
|
30
30
|
getattr(self.connection.features, feature, False)
|
31
|
-
for feature in field.model.
|
31
|
+
for feature in field.model.model_options.required_db_features
|
32
32
|
)
|
33
33
|
if db_supports_all_required_features:
|
34
34
|
field_type = field.db_type(self.connection)
|
@@ -66,7 +66,7 @@ class SQLUpdateCompiler(compiler.SQLUpdateCompiler, SQLCompiler):
|
|
66
66
|
if self.query.order_by:
|
67
67
|
order_by_sql = []
|
68
68
|
order_by_params = []
|
69
|
-
db_table = self.query.
|
69
|
+
db_table = self.query.get_model_meta().db_table
|
70
70
|
try:
|
71
71
|
for resolved, (sql, params, _) in self.get_order_by():
|
72
72
|
if (
|
@@ -233,7 +233,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
|
233
233
|
if not fields:
|
234
234
|
return "", ()
|
235
235
|
columns = [
|
236
|
-
f"{self.quote_name(field.model.
|
236
|
+
f"{self.quote_name(field.model.model_options.db_table)}.{self.quote_name(field.column)}"
|
237
237
|
for field in fields
|
238
238
|
]
|
239
239
|
return "RETURNING {}".format(", ".join(columns)), ()
|
@@ -125,7 +125,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
|
125
125
|
if self.skip_default(field) and field.default not in (None, NOT_PROVIDED):
|
126
126
|
effective_default = self.effective_default(field)
|
127
127
|
self.execute(
|
128
|
-
f"UPDATE {self.quote_name(model.
|
128
|
+
f"UPDATE {self.quote_name(model.model_options.db_table)} SET {self.quote_name(field.column)} = %s",
|
129
129
|
[effective_default],
|
130
130
|
)
|
131
131
|
|
@@ -154,7 +154,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
|
154
154
|
return False
|
155
155
|
|
156
156
|
storage = self.connection.introspection.get_storage_engine(
|
157
|
-
self.connection.cursor(), model.
|
157
|
+
self.connection.cursor(), model.model_options.db_table
|
158
158
|
)
|
159
159
|
# No need to create an index for ForeignKey fields except if
|
160
160
|
# db_constraint=False because the index from that constraint won't be
|
@@ -197,7 +197,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
|
197
197
|
if not first_field_name:
|
198
198
|
return
|
199
199
|
|
200
|
-
first_field = model.
|
200
|
+
first_field = model._model_meta.get_field(first_field_name)
|
201
201
|
if first_field.get_internal_type() == "ForeignKey":
|
202
202
|
column = self.connection.introspection.identifier_converter(
|
203
203
|
first_field.column
|
@@ -206,7 +206,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
|
206
206
|
constraint_names = [
|
207
207
|
name
|
208
208
|
for name, infodict in self.connection.introspection.get_constraints(
|
209
|
-
cursor, model.
|
209
|
+
cursor, model.model_options.db_table
|
210
210
|
).items()
|
211
211
|
if infodict["index"] and infodict["columns"][0] == column
|
212
212
|
]
|
@@ -270,7 +270,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
|
270
270
|
if not fields:
|
271
271
|
return "", ()
|
272
272
|
columns = [
|
273
|
-
f"{self.quote_name(field.model.
|
273
|
+
f"{self.quote_name(field.model.model_options.db_table)}.{self.quote_name(field.column)}"
|
274
274
|
for field in fields
|
275
275
|
]
|
276
276
|
return "RETURNING {}".format(", ".join(columns)), ()
|
@@ -173,7 +173,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
|
173
173
|
or (old_type.startswith("citext") and not new_type.startswith("citext"))
|
174
174
|
):
|
175
175
|
index_name = self._create_index_name(
|
176
|
-
model.
|
176
|
+
model.model_options.db_table, [old_field.column], suffix="_like"
|
177
177
|
)
|
178
178
|
self.execute(self._delete_index_sql(model, index_name))
|
179
179
|
|
@@ -186,7 +186,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
|
186
186
|
new_internal_type = new_field.get_internal_type()
|
187
187
|
old_internal_type = old_field.get_internal_type()
|
188
188
|
# Make ALTER TYPE with IDENTITY make sense.
|
189
|
-
table = strip_quotes(model.
|
189
|
+
table = strip_quotes(model.model_options.db_table)
|
190
190
|
auto_field_types = {"PrimaryKeyField"}
|
191
191
|
old_is_auto = old_internal_type in auto_field_types
|
192
192
|
new_is_auto = new_internal_type in auto_field_types
|
@@ -306,7 +306,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
|
306
306
|
or new_field.primary_key
|
307
307
|
):
|
308
308
|
index_to_remove = self._create_index_name(
|
309
|
-
model.
|
309
|
+
model.model_options.db_table, [old_field.column], suffix="_like"
|
310
310
|
)
|
311
311
|
self.execute(self._delete_index_sql(model, index_to_remove))
|
312
312
|
|
@@ -439,7 +439,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
|
439
439
|
if not fields:
|
440
440
|
return "", ()
|
441
441
|
columns = [
|
442
|
-
f"{self.quote_name(field.model.
|
442
|
+
f"{self.quote_name(field.model.model_options.db_table)}.{self.quote_name(field.column)}"
|
443
443
|
for field in fields
|
444
444
|
]
|
445
445
|
return "RETURNING {}".format(", ".join(columns)), ()
|