如何在multidb项目中使用admin / auth进行迁移?

时间:2016-02-19 18:45:11

标签: django

众所周知,迁移会忽略数据库路由。 已知的解决方案是使用参数--database进行“手动”路由,并单独迁移每个应用程序。

然而,当使用contrib apps admin / auth / contenttypes时,应用迁移会触发post_migrate_signal强制他们检查可能更改的模型的权限,并且他们尝试在指定的数据库中执行此操作 - 数据库,而不是默认。

特别是,我的设置如下:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'foo',
    'bar'
}

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR + '/var/db.sqlite'
    },
    'foo': {
        'ENGINE': 'django.contrib.gis.db.backends.postgis',
        'HOST': 'foohost',
        'NAME': 'foo'
    },
    'bar': {
        'ENGINE': 'django.db.backends.postgresql',
        'HOST': '',
        'NAME': 'bar'
    }
}

DATABASE_ROUTERS = ['DumbDbRouter'] # simply returns app_label as  a target db

要运行contrib应用程序的初始迁移,请单独调用:

./manage.py migrate auth
./manage.py migrate admin
./manage.py migrate sessions

在此之后,将为每个找到的模型生成所有这些内容类型和权限。

现在,为我的应用运行迁移(初始或顺序):

./manage.py migrate foo --database=foo
# fails with error "Error creating new content types.". 

跟踪显示它是从尝试在数据库django_contenttypes中查找表foo而引发的。 现在,其他一些操作(如runserver)会发出警告:“您有未应用的迁移。”

我发现的唯一解决方法是禁用所有贡献内容(包括管理员网址),然后进行迁移,然后将其关闭。

后果是不洁净的。

1 个答案:

答案 0 :(得分:0)

您可以在路由器中使用allow_migrate方法处理它。如果应用 fooapp 应位于数据库 foo 中,请确保 contenttypes 应用也在那里。例如:

class DumbDbRouter(object)
    # ...
    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if db == 'foo':
            return app_label in ['fooapp', 'contenttypes']  # <-- PAY ATTENTION
        elif app_label == 'fooapp':
            return False
        return None

阅读文档here

  
      
  • contenttypes.ContentType ,sessions.Site和sites.Site中的每一个都可以存储在任何数据库中,给定合适的路由器
  •   

希望它有所帮助!