我正在构建一个Django支持的站点,我希望为某些应用程序提供单独的数据库,我构建了一个灵活的路由器,将每个应用程序路由到预定义的数据库,这很好。
问题是,当我迁移模型时,我必须每次都设置--database
参数,我觉得这很烦人且多余。还有很多次我使用迁移的app中的表来填充我的默认数据库(忘记添加--database
)。
我在路由器中尝试了allow_migrate(...)
函数,但我所能实现的是安全机制,如果我忘记指定数据库,它将不会运行迁移。
我的问题是:有没有办法为Django中的模型迁移设置自动数据库选择?
我的做法可能是错的,让我感到惊讶的是,之前似乎没有人这么做过。
答案 0 :(得分:7)
对于任何面临这个问题的人来说,这就是我最终解决的问题:
routers.py:
from django.conf import settings
class DatabaseAppsRouter(object):
def db_for_read(self, model, **hints):
# your db routing
def db_for_write(self, model, **hints):
# your db routing
def allow_relation(self, obj1, obj2, **hints):
# your db routing
def allow_syncdb(self, db, model):
# your db routing
def allow_migrate(self, db, app_label, model_name=None, **hints):
if db in settings.DATABASE_APPS_MAPPING.values():
return settings.DATABASE_APPS_MAPPING.get(app_label) == db
elif app_label in settings.DATABASE_APPS_MAPPING:
return False
settings.py
DATABASE_ROUTERS = ['project.routers.DatabaseAppsRouter']
DATABASE_APPS_MAPPING = {'contenttypes': 'default',
'auth': 'default',
'admin': 'default',
'sessions': 'default',
'messages': 'default',
'staticfiles': 'default',
'myapp': 'mydb',
}
此设置允许我运行两个命令:
python manage.py migrate
python manage.py migrate --database=mydb
这仍然是一对多,但至少现在我不能错误地将myapp迁移到默认数据库,这是我想承认的更多次。
警告 - 咆哮:
到目前为止,我发现Django的设计是古怪但非常合乎逻辑且程序员友好,就像python本身一样。但迁移与多个数据库设置交互的方式确实很不方便,因此很容易使用不需要的表来填充默认数据库。 凯文在答案中的讨论表明,我不是唯一一个遇到这种困难的人。
答案 1 :(得分:3)
我不知道有什么方法可以自动完成。但是,一个简单的方法可能是使用适当的migrate
和app参数多次调用Django migrate
命令的--database
命令的write your own version。
根据Django迁移的作者,这是a conscious design decision,所以我不希望它改变:"就像syncdb一样,迁移一次只能在一个数据库上运行,所以你必须按照你的建议为每个数据库单独执行它。这是设计的。"