迁移命令在第二个数据库上创建所有表 - Django

Migrate command create all tables on second DB - Django

我的项目 (website) 上有一个应用程序 (ali),我希望它有自己的数据库。问题是,当我 运行 python manage.py migrate --database=ali 时,该命令会重新创建我的 ali 数据库中的所有表;而预期的结果是只有 ali_search 数据库。

P.S.: 在我 运行 一些测试之后,应用程序似乎 运行 符合预期 。换句话说,我的 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 数据库得到的
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)是否有问题?

对我来说,migrate 命令应该查看路由以创建表。但似乎并非如此。因此,似乎最简单的解决方法是使用 [app_label] 参数调用 migrate。像这样:

python manage.py migrate ali --database=ali

allow_migrate()返回None表示路由器对当前操作没有意见。如果 none 个配置的路由器有意见,则默认为允许该操作。您当前的路由器 returns None 用于 ali 以外的应用程序,因此在两个数据库上都允许这些操作。

要禁止在 ali 数据库上迁移其他应用程序,您必须在这些情况下明确 return 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