#35967: TransactionTestCase.serialized_rollback reads from real database rather
than test when using read replica for a model instance created in a
migration with a ManyToManyField
-------------------------------------+-------------------------------------
Reporter: Jake Howard | Owner: (none)
Type: Bug | Status: new
Component: Core | Version: dev
(Serialization) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):
* component: Database layer (models, ORM) => Core (Serialization)
Comment:
Thanks for the crystal clear reproduction. I haven't tested to be sure,
but it certainly looks a lot like #23979.
This hack passes your test case, but I'm not going to opine on whether
it's correct; I just put this together as a learning exercise and to
verify my hunch that this was more to do with the serializer and less to
do with the testing framework. If someone more knowledgable can opine on
correctness and backwards compatibility, I'm happy to push this forward.
{{{#!diff
diff --git a/django/core/serializers/base.py
b/django/core/serializers/base.py
index 1fbca9244b..f2f0d4d8d6 100644
--- a/django/core/serializers/base.py
+++ b/django/core/serializers/base.py
@@ -5,7 +5,7 @@ Module for abstract serializer/unserializer base classes.
from io import StringIO
from django.core.exceptions import ObjectDoesNotExist
-from django.db import models
+from django.db import models, DEFAULT_DB_ALIAS
DEFER_FIELD = object()
@@ -91,6 +91,7 @@ class Serializer:
use_natural_primary_keys=False,
progress_output=None,
object_count=0,
+ using=DEFAULT_DB_ALIAS,
**options,
):
"""
@@ -141,7 +142,7 @@ class Serializer:
self.selected_fields is None
or field.attname in self.selected_fields
):
- self.handle_m2m_field(obj, field)
+ self.handle_m2m_field(obj, field, using=using)
self.end_object(obj)
progress_bar.update(count)
self.first = self.first and False
@@ -192,7 +193,7 @@ class Serializer:
"subclasses of Serializer must provide a handle_fk_field()
method"
)
- def handle_m2m_field(self, obj, field):
+ def handle_m2m_field(self, obj, field, *, using=DEFAULT_DB_ALIAS):
"""
Called to handle a ManyToManyField.
"""
diff --git a/django/core/serializers/python.py
b/django/core/serializers/python.py
index 57edebbb70..93898d3801 100644
--- a/django/core/serializers/python.py
+++ b/django/core/serializers/python.py
@@ -64,7 +64,7 @@ class Serializer(base.Serializer):
value = self._value_from_field(obj, field)
self._current[
field.name] = value
- def handle_m2m_field(self, obj, field):
+ def handle_m2m_field(self, obj, field, *, using=DEFAULT_DB_ALIAS):
if field.remote_field.through._meta.auto_created:
if self.use_natural_foreign_keys and hasattr(
field.remote_field.model, "natural_key"
@@ -86,6 +86,7 @@ class Serializer(base.Serializer):
getattr(obj,
field.name)
.select_related(None)
.only("pk")
+ .using(using)
.iterator()
)
diff --git a/django/db/backends/base/creation.py
b/django/db/backends/base/creation.py
index 6856fdb596..8adfa0d7ca 100644
--- a/django/db/backends/base/creation.py
+++ b/django/db/backends/base/creation.py
@@ -142,7 +142,9 @@ class BaseDatabaseCreation:
# Serialize to a string
out = StringIO()
- serializers.serialize("json", get_objects(), indent=None,
stream=out)
+ serializers.serialize(
+ "json", get_objects(), indent=None, stream=out,
using=self.connection.alias
+ )
return out.getvalue()
def deserialize_db_from_string(self, data):
}}}
--
Ticket URL: <
https://code.djangoproject.com/ticket/35967#comment:3>