用于在django中迁移的自动数据库路由器

时间:2016-08-24 21:49:33

标签: python django django-migrations

我正在构建一个Django支持的站点,我希望为某些应用程序提供单独的数据库,我构建了一个灵活的路由器,将每个应用程序路由到预定义的数据库,这很好。 问题是,当我迁移模型时,我必须每次都设置--database参数,我觉得这很烦人且多余。还有很多次我使用迁移的app中的表来填充我的默认数据库(忘记添加--database)。 我在路由器中尝试了allow_migrate(...)函数,但我所能实现的是安全机制,如果我忘记指定数据库,它将不会运行迁移。 我的问题是:有没有办法为Django中的模型迁移设置自动数据库选择? 我的做法可能是错的,让我感到惊讶的是,之前似乎没有人这么做过。

2 个答案:

答案 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一样,迁移一次只能在一个数据库上运行,所以你必须按照你的建议为每个数据库单独执行它。这是设计的。"