众所周知,迁移会忽略数据库路由。 已知的解决方案是使用参数--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
)会发出警告:“您有未应用的迁移。”
我发现的唯一解决方法是禁用所有贡献内容(包括管理员网址),然后进行迁移,然后将其关闭。
后果是不洁净的。
答案 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中的每一个都可以存储在任何数据库中,给定合适的路由器。
希望它有所帮助!