#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:  Jacob
                                     |  Walls
         Type:  Bug                  |                   Status:  assigned
    Component:  Core                 |                  Version:  dev
  (Serialization)                    |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Comment (by Simon Charette):

 > If someone more knowledgable can opine on correctness and backwards
 compatibility, I'm happy to push this forward.

 Hey Jacob I admittedly haven't looked into the issue in depth but I think
 that forcing the usage of the current alias like you did here is a
 certainly a key towards the solution.

 I have a hunch that the actual problems lives in
 `djang.test.utils.setup_databases` though and particularly how
 `BaseDatabaseCreation.create_test_db` is implemented. `setup_databases`
 currently follows this sequence of operations for each `DATABASES` entries

 1. Create the test db replacement
 2. Repoint `settings.DATABASES[alias][name]` to the test db replacement
 3. Peform migrations
 4. Serialize content

 I think that instead what it should do is 1, 2, 3 for each `DATABASES`
 entries (making sure that all the test databases are setup) and then do 4
 for each of them. Something like

 {{{#!diff
 diff --git a/django/db/backends/base/creation.py
 b/django/db/backends/base/creation.py
 index 6856fdb596..7a0e2a0622 100644
 --- a/django/db/backends/base/creation.py
 +++ b/django/db/backends/base/creation.py
 @@ -91,6 +91,7 @@ def create_test_db(
          # who are testing on databases without transactions or who are
 using
          # a TransactionTestCase still get a clean database on every test
 run.
          if serialize:
 +            # XXX: Emit a deprecation warnings when `serialize` is
 provided.
              self.connection._test_serialized_contents =
 self.serialize_db_to_string()

          call_command("createcachetable", database=self.connection.alias)
 diff --git a/django/test/utils.py b/django/test/utils.py
 index ddb85127dc..a2fe8b14cc 100644
 --- a/django/test/utils.py
 +++ b/django/test/utils.py
 @@ -189,6 +189,7 @@ def setup_databases(
      test_databases, mirrored_aliases =
 get_unique_databases_and_mirrors(aliases)

      old_names = []
 +    serialize_connections = []

      for db_name, aliases in test_databases.values():
          first_alias = None
 @@ -200,15 +201,13 @@ def setup_databases(
              if first_alias is None:
                  first_alias = alias
                  with time_keeper.timed("  Creating '%s'" % alias):
 -                    serialize_alias = (
 -                        serialized_aliases is None or alias in
 serialized_aliases
 -                    )
                      connection.creation.create_test_db(
                          verbosity=verbosity,
                          autoclobber=not interactive,
                          keepdb=keepdb,
 -                        serialize=serialize_alias,
                      )
 +                    if serialized_aliases is None or alias in
 serialized_aliases:
 +                        serialize_connections.append(connection)
                  if parallel > 1:
                      for index in range(parallel):
                          with time_keeper.timed("  Cloning '%s'" % alias):
 @@ -223,6 +222,13 @@ def setup_databases(
                      connections[first_alias].settings_dict
                  )

 +    # Serialize content of test databases only once all of them are setup
 +    # to account for database routing during serialization.
 +    for serialize_connection in serialize_connections:
 +        serialize_connection._test_serialized_contents = (
 +            serialize_connection.serialize_db_to_string()
 +        )
 +
      # Configure the test mirrors.
      for alias, mirror_alias in mirrored_aliases.items():
          connections[alias].creation.set_as_test_mirror(
 }}}
-- 
Ticket URL: <https://code.djangoproject.com/ticket/35967#comment:5>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/01070193a9cb46c3-be1a6e25-a954-41b3-a8e4-7de8a479fc0e-000000%40eu-central-1.amazonses.com.

Reply via email to