Команда Migrate создает все таблицы на второй БД - Django - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть приложение (ali) в моем проекте (website), и я хотел, чтобы оно имело свою собственную базу данных.Проблема в том, что когда я запускаю python manage.py migrate --database=ali, команда воссоздает все таблицы в моей базе данных ali;в то время как ожидаемый результат будет иметь только базу данных ali_search.

PS: приложение, кажется, работает как ожидалось после того, как я выполнил некоторые тесты.Другими словами, модели из моего приложения ali сохраняются в базе данных ali.Тем не менее, наличие всех этих пустых таблиц в моей ali БД - неправильный путь.

Настройки:

# website.settings

...

INSTALLED_APPS = [
    'base.apps.BaseConfig',
    'ali.apps.AliConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.sites',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sitemaps',
    'django_comments',
    'mptt',
    'tagging',
    'zinnia',
]

....

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'website',
        'USER': 'website',
        'PASSWORD': 'website',
        'HOST': 'localhost',
        'PORT': '5432',
    },
    'ali': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'ali',
        'USER': 'ali',
        'PASSWORD': 'ali',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

DATABASE_ROUTERS = [
    'ali.routers.AliRouter',
]

....

Маршрутизатор:

# ali.routers

class AliRouter:
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'ali':
            return 'ali'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'ali':
            return 'ali'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label == 'ali' or \
           obj2._meta.app_label == 'ali':
           return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label == 'ali':
            return db == 'ali'
        return None

Модель:

# ali.models

from django.db import models

class Search(models.Model):

    results = models.IntegerField()

Это то, что я получаю, опрашивая мою Али БД с помощью \dt:

ali=# \dt
                  List of relations
 Schema |            Name            | Type  | Owner 
--------+----------------------------+-------+-------
 public | ali_search                 | table | ali
 public | auth_group                 | table | ali
 public | auth_group_permissions     | table | ali
 public | auth_permission            | table | ali
 public | auth_user                  | table | ali
 public | auth_user_groups           | table | ali
 public | auth_user_user_permissions | table | ali
 public | django_admin_log           | table | ali
 public | django_comment_flags       | table | ali
 public | django_comments            | table | ali
 public | django_content_type        | table | ali
 public | django_migrations          | table | ali
 public | django_session             | table | ali
 public | django_site                | table | ali
 public | tagging_tag                | table | ali
 public | tagging_taggeditem         | table | ali
 public | zinnia_category            | table | ali
 public | zinnia_entry               | table | ali
 public | zinnia_entry_authors       | table | ali
 public | zinnia_entry_categories    | table | ali
 public | zinnia_entry_related       | table | ali
 public | zinnia_entry_sites         | table | ali
(22 rows)

Но я действительно ожидал бы:

ali=# \dt
                  List of relations
 Schema |            Name            | Type  | Owner 
--------+----------------------------+-------+-------
 public | ali_search                 | table | ali
(1 row)

Может ли быть проблемой тот факт, что приложение имеет то же имя, что и база данных (в данном случае ali )?

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Возвращение None из allow_migrate() означает, что маршрутизатор не имеет мнения о текущей операции.Если ни один из настроенных маршрутизаторов не имеет своего мнения, по умолчанию это разрешено.Ваш текущий маршрутизатор возвращает None для приложений, отличных от ali, поэтому эти операции разрешены в обеих базах данных.

Чтобы запретить перенос других приложений в базе данных ali, необходимо явно вернуть False в таких случаях, например:

def allow_migrate(self, db, app_label, model_name=None, **hints):
    if app_label == 'ali':
        return db == 'ali'
    return db == 'default'

Теперь вы можете просто запустить migrate для каждой базы данных, без необходимости указывать, какие приложения переносить:

$ python manage.py migrate --database=default
$ python manage.py migrate --database=ali
0 голосов
/ 19 декабря 2018

Для меня команда migrate должна взглянуть на маршруты для создания таблиц.Но, похоже, дело не в этом.Следовательно, кажется, что легко исправить это вызвать migrate с аргументом [app_label].Как это:

python manage.py migrate ali --database=ali

...