#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 django-updates+unsubscr...@googlegroups.com.
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