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

Automatic db router for migrations in django

提问人:Raff89 提问时间:8/25/2016 更新时间:8/26/2016 访问量:4599

问:

我正在构建一个 Django 驱动的站点,我想为一些应用程序提供单独的数据库,我构建了一个灵活的路由器,将每个应用程序路由到预定义的数据库,这很好用。 问题是,当我迁移模型时,我每次都必须设置参数,我发现这很烦人且多余。还有很多次,我用迁移的应用程序中的表淹没了我的默认数据库(通过忘记添加)。 我在路由器中试验了功能,但我所能实现的只是安全机制,如果我忘记指定数据库,它将不会运行迁移。 我的问题是:有没有办法在 Django 中为模型迁移设置自动数据库选择? 我的方法可能是错误的,令我惊讶的是,以前似乎没有人这样做过。--database--databaseallow_migrate(...)

python django django-migrations

评论


答:

4赞 Kevin Christopher Henry 8/25/2016 #1

我不知道有什么方法可以自动做到这一点。但是,一个简单的方法可能是编写自己的命令版本,该命令使用适当的 and app 参数多次调用 Django 命令。migratemigrate--database

根据 Django 迁移的作者的说法,这是一个有意识的设计决策,所以我不希望它改变:“就像 syncdb 一样,migrate 一次只在一个数据库上运行,所以你必须按照你的建议为每个数据库单独执行它。这是设计使然。

评论

0赞 Raff89 8/25/2016
感谢您提供有关此主题的讨论的链接,似乎 db/migrations 子系统的设计不允许我的首选解决方案。我会尝试你的建议。
15赞 Raff89 8/26/2016 #2

对于面临我遇到的问题的任何人来说,这是我最终确定的:

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 本身一样。但是,迁移与多个数据库设置交互的方式确实很不方便,因此很容易用不需要的表淹没默认数据库。 凯文在他的回答中提到的讨论表明,我不是唯一一个遇到这种困难的人。