Changes between Version 2 and Version 3 of Ticket #33280


Ignore:
Timestamp:
Nov 11, 2021, 2:27:48 AM (3 years ago)
Author:
razielvamp666
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #33280 – Description

    v2 v3  
     1My configuration is:
     2
     3
     4{{{
     5python 3.7.1
     6}}}
     7
     8
     9{{{
     10Django==2.2.24
     11django-axes==5.16.0
     12django-bootstrap-modal-forms==1.3.1
     13django-celery-results==1.0.4
     14django-cors-headers==3.1.1
     15django-database-view==0.3.0
     16django-debug-toolbar==1.11
     17django-dynamic-db-router==0.3.0
     18django-ipware==3.0.7
     19django-redis-cache==3.0.0
     20django-redis-sessions==0.6.2
     21django-ses==1.0.3
     22django-storages==1.12.3
     23django-taggit==0.24.0
     24djangorestframework==3.12.4
     25pytest-django==4.4.0
     26}}}
     27
     28I 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 (`{}`).
     29
     30When I run `python manage.py migrate --database=some_db_name`
     31
     32I've get error:
     33
     34{{{
     35  Applying app_name.0154_migration_name...Traceback (most recent call last):
     36  File "manage.py", line 41, in <module>
     37    execute_from_command_line(sys.argv)
     38  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
     39    utility.execute()
     40  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
     41    self.fetch_command(subcommand).run_from_argv(self.argv)
     42  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/core/management/base.py", line 323, in run_from_argv
     43    self.execute(*args, **cmd_options)
     44  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/core/management/base.py", line 364, in execute
     45    output = self.handle(*args, **options)
     46  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/core/management/base.py", line 83, in wrapped
     47    res = handle_func(*args, **kwargs)
     48  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/core/management/commands/migrate.py", line 234, in handle
     49    fake_initial=fake_initial,
     50  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/migrations/executor.py", line 117, in migrate
     51    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
     52  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
     53    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
     54  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/migrations/executor.py", line 245, in apply_migration
     55    state = migration.apply(state, schema_editor)
     56  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/migrations/migration.py", line 124, in apply
     57    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
     58  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/dbview/helpers.py", line 21, in database_forwards
     59    self._create_standard_view(model, schema_editor)
     60  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/dbview/helpers.py", line 60, in _create_standard_view
     61    qs = str(model.view())
     62  File "/user/code/app_name/app_name/models/file_name.py", line 136, in view
     63    return str(qs.query)
     64  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/models/sql/query.py", line 265, in __str__
     65    sql, params = self.sql_with_params()
     66  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/models/sql/query.py", line 273, in sql_with_params
     67    return self.get_compiler(DEFAULT_DB_ALIAS).as_sql()
     68  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 474, in as_sql
     69    extra_select, order_by, group_by = self.pre_sql_setup()
     70  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 54, in pre_sql_setup
     71    self.setup_query()
     72  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 45, in setup_query
     73    self.select, self.klass_info, self.annotation_col_map = self.get_select()
     74  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 254, in get_select
     75    sql, params = self.compile(col, select_format=True)
     76  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 405, in compile
     77    sql, params = node.as_sql(self, self.connection)
     78  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/models/expressions.py", line 737, in as_sql
     79    return "%s.%s" % (qn(self.alias), qn(self.target.column)), []
     80  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 396, in quote_name_unless_alias
     81    r = self.connection.ops.quote_name(name)
     82  File "/user/.pyenv/versions/gl/lib/python3.7/site-packages/django/db/backends/dummy/base.py", line 20, in complain
     83    raise ImproperlyConfigured("settings.DATABASES is improperly configured. "
     84django.core.exceptions.ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.
     85}}}
     86
     87You can see that problem is here:
     88
     89{{{
     90return self.get_compiler(DEFAULT_DB_ALIAS).as_sql()
     91}}}
     92
     93`DEFAULT_DB_ALIAS` is `default` and it hardcoded.
     94
     95Also `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)
     96
     97It should use CURRENT_DB as other parts of Django
     98Unfortunately 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:
     99
     1001. DB may be get from `--database=...` directly (But not sure if that is a correct solution).
     1012. 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)
     1023. 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)
     103
     104Right now I using workaround and set `from django.conf import settings; settings.DATABASES['default'] = current_db_taken_from_cmd` if command is `migrate`.
     105Not 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`
     106
     107Migration file is looking like:
     108
     109{{{
     110# Generated by Django 2.2.10 on 2021-10-06 04:17
     111from dbview.helpers import CreateView
     112
     113import common.enums.some_enum
     114from django.db import migrations, models
     115import django.db.models.deletion
     116
     117
     118class Migration(migrations.Migration):
     119
     120    dependencies = [
     121        ('app_name', '0153_previous_migration'),
     122    ]
     123
     124    operations = [
     125        migrations.CreateModel(
     126            name='SomeName',
     127            fields=[
     128                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
     129                ('create_datetime', models.DateTimeField(auto_now_add=True, verbose_name='A')),
     130                ('user', models.CharField(default='admin', max_length=32, verbose_name='B')),
     131                ('update_datetime', models.DateTimeField(auto_now=True, verbose_name='C')),
     132                ...
     133            ],
     134            options={
     135                'db_table': 'table_name',
     136                'unique_together': {('other_table', 'table_name')},
     137            },
     138        ),
     139        CreateView(
     140            name='SomeNameView',
     141            fields=[
     142                ('table_name_1', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, primary_key=True, serialize=False, to='orm_django.ApplyingInformation')),
     143                ('table_name_2', models.IntegerField(verbose_name='A')),
     144                ('table_name_3', models.IntegerField(verbose_name='B')),
     145                ('table_name_3', models.IntegerField(verbose_name='C')),
     146                ...
     147            ],
     148            options={
     149                'db_table': 'table_view',
     150            },
     151        ),
     152        migrations.AddIndex(
     153            model_name='modelname',
     154            index=models.Index(fields=['field_A', 'field_B', ...], name='index_name'),
     155        ),
     156    ]
     157}}}
Back to Top