2016-02-19 107 views
1

这是已知的问题,迁移忽略数据库路由。 已知的解决方案是使用参数 - 数据库进行“手动”路由,并分别迁移每个应用程序。如何在multidb项目中使用admin/auth进行迁移?

但是,当使用contrib apps admin/auth/contenttypes时,应用迁移将触发post_migrate_signal,迫使他们检查可能更改模型的权限扩展,并尝试在使用--database指定的数据库中执行该操作然后默认。

特别地,我已经安装是这样的:

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 

在此之后,是为每一个生成的所有那些CONTENTTYPES和权限找到模型。现在

,运行的迁移我的应用程序(无论是初始或顺序):

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

跟踪显示它从试图找到表django_contenttypes数据库foo提高。 现在,其他一些操作(例如runserver)会警告:“您有未应用的迁移。”

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

结果是不洁的。

回答

0

您可以在路由器中使用allow_migrate方法处理它。如果您的应用程序fooapp应该在数据库foo,那么请确保内容类型应用程序也在那里。例如:

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.Session和sites.Site可以存储在任何数据库,给出一个合适的路由器

希望它有帮助!

+0

你的意思是我需要在所有数据库上分发contenttype表的内容吗? 它如何工作? – qMax

+0

您应该在每个与应用程序相关的非默认数据库(如'foo')上使用迁移来分发内容类型。它需要django_migration表(在非默认数据库中),它依赖于contenttype表。默认情况下,contenttype表存储在默认数据库中。在其他数据库中,您应该手动存储使用数据库路由器的contenttype表。 –

+0

引用的文档说,admin和auth模型依赖于contenttypes,并且应该存储在同一个数据库中。这可能需要在每个获得授权的数据库中复制授权模型。 – qMax