【问题标题】:Migrate command create all tables on second DB - Django迁移命令在第二个数据库上创建所有表 - Django
【发布时间】:2018-12-19 11:16:45
【问题描述】:

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

P.S.:在我运行了一些测试之后,应用程序似乎按预期运行。换句话说,来自我的ali 应用程序的模型被保存在ali 数据库中。尽管如此,在我的ali DB 中放置所有这些空表并不是正确的方法。

设置:

# 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 DB 得到的:

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)是否存在问题?

【问题讨论】:

    标签: django django-migrations django-postgresql


    【解决方案1】:

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

    要禁止迁移 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
    

    【讨论】:

    • 我的错,忘了查看我从 allow_migrate() 返回的内容。谢谢你的回答,效果很好!
    【解决方案2】:

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

    python manage.py migrate ali --database=ali

    【讨论】:

      猜你喜欢
      • 2012-04-10
      • 2021-06-17
      • 1970-01-01
      • 1970-01-01
      • 2017-02-21
      • 2019-07-25
      • 2015-12-08
      • 2016-10-27
      • 2017-04-10
      相关资源
      最近更新 更多