迁移时 Django 3 multi-base 不工作

Posted

技术标签:

【中文标题】迁移时 Django 3 multi-base 不工作【英文标题】:Django 3 multi-base not working when migrate 【发布时间】:2020-06-29 17:35:42 【问题描述】:

我将 Django 3 与 3 个应用程序一起使用:安全性、历史学家、工作台。 每个应用程序都有自己的数据库。 在 settings.py 中:

DATABASE_ROUTERS = [
    'security.router.securityRouter',
    'bench.router.benchRouter',
    'historian.router.historianRouter', 
    ]

DATABASES = 
    'default': 
        'ENGINE': 'sql_server.pyodbc',
        'NAME': 'DB_DJANGO',
        'HOST': 'LOCALHOST\\SQLEXPRESS',
        'PORT': '1433',
        'USER': 'user',
        'PASSWORD': '******',
        'OPTIONS':
            'driver': 'ODBC Driver 17 for SQL Server',
        
    ,
    'BdBench': 
        'ENGINE': 'sql_server.pyodbc',
        'NAME': 'BD_Bench',
        'HOST': 'LOCALHOST\\SQLEXPRESS',
        'PORT': '1433',
        'USER': 'sa',
        'PASSWORD': '5eCUr1tE',
        'OPTIONS':
            'driver': 'ODBC Driver 17 for SQL Server',
        
    ,
    'BdBenchMeas': 
        'ENGINE': 'sql_server.pyodbc',
        'NAME': 'BD_Bench',
        'HOST': 'LOCALHOST\\SQLEXPRESS',
        'PORT': '1433',
        'USER': 'user',
        'PASSWORD': '******',
        'OPTIONS':
            'driver': 'ODBC Driver 17 for SQL Server',
        
    ,
    'BdSecurity': 
        'ENGINE': 'sql_server.pyodbc',
        'NAME': 'BD_Security',
        'HOST': 'LOCALHOST\\SQLEXPRESS',
        'PORT': '1433',
        'USER': 'user',
        'PASSWORD': '******',
        'OPTIONS':
            'driver': 'ODBC Driver 17 for SQL Server',
        
    ,
    'BdHistorian': 
        'ENGINE': 'sql_server.pyodbc',
        'NAME': 'BD_Historian',
        'HOST': 'LOCALHOST\\SQLEXPRESS',
        'PORT': '1433',
        'USER': 'user',
        'PASSWORD': '******',
        'OPTIONS':
            'driver': 'ODBC Driver 17 for SQL Server',
        
    ,

我为每个应用程序使用:一个 router.py 文件:安全/router.py

class securityRouter(object):
    APPS = ['security', 'auth', 'sessions', 'contenttypes']
    BD = 'BdSecurity'

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.APPS:
            return self.BD
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.APPS:
            return self.BD
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label in self.APPS and obj2._meta.app_label in self.APPS:
            return True 
        return None     

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label in self.APPS:
            return db == self.BD
        return None

historian / router.py

class historianRouter(object):
    APPS = ['historian']
    BD = 'BdHistorian'

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.APPS:
            return self.BD
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.APPS:
            return self.BD
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label in self.APPS and obj2._meta.app_label in self.APPS:
            return True 
        return None     

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label in self.APPS:
            return db == self.BD
        return None

bench / router.py

class benchRouter(object):
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'bench':
            if model._meta.model_name == 'measurement':
                return 'BdBenchMeas'
            else:
                return 'BdBench'
        else:
            return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'bench':
            if model._meta.model_name == 'measurement':
                return 'BdBenchMeas'
            else:
                return 'BdBench'
        else:
            return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label == 'bench' and obj2._meta.app_label == 'bench':
            return True  
        return None       

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label == 'bench':
            return db == 'BdBench'
        return None

当我为每个应用迁移时:python manage.py migrate securitypython manage.py migrate historianpython manage.py migrate bench

我明白了: 在 BD_Security 数据库中没有表 在 BD_historian 数据库中没有表 在 BD_Bench 数据库中有 bench 和 historian 表。 在 DB_DJANGO 数据库中只有一个表 django_migrations

我用这个教程django-multidb 为什么我没有正确迁移我的应用程序/模型?

有人帮我吗?! 谢谢

【问题讨论】:

【参考方案1】:

如果您使用不同的数据库进行迁移,如果它不是默认数据库,则应始终添加 --database 开关。在docs 的第一段中是这样说的。

像这样:

python manage.py migrate security --database BdSecurity

【讨论】:

以上是关于迁移时 Django 3 multi-base 不工作的主要内容,如果未能解决你的问题,请参考以下文章

压缩 Django 迁移时的循环依赖

django迁移数据库报错解决

django数据迁移问题

Django迁移错误表已经存在

不知道为啥 django South 试图运行反向迁移

django迁移数据到mysql时提示异常