#27054: makemigrations tries to create django_migrations in external database
--------------------------------------+------------------------------------
     Reporter:  SydneyUniLibrary-Jim  |                    Owner:  nobody
         Type:  Bug                   |                   Status:  new
    Component:  Migrations            |                  Version:  1.10
     Severity:  Release blocker       |               Resolution:
     Keywords:                        |             Triage Stage:  Accepted
    Has patch:  1                     |      Needs documentation:  0
  Needs tests:  1                     |  Patch needs improvement:  0
Easy pickings:  0                     |                    UI/UX:  0
--------------------------------------+------------------------------------

Comment (by SydneyUniLibrary-Jim):

 For each connection: `loader.check_consistent_history` calls
 `recorder.MigrationRecorder.applied_migrations` to get the set of
 migrations that have already been applied to the database on the other end
 of the connection. `MigrationRecorder.applied_migrations` calls
 `MigrationRecorder.ensure_schema` so that it can query the table
 underlying `MigrationRecorder.Migration`.

 Conceptually `MigrationRecorder.applied_migrations` is a read-only
 operation with respect to the database, but nevertheless it does attempt
 write operations as an implementation side-effect.

 I'm inexperienced in Django's code, so I'll lift catch the exception
 higher up the call stack if you think that's best.

 My thoughts at catching the `MigrationSchemaMissing` exception within
 `applied_migrations` was along the following lines.

 The existing usages of `applied_migrations` are:
 *
 `django.db.migrations.executor.MigrationsExecutor.check_replacements(self)`:
 doesn't handle `MigrationSchemaMissing`, copes with `applied_migrations`
 returning an empty set
 * `django.db.migrations.loader.MigrationLoader.build_graph(self)`: this
 code explicitly treats no connection as being equivalent to
 `applied_migrations` returning an empty set
 *
 `django.db.migrations.loader.MigrationLoader.check_consistent_history(self,
 connection)`: uses the result of `applied_migrations` in a for loop, so
 copes with `applied_migrations` returning an empty set

 `MigrationSchemaMissing` is only raised in
 `MigrationRecorder.ensure_schema`.

 `MigrationSchemaMissing` is only handled in
 `django.core.management.core.management.base.BaseCommand.check_migrations`,
 where it logs a message to stdout and then skips checking the migrations.
 However `check_migrations` doesn't directly or indirectly call
 `applied_migrations` in the try suite.

 `MigrationSchemaMissing` is a subclass of `DatabaseError`, which has too
 many usages to consider.

 Considering the existing usages above, and possible future usages, my
 thinking for catching `MigrationSchemaMissing` inside `applied_migrations`
 is:
 * not being able to create `django_migrations` is not exceptional. I think
 my use-case and `BaseCommand.check_migrations` proves that
 * `MigrationSchemaMissing` is indirectly raised in `applied_migrations`
 because of the implementation side-effect, not because of the semantics of
 `applied_migrations`. I think it is leaking an exception in a non-
 exceptional circumstance.
 * I don't think a callee would usefully want to distinguish between a
 database with no migrations, where empty set returned, from a sitatuation
 of the `django_migrations` table failed to be created, where
 `MigrationSchemaMissing` is raised.
 * requiring a callee to have to consider `MigrationSchemaMissing` being
 raise is onerous, when returning an empty set would most likely have the
 same effect in the callee's code.

--
Ticket URL: <https://code.djangoproject.com/ticket/27054#comment:6>
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 post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/078.27044cefa31c6197322db64330739b0f%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to