#33280: [bug] migration don't work with multiple databases (sometimes)
-------------------------------------+-------------------------------------
               Reporter:             |          Owner:  nobody
  razielvamp666                      |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  2.2
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:  orm migration
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 My configuration is:


 {{{
 python 3.7.1
 }}}


 {{{
 Django==2.2.24
 django-axes==5.16.0
 django-bootstrap-modal-forms==1.3.1
 django-celery-results==1.0.4
 django-cors-headers==3.1.1
 django-database-view==0.3.0
 django-debug-toolbar==1.11
 django-dynamic-db-router==0.3.0
 django-ipware==3.0.7
 django-redis-cache==3.0.0
 django-redis-sessions==0.6.2
 django-ses==1.0.3
 django-storages==1.12.3
 django-taggit==0.24.0
 djangorestframework==3.12.4
 pytest-django==4.4.0
 }}}

 I using Django with multiple databases and default DB is not set for
 security reasons (I prefer to get error if Django will fallback to
 `default` connection, because it means that current tenant DB is not used
 for some reasons). so `default` connection is empty (`{}`).

 When I run `python manage.py migrate --database=some_db_name`

 I've get error:

 {{{
   Applying app_name.0154_migration_name...Traceback (most recent call
 last):
   File "manage.py", line 41, in <module>
     execute_from_command_line(sys.argv)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/core/management/__init__.py", line 381, in
 execute_from_command_line
     utility.execute()
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/core/management/__init__.py", line 375, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/core/management/base.py", line 323, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/core/management/base.py", line 364, in execute
     output = self.handle(*args, **options)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/core/management/base.py", line 83, in wrapped
     res = handle_func(*args, **kwargs)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/core/management/commands/migrate.py", line 234, in handle
     fake_initial=fake_initial,
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/migrations/executor.py", line 117, in migrate
     state = self._migrate_all_forwards(state, plan, full_plan, fake=fake,
 fake_initial=fake_initial)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/migrations/executor.py", line 147, in
 _migrate_all_forwards
     state = self.apply_migration(state, migration, fake=fake,
 fake_initial=fake_initial)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/migrations/executor.py", line 245, in apply_migration
     state = migration.apply(state, schema_editor)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/migrations/migration.py", line 124, in apply
     operation.database_forwards(self.app_label, schema_editor, old_state,
 project_state)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/dbview/helpers.py", line 21, in database_forwards
     self._create_standard_view(model, schema_editor)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/dbview/helpers.py", line 60, in _create_standard_view
     qs = str(model.view())
   File
 "/user/code/genki_labo/orm_django/models/novel_coronavirus_vaccine.py",
 line 136, in view
     return str(qs.query)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/models/sql/query.py", line 265, in __str__
     sql, params = self.sql_with_params()
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/models/sql/query.py", line 273, in sql_with_params
     return self.get_compiler(DEFAULT_DB_ALIAS).as_sql()
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/models/sql/compiler.py", line 474, in as_sql
     extra_select, order_by, group_by = self.pre_sql_setup()
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/models/sql/compiler.py", line 54, in pre_sql_setup
     self.setup_query()
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/models/sql/compiler.py", line 45, in setup_query
     self.select, self.klass_info, self.annotation_col_map =
 self.get_select()
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/models/sql/compiler.py", line 254, in get_select
     sql, params = self.compile(col, select_format=True)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/models/sql/compiler.py", line 405, in compile
     sql, params = node.as_sql(self, self.connection)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/models/expressions.py", line 737, in as_sql
     return "%s.%s" % (qn(self.alias), qn(self.target.column)), []
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/models/sql/compiler.py", line 396, in
 quote_name_unless_alias
     r = self.connection.ops.quote_name(name)
   File "/user/.pyenv/versions/gl/lib/python3.7/site-
 packages/django/db/backends/dummy/base.py", line 20, in complain
     raise ImproperlyConfigured("settings.DATABASES is improperly
 configured. "
 django.core.exceptions.ImproperlyConfigured: settings.DATABASES is
 improperly configured. Please supply the ENGINE value. Check settings
 documentation for more details.
 }}}

 You can see that problem is here:

 {{{
 return self.get_compiler(DEFAULT_DB_ALIAS).as_sql()
 }}}

 `DEFAULT_DB_ALIAS` is `default` and it hardcoded.

 Also `DEFAULT_DB_ALIAS` is used couple of times inside
 `django/db/models/sql/query.py` (please search by `DEFAULT_DB_ALIAS` in
 file to see details)

 It should use CURRENT_DB as other parts of Django
 Unfortunately I didn't check how migration determines current DB when
 `--database=...` is set so can't recommend exact solution, but I may see
 couple hints:

 1. DB may be get from `--database=...` directly (But not sure if that is a
 correct solution).
 2. DB may be get from
 [`DatabaseRouter`](https://docs.djangoproject.com/en/2.2/topics/db/multi-
 db/#database-routers) as other parts of Django (It is looking like correct
 solution)
 3. Here should be `using` option to be able set connection DB directly
 (for example, all functions inside `django/db/transaction.py` has `using`
 argument to be able set connection name directly)

 Right now I using workaround and set `from django.conf import settings;
 settings.DATABASES['default'] = current_db_taken_from_cmd` if command is
 `migrate`.
 Not all migrations fail. I don't know reason why it happens only with
 specific migrations, but I guess that it because this migration doing
 `CreateView`

 Migration file is looking like:

 {{{
 # Generated by Django 2.2.10 on 2021-10-06 04:17
 from dbview.helpers import CreateView

 import common.enums.some_enum
 from django.db import migrations, models
 import django.db.models.deletion


 class Migration(migrations.Migration):

     dependencies = [
         ('app_name', '0153_previous_migration'),
     ]

     operations = [
         migrations.CreateModel(
             name='SomeName',
             fields=[
                 ('id', models.AutoField(auto_created=True,
 primary_key=True, serialize=False, verbose_name='ID')),
                 ('create_datetime',
 models.DateTimeField(auto_now_add=True, verbose_name='A')),
                 ('user', models.CharField(default='admin', max_length=32,
 verbose_name='B')),
                 ('update_datetime', models.DateTimeField(auto_now=True,
 verbose_name='C')),
                 ...
             ],
             options={
                 'db_table': 'table_name',
                 'unique_together': {('other_table', 'table_name')},
             },
         ),
         CreateView(
             name='SomeNameView',
             fields=[
                 ('table_name_1',
 models.OneToOneField(on_delete=django.db.models.deletion.PROTECT,
 primary_key=True, serialize=False, to='orm_django.ApplyingInformation')),
                 ('table_name_2', models.IntegerField(verbose_name='A')),
                 ('table_name_3', models.IntegerField(verbose_name='B')),
                 ('table_name_3', models.IntegerField(verbose_name='C')),
                 ...
             ],
             options={
                 'db_table': 'table_view',
             },
         ),
         migrations.AddIndex(
             model_name='modelname',
             index=models.Index(fields=['field_A', 'field_B', ...],
 name='index_name'),
         ),
     ]
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33280>
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 on the web visit 
https://groups.google.com/d/msgid/django-updates/056.1b5ad189b40bd4936d0650527e5f5e10%40djangoproject.com.

Reply via email to