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
@@ -51,10 +51,8 @@ from functools import cached_property
|
|
51
51
|
from plain.exceptions import FieldError
|
52
52
|
from plain.models import transaction
|
53
53
|
from plain.models.db import (
|
54
|
-
DEFAULT_DB_ALIAS,
|
55
54
|
NotSupportedError,
|
56
|
-
|
57
|
-
router,
|
55
|
+
db_connection,
|
58
56
|
)
|
59
57
|
from plain.models.expressions import Window
|
60
58
|
from plain.models.functions import RowNumber
|
@@ -75,17 +73,14 @@ class ForeignKeyDeferredAttribute(DeferredAttribute):
|
|
75
73
|
|
76
74
|
def _filter_prefetch_queryset(queryset, field_name, instances):
|
77
75
|
predicate = Q(**{f"{field_name}__in": instances})
|
78
|
-
db = queryset._db or DEFAULT_DB_ALIAS
|
79
76
|
if queryset.query.is_sliced:
|
80
|
-
if not
|
77
|
+
if not db_connection.features.supports_over_clause:
|
81
78
|
raise NotSupportedError(
|
82
79
|
"Prefetching from a limited queryset is only supported on backends "
|
83
80
|
"that support window functions."
|
84
81
|
)
|
85
82
|
low_mark, high_mark = queryset.query.low_mark, queryset.query.high_mark
|
86
|
-
order_by = [
|
87
|
-
expr for expr, _ in queryset.query.get_compiler(using=db).get_order_by()
|
88
|
-
]
|
83
|
+
order_by = [expr for expr, _ in queryset.query.get_compiler().get_order_by()]
|
89
84
|
window = Window(RowNumber(), partition_by=field_name, order_by=order_by)
|
90
85
|
predicate &= GreaterThan(window, low_mark)
|
91
86
|
if high_mark is not None:
|
@@ -127,7 +122,9 @@ class ForwardManyToOneDescriptor:
|
|
127
122
|
return self.field.is_cached(instance)
|
128
123
|
|
129
124
|
def get_queryset(self, **hints):
|
130
|
-
|
125
|
+
qs = self.field.remote_field.model._base_manager.get_queryset()
|
126
|
+
qs._add_hints(**hints)
|
127
|
+
return qs.all()
|
131
128
|
|
132
129
|
def get_prefetch_queryset(self, instances, queryset=None):
|
133
130
|
if queryset is None:
|
@@ -232,21 +229,6 @@ class ForwardManyToOneDescriptor:
|
|
232
229
|
raise ValueError(
|
233
230
|
f'Cannot assign "{value!r}": "{instance._meta.object_name}.{self.field.name}" must be a "{self.field.remote_field.model._meta.object_name}" instance.'
|
234
231
|
)
|
235
|
-
elif value is not None:
|
236
|
-
if instance._state.db is None:
|
237
|
-
instance._state.db = router.db_for_write(
|
238
|
-
instance.__class__, instance=value
|
239
|
-
)
|
240
|
-
if value._state.db is None:
|
241
|
-
value._state.db = router.db_for_write(
|
242
|
-
value.__class__, instance=instance
|
243
|
-
)
|
244
|
-
if not router.allow_relation(value, instance):
|
245
|
-
raise ValueError(
|
246
|
-
f'Cannot assign "{value!r}": the current database router prevents this '
|
247
|
-
"relation."
|
248
|
-
)
|
249
|
-
|
250
232
|
remote_field = self.field.remote_field
|
251
233
|
# If we're setting the value of a OneToOneField to None, we need to clear
|
252
234
|
# out the cache on any old related object. Otherwise, deleting the
|
@@ -387,13 +369,10 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
|
387
369
|
"""
|
388
370
|
Filter the queryset for the instance this manager is bound to.
|
389
371
|
"""
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
].features.interprets_empty_strings_as_nulls
|
372
|
+
empty_strings_as_null = (
|
373
|
+
db_connection.features.interprets_empty_strings_as_nulls
|
374
|
+
)
|
394
375
|
queryset._add_hints(instance=self.instance)
|
395
|
-
if self._db:
|
396
|
-
queryset = queryset.using(self._db)
|
397
376
|
queryset._defer_next_filter = True
|
398
377
|
queryset = queryset.filter(**self.core_filters)
|
399
378
|
for field in self.field.foreign_related_fields:
|
@@ -453,7 +432,6 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
|
453
432
|
queryset = super().get_queryset()
|
454
433
|
|
455
434
|
queryset._add_hints(instance=instances[0])
|
456
|
-
queryset = queryset.using(queryset._db or self._db)
|
457
435
|
|
458
436
|
rel_obj_attr = self.field.get_local_related_value
|
459
437
|
instance_attr = self.field.get_foreign_related_value
|
@@ -472,7 +450,6 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
|
472
450
|
def add(self, *objs, bulk=True):
|
473
451
|
self._check_fk_val()
|
474
452
|
self._remove_prefetched_objects()
|
475
|
-
db = router.db_for_write(self.model, instance=self.instance)
|
476
453
|
|
477
454
|
def check_and_update_obj(obj):
|
478
455
|
if not isinstance(obj, self.model):
|
@@ -485,19 +462,19 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
|
485
462
|
pks = []
|
486
463
|
for obj in objs:
|
487
464
|
check_and_update_obj(obj)
|
488
|
-
if obj._state.adding
|
465
|
+
if obj._state.adding:
|
489
466
|
raise ValueError(
|
490
467
|
f"{obj!r} instance isn't saved. Use bulk=False or save "
|
491
468
|
"the object first."
|
492
469
|
)
|
493
470
|
pks.append(obj.pk)
|
494
|
-
self.model._base_manager.
|
471
|
+
self.model._base_manager.filter(pk__in=pks).update(
|
495
472
|
**{
|
496
473
|
self.field.name: self.instance,
|
497
474
|
}
|
498
475
|
)
|
499
476
|
else:
|
500
|
-
with transaction.atomic(
|
477
|
+
with transaction.atomic(savepoint=False):
|
501
478
|
for obj in objs:
|
502
479
|
check_and_update_obj(obj)
|
503
480
|
obj.save()
|
@@ -505,20 +482,17 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
|
505
482
|
def create(self, **kwargs):
|
506
483
|
self._check_fk_val()
|
507
484
|
kwargs[self.field.name] = self.instance
|
508
|
-
|
509
|
-
return super(RelatedManager, self.db_manager(db)).create(**kwargs)
|
485
|
+
return super().create(**kwargs)
|
510
486
|
|
511
487
|
def get_or_create(self, **kwargs):
|
512
488
|
self._check_fk_val()
|
513
489
|
kwargs[self.field.name] = self.instance
|
514
|
-
|
515
|
-
return super(RelatedManager, self.db_manager(db)).get_or_create(**kwargs)
|
490
|
+
return super().get_or_create(**kwargs)
|
516
491
|
|
517
492
|
def update_or_create(self, **kwargs):
|
518
493
|
self._check_fk_val()
|
519
494
|
kwargs[self.field.name] = self.instance
|
520
|
-
|
521
|
-
return super(RelatedManager, self.db_manager(db)).update_or_create(**kwargs)
|
495
|
+
return super().update_or_create(**kwargs)
|
522
496
|
|
523
497
|
# remove() and clear() are only provided if the ForeignKey can have a
|
524
498
|
# value of null.
|
@@ -550,13 +524,11 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
|
550
524
|
|
551
525
|
def _clear(self, queryset, bulk):
|
552
526
|
self._remove_prefetched_objects()
|
553
|
-
db = router.db_for_write(self.model, instance=self.instance)
|
554
|
-
queryset = queryset.using(db)
|
555
527
|
if bulk:
|
556
528
|
# `QuerySet.update()` is intrinsically atomic.
|
557
529
|
queryset.update(**{self.field.name: None})
|
558
530
|
else:
|
559
|
-
with transaction.atomic(
|
531
|
+
with transaction.atomic(savepoint=False):
|
560
532
|
for obj in queryset:
|
561
533
|
setattr(obj, self.field.name, None)
|
562
534
|
obj.save(update_fields=[self.field.name])
|
@@ -568,13 +540,12 @@ def create_reverse_many_to_one_manager(superclass, rel):
|
|
568
540
|
objs = tuple(objs)
|
569
541
|
|
570
542
|
if self.field.allow_null:
|
571
|
-
|
572
|
-
with transaction.atomic(using=db, savepoint=False):
|
543
|
+
with transaction.atomic(savepoint=False):
|
573
544
|
if clear:
|
574
545
|
self.clear(bulk=bulk)
|
575
546
|
self.add(*objs, bulk=bulk)
|
576
547
|
else:
|
577
|
-
old_objs = set(self.
|
548
|
+
old_objs = set(self.all())
|
578
549
|
new_objs = []
|
579
550
|
for obj in objs:
|
580
551
|
if obj in old_objs:
|
@@ -726,8 +697,6 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
726
697
|
Filter the queryset for the instance this manager is bound to.
|
727
698
|
"""
|
728
699
|
queryset._add_hints(instance=self.instance)
|
729
|
-
if self._db:
|
730
|
-
queryset = queryset.using(self._db)
|
731
700
|
queryset._defer_next_filter = True
|
732
701
|
return queryset._next_is_sticky().filter(**self.core_filters)
|
733
702
|
|
@@ -749,7 +718,6 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
749
718
|
queryset = super().get_queryset()
|
750
719
|
|
751
720
|
queryset._add_hints(instance=instances[0])
|
752
|
-
queryset = queryset.using(queryset._db or self._db)
|
753
721
|
queryset = _filter_prefetch_queryset(
|
754
722
|
queryset._next_is_sticky(), self.query_field_name, instances
|
755
723
|
)
|
@@ -763,8 +731,7 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
763
731
|
# dealing with PK values.
|
764
732
|
fk = self.through._meta.get_field(self.source_field_name)
|
765
733
|
join_table = fk.model._meta.db_table
|
766
|
-
|
767
|
-
qn = connection.ops.quote_name
|
734
|
+
qn = db_connection.ops.quote_name
|
768
735
|
queryset = queryset.extra(
|
769
736
|
select={
|
770
737
|
f"_prefetch_related_val_{f.attname}": f"{qn(join_table)}.{qn(f.column)}"
|
@@ -778,7 +745,7 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
778
745
|
for f in fk.local_related_fields
|
779
746
|
),
|
780
747
|
lambda inst: tuple(
|
781
|
-
f.get_db_prep_value(getattr(inst, f.attname),
|
748
|
+
f.get_db_prep_value(getattr(inst, f.attname), db_connection)
|
782
749
|
for f in fk.foreign_related_fields
|
783
750
|
),
|
784
751
|
False,
|
@@ -788,8 +755,7 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
788
755
|
|
789
756
|
def add(self, *objs, through_defaults=None):
|
790
757
|
self._remove_prefetched_objects()
|
791
|
-
|
792
|
-
with transaction.atomic(using=db, savepoint=False):
|
758
|
+
with transaction.atomic(savepoint=False):
|
793
759
|
self._add_items(
|
794
760
|
self.source_field_name,
|
795
761
|
self.target_field_name,
|
@@ -811,25 +777,23 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
811
777
|
self._remove_items(self.source_field_name, self.target_field_name, *objs)
|
812
778
|
|
813
779
|
def clear(self):
|
814
|
-
|
815
|
-
with transaction.atomic(using=db, savepoint=False):
|
780
|
+
with transaction.atomic(savepoint=False):
|
816
781
|
self._remove_prefetched_objects()
|
817
|
-
filters = self._build_remove_filters(super().get_queryset()
|
818
|
-
self.through._default_manager.
|
782
|
+
filters = self._build_remove_filters(super().get_queryset())
|
783
|
+
self.through._default_manager.filter(filters).delete()
|
819
784
|
|
820
785
|
def set(self, objs, *, clear=False, through_defaults=None):
|
821
786
|
# Force evaluation of `objs` in case it's a queryset whose value
|
822
787
|
# could be affected by `manager.clear()`. Refs #19816.
|
823
788
|
objs = tuple(objs)
|
824
789
|
|
825
|
-
|
826
|
-
with transaction.atomic(using=db, savepoint=False):
|
790
|
+
with transaction.atomic(savepoint=False):
|
827
791
|
if clear:
|
828
792
|
self.clear()
|
829
793
|
self.add(*objs, through_defaults=through_defaults)
|
830
794
|
else:
|
831
795
|
old_ids = set(
|
832
|
-
self.
|
796
|
+
self.values_list(
|
833
797
|
self.target_field.target_field.attname, flat=True
|
834
798
|
)
|
835
799
|
)
|
@@ -850,16 +814,12 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
850
814
|
self.add(*new_objs, through_defaults=through_defaults)
|
851
815
|
|
852
816
|
def create(self, *, through_defaults=None, **kwargs):
|
853
|
-
|
854
|
-
new_obj = super(ManyRelatedManager, self.db_manager(db)).create(**kwargs)
|
817
|
+
new_obj = super().create(**kwargs)
|
855
818
|
self.add(new_obj, through_defaults=through_defaults)
|
856
819
|
return new_obj
|
857
820
|
|
858
821
|
def get_or_create(self, *, through_defaults=None, **kwargs):
|
859
|
-
|
860
|
-
obj, created = super(ManyRelatedManager, self.db_manager(db)).get_or_create(
|
861
|
-
**kwargs
|
862
|
-
)
|
822
|
+
obj, created = super().get_or_create(**kwargs)
|
863
823
|
# We only need to add() if created because if we got an object back
|
864
824
|
# from get() then the relationship already exists.
|
865
825
|
if created:
|
@@ -867,10 +827,7 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
867
827
|
return obj, created
|
868
828
|
|
869
829
|
def update_or_create(self, *, through_defaults=None, **kwargs):
|
870
|
-
|
871
|
-
obj, created = super(
|
872
|
-
ManyRelatedManager, self.db_manager(db)
|
873
|
-
).update_or_create(**kwargs)
|
830
|
+
obj, created = super().update_or_create(**kwargs)
|
874
831
|
# We only need to add() if created because if we got an object back
|
875
832
|
# from get() then the relationship already exists.
|
876
833
|
if created:
|
@@ -887,11 +844,6 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
887
844
|
target_field = self.through._meta.get_field(target_field_name)
|
888
845
|
for obj in objs:
|
889
846
|
if isinstance(obj, self.model):
|
890
|
-
if not router.allow_relation(obj, self.instance):
|
891
|
-
raise ValueError(
|
892
|
-
f'Cannot add "{obj!r}": instance is on database "{self.instance._state.db}", '
|
893
|
-
f'value is on database "{obj._state.db}"'
|
894
|
-
)
|
895
847
|
target_id = target_field.get_foreign_related_value(obj)[0]
|
896
848
|
if target_id is None:
|
897
849
|
raise ValueError(
|
@@ -907,21 +859,19 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
907
859
|
return target_ids
|
908
860
|
|
909
861
|
def _get_missing_target_ids(
|
910
|
-
self, source_field_name, target_field_name,
|
862
|
+
self, source_field_name, target_field_name, target_ids
|
911
863
|
):
|
912
864
|
"""
|
913
865
|
Return the subset of ids of `objs` that aren't already assigned to
|
914
866
|
this relationship.
|
915
867
|
"""
|
916
|
-
vals = (
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
}
|
924
|
-
)
|
868
|
+
vals = self.through._default_manager.values_list(
|
869
|
+
target_field_name, flat=True
|
870
|
+
).filter(
|
871
|
+
**{
|
872
|
+
source_field_name: self.related_val[0],
|
873
|
+
f"{target_field_name}__in": target_ids,
|
874
|
+
}
|
925
875
|
)
|
926
876
|
return target_ids.difference(vals)
|
927
877
|
|
@@ -937,14 +887,13 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
937
887
|
|
938
888
|
through_defaults = dict(resolve_callables(through_defaults or {}))
|
939
889
|
target_ids = self._get_target_ids(target_field_name, objs)
|
940
|
-
db = router.db_for_write(self.through, instance=self.instance)
|
941
890
|
|
942
891
|
missing_target_ids = self._get_missing_target_ids(
|
943
|
-
source_field_name, target_field_name,
|
892
|
+
source_field_name, target_field_name, target_ids
|
944
893
|
)
|
945
|
-
with transaction.atomic(
|
894
|
+
with transaction.atomic(savepoint=False):
|
946
895
|
# Add the ones that aren't there already.
|
947
|
-
self.through._default_manager.
|
896
|
+
self.through._default_manager.bulk_create(
|
948
897
|
[
|
949
898
|
self.through(
|
950
899
|
**through_defaults,
|
@@ -974,16 +923,15 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
|
974
923
|
else:
|
975
924
|
old_ids.add(obj)
|
976
925
|
|
977
|
-
|
978
|
-
with transaction.atomic(using=db, savepoint=False):
|
926
|
+
with transaction.atomic(savepoint=False):
|
979
927
|
target_model_qs = super().get_queryset()
|
980
928
|
if target_model_qs._has_filters():
|
981
|
-
old_vals = target_model_qs.
|
929
|
+
old_vals = target_model_qs.filter(
|
982
930
|
**{f"{self.target_field.target_field.attname}__in": old_ids}
|
983
931
|
)
|
984
932
|
else:
|
985
933
|
old_vals = old_ids
|
986
934
|
filters = self._build_remove_filters(old_vals)
|
987
|
-
self.through._default_manager.
|
935
|
+
self.through._default_manager.filter(filters).delete()
|
988
936
|
|
989
937
|
return ManyRelatedManager
|
plain/models/forms.py
CHANGED
@@ -770,13 +770,11 @@ def modelfield_to_formfield(
|
|
770
770
|
# will be validated twice. This is considered acceptable since we want
|
771
771
|
# the value in the form field (to pass into widget for example).
|
772
772
|
# TODO: Handle multiple backends with different feature flags.
|
773
|
-
from plain.models.db import
|
773
|
+
from plain.models.db import db_connection
|
774
774
|
|
775
775
|
if (
|
776
776
|
modelfield.allow_null
|
777
|
-
and not
|
778
|
-
DEFAULT_DB_ALIAS
|
779
|
-
].features.interprets_empty_strings_as_nulls
|
777
|
+
and not db_connection.features.interprets_empty_strings_as_nulls
|
780
778
|
):
|
781
779
|
defaults["empty_value"] = None
|
782
780
|
return fields.CharField(
|
plain/models/indexes.py
CHANGED
@@ -85,11 +85,11 @@ class Index:
|
|
85
85
|
return None
|
86
86
|
query = Query(model=model, alias_cols=False)
|
87
87
|
where = query.build_where(self.condition)
|
88
|
-
compiler = query.get_compiler(
|
88
|
+
compiler = query.get_compiler()
|
89
89
|
sql, params = where.as_sql(compiler, schema_editor.connection)
|
90
90
|
return sql % tuple(schema_editor.quote_value(p) for p in params)
|
91
91
|
|
92
|
-
def create_sql(self, model, schema_editor,
|
92
|
+
def create_sql(self, model, schema_editor, **kwargs):
|
93
93
|
include = [
|
94
94
|
model._meta.get_field(field_name).column for field_name in self.include
|
95
95
|
]
|
@@ -119,7 +119,6 @@ class Index:
|
|
119
119
|
model,
|
120
120
|
fields=fields,
|
121
121
|
name=self.name,
|
122
|
-
using=using,
|
123
122
|
col_suffixes=col_suffixes,
|
124
123
|
opclasses=self.opclasses,
|
125
124
|
condition=condition,
|
plain/models/lookups.py
CHANGED
@@ -448,13 +448,6 @@ class In(FieldGetDbPrepValueIterableMixin, BuiltinLookup):
|
|
448
448
|
return super().get_prep_lookup()
|
449
449
|
|
450
450
|
def process_rhs(self, compiler, connection):
|
451
|
-
db_rhs = getattr(self.rhs, "_db", None)
|
452
|
-
if db_rhs is not None and db_rhs != connection.alias:
|
453
|
-
raise ValueError(
|
454
|
-
"Subqueries aren't allowed across different databases. Force "
|
455
|
-
"the inner query to be evaluated using `list(inner_query)`."
|
456
|
-
)
|
457
|
-
|
458
451
|
if self.rhs_is_direct_value():
|
459
452
|
# Remove None from the list as NULL is never equal to anything.
|
460
453
|
try:
|
plain/models/manager.py
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
import copy
|
2
1
|
import inspect
|
3
2
|
from functools import wraps
|
4
3
|
from importlib import import_module
|
5
4
|
|
6
|
-
from plain.models.db import router
|
7
5
|
from plain.models.query import QuerySet
|
8
6
|
|
9
7
|
|
@@ -29,7 +27,6 @@ class BaseManager:
|
|
29
27
|
self._set_creation_counter()
|
30
28
|
self.model = None
|
31
29
|
self.name = None
|
32
|
-
self._db = None
|
33
30
|
self._hints = {}
|
34
31
|
|
35
32
|
def __str__(self):
|
@@ -132,16 +129,6 @@ class BaseManager:
|
|
132
129
|
self.creation_counter = BaseManager.creation_counter
|
133
130
|
BaseManager.creation_counter += 1
|
134
131
|
|
135
|
-
def db_manager(self, using=None, hints=None):
|
136
|
-
obj = copy.copy(self)
|
137
|
-
obj._db = using or self._db
|
138
|
-
obj._hints = hints or self._hints
|
139
|
-
return obj
|
140
|
-
|
141
|
-
@property
|
142
|
-
def db(self):
|
143
|
-
return self._db or router.db_for_read(self.model, **self._hints)
|
144
|
-
|
145
132
|
#######################
|
146
133
|
# PROXIES TO QUERYSET #
|
147
134
|
#######################
|
@@ -151,7 +138,7 @@ class BaseManager:
|
|
151
138
|
Return a new QuerySet object. Subclasses can override this method to
|
152
139
|
customize the behavior of the Manager.
|
153
140
|
"""
|
154
|
-
return self._queryset_class(model=self.model,
|
141
|
+
return self._queryset_class(model=self.model, hints=self._hints)
|
155
142
|
|
156
143
|
def all(self):
|
157
144
|
# We can't proxy this method through the `QuerySet` like we do for the
|
@@ -1,5 +1,4 @@
|
|
1
1
|
from plain.models import migrations
|
2
|
-
from plain.models.db import router
|
3
2
|
|
4
3
|
from .loader import MigrationLoader
|
5
4
|
from .recorder import MigrationRecorder
|
@@ -179,16 +178,6 @@ class MigrationExecutor:
|
|
179
178
|
on initial migrations (as it only looks for CreateModel and AddField).
|
180
179
|
"""
|
181
180
|
|
182
|
-
def should_skip_detecting_model(migration, model):
|
183
|
-
"""
|
184
|
-
No need to detect tables for models that can't be migrated on the current database.
|
185
|
-
"""
|
186
|
-
return not router.allow_migrate(
|
187
|
-
self.connection.alias,
|
188
|
-
migration.package_label,
|
189
|
-
model_name=model._meta.model_name,
|
190
|
-
)
|
191
|
-
|
192
181
|
if migration.initial is None:
|
193
182
|
# Bail if the migration isn't the first one in its app
|
194
183
|
if any(
|
@@ -224,8 +213,6 @@ class MigrationExecutor:
|
|
224
213
|
migration.package_label, operation.name
|
225
214
|
)
|
226
215
|
|
227
|
-
if should_skip_detecting_model(migration, model):
|
228
|
-
continue
|
229
216
|
db_table = model._meta.db_table
|
230
217
|
if fold_identifier_case:
|
231
218
|
db_table = db_table.casefold()
|
@@ -237,9 +224,6 @@ class MigrationExecutor:
|
|
237
224
|
migration.package_label, operation.model_name
|
238
225
|
)
|
239
226
|
|
240
|
-
if should_skip_detecting_model(migration, model):
|
241
|
-
continue
|
242
|
-
|
243
227
|
table = model._meta.db_table
|
244
228
|
field = model._meta.get_field(operation.name)
|
245
229
|
|
@@ -317,7 +317,7 @@ class MigrationLoader:
|
|
317
317
|
continue
|
318
318
|
raise InconsistentMigrationHistory(
|
319
319
|
f"Migration {migration[0]}.{migration[1]} is applied before its dependency "
|
320
|
-
f"{parent[0]}.{parent[1]} on database
|
320
|
+
f"{parent[0]}.{parent[1]} on the database."
|
321
321
|
)
|
322
322
|
|
323
323
|
def detect_conflicts(self):
|
@@ -114,7 +114,7 @@ class Migration:
|
|
114
114
|
if not schema_editor.atomic_migration and atomic_operation:
|
115
115
|
# Force a transaction on a non-transactional-DDL backend or an
|
116
116
|
# atomic operation inside a non-atomic migration.
|
117
|
-
with atomic(
|
117
|
+
with atomic():
|
118
118
|
operation.database_forwards(
|
119
119
|
self.package_label, schema_editor, old_state, project_state
|
120
120
|
)
|
@@ -1,6 +1,3 @@
|
|
1
|
-
from plain.models.db import router
|
2
|
-
|
3
|
-
|
4
1
|
class Operation:
|
5
2
|
"""
|
6
3
|
Base class for migration operations.
|
@@ -100,16 +97,12 @@ class Operation:
|
|
100
97
|
"""
|
101
98
|
return self.references_model(model_name, package_label)
|
102
99
|
|
103
|
-
def allow_migrate_model(self,
|
104
|
-
"""
|
105
|
-
|
106
|
-
|
107
|
-
This is a thin wrapper around router.allow_migrate_model().
|
108
|
-
"""
|
109
|
-
if not model._meta.can_migrate(connection_alias):
|
100
|
+
def allow_migrate_model(self, connection, model):
|
101
|
+
"""Return whether or not a model may be migrated."""
|
102
|
+
if not model._meta.can_migrate(connection):
|
110
103
|
return False
|
111
104
|
|
112
|
-
return
|
105
|
+
return True
|
113
106
|
|
114
107
|
def reduce(self, operation, package_label):
|
115
108
|
"""
|
@@ -101,7 +101,7 @@ class AddField(FieldOperation):
|
|
101
101
|
|
102
102
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
103
103
|
to_model = to_state.models_registry.get_model(package_label, self.model_name)
|
104
|
-
if self.allow_migrate_model(schema_editor.connection
|
104
|
+
if self.allow_migrate_model(schema_editor.connection, to_model):
|
105
105
|
from_model = from_state.models_registry.get_model(
|
106
106
|
package_label, self.model_name
|
107
107
|
)
|
@@ -164,7 +164,7 @@ class RemoveField(FieldOperation):
|
|
164
164
|
from_model = from_state.models_registry.get_model(
|
165
165
|
package_label, self.model_name
|
166
166
|
)
|
167
|
-
if self.allow_migrate_model(schema_editor.connection
|
167
|
+
if self.allow_migrate_model(schema_editor.connection, from_model):
|
168
168
|
schema_editor.remove_field(
|
169
169
|
from_model, from_model._meta.get_field(self.name)
|
170
170
|
)
|
@@ -218,7 +218,7 @@ class AlterField(FieldOperation):
|
|
218
218
|
|
219
219
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
220
220
|
to_model = to_state.models_registry.get_model(package_label, self.model_name)
|
221
|
-
if self.allow_migrate_model(schema_editor.connection
|
221
|
+
if self.allow_migrate_model(schema_editor.connection, to_model):
|
222
222
|
from_model = from_state.models_registry.get_model(
|
223
223
|
package_label, self.model_name
|
224
224
|
)
|
@@ -289,7 +289,7 @@ class RenameField(FieldOperation):
|
|
289
289
|
|
290
290
|
def database_forwards(self, package_label, schema_editor, from_state, to_state):
|
291
291
|
to_model = to_state.models_registry.get_model(package_label, self.model_name)
|
292
|
-
if self.allow_migrate_model(schema_editor.connection
|
292
|
+
if self.allow_migrate_model(schema_editor.connection, to_model):
|
293
293
|
from_model = from_state.models_registry.get_model(
|
294
294
|
package_label, self.model_name
|
295
295
|
)
|