• Home
  • 关于
    • 点滴 photo

      点滴

      这里没有东西,除了时间。

    • Learn More
    • Email
  • 所有文章
    • 文章
    • TAG

Django之migrate记录

18 Aug 2018

不积跬步,无以至千里;不积小流,无以成江海。

——荀子

前言

最近项目中使用到了Django,发现它的Model很好用,再加上migrate,配置好后,可以自动建表。由于项目是多人开发,且业务模块是不同的,所以存在多个数据库的情况,经过一番折腾终于配置好了支持多个APP和多个数据库。

多库支持

除了需要设置DATABASES中的数据库配置和DATABASES_APPS_MAPPING外,多个数据库还需要在settings.py文件中设置DATABASE_ROUTERS的值:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'default',
        'USER': 'user',
        'PASSWORD': 'passwd',
        'HOST': 'localhost',
        'PORT': '3306',
    },
    'myapp': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'myapp',
        'USER': 'user',
        'PASSWORD': 'passwd',
        'HOST': 'localhost',
        'PORT': '3306',
    },
}

DATABASES_APPS_MAPPING = {
    'default': 'default',
    'myapp': 'myapp',
}
DATABASE_ROUTERS = ['project.database_app_router.DatabaseAppsRouter']

在project目录下创建database_app_router.py文件,代码如下:

from django.conf import settings

class DatabaseAppsRouter(object):
    def db_for_read(self, model, **hints):
        app_label = model._meta.app_label
        if app_label in settings.DATABASES_APPS_MAPPING:
            res = settings.DATABASES_APPS_MAPPING[app_label]
            return res
        return None

    def db_for_write(self, model, **hints):
        app_label = model._meta.app_label
        if app_label in settings.DATABASES_APPS_MAPPING:
            return settings.DATABASES_APPS_MAPPING[app_label]
        return None

    def allow_relation(self, obj1, obj2, **hints):
        # 获取对应数据库的名字
        db_obj1 = settings.DATABASES_APPS_MAPPING.get(obj1._meta.app_label)
        db_obj2 = settings.DATABASES_APPS_MAPPING.get(obj2._meta.app_label)
        if db_obj1 and db_obj2:
            if db_obj1 == db_obj2:
                return True
            else:
                return False
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if db in settings.DATABASES_APPS_MAPPING.values():
            return settings.DATABASES_APPS_MAPPING.get(app_label) == db
        elif app_label in settings.DATABASES_APPS_MAPPING:
            return False
        return None

遇到的问题

正常的创建好model后,执行mirate即可创建好数据表。

python manage.py makemigrations myapp
python manage.py migrate myapp

不过多个数据库就会出现问题,一切都显示正常,但数据表并没有创建成功。需要添加–database参数,因为默认migrate执行时只会操作default数据库,没有使用default数据库的APP的更新将会被忽略。

python manage.py migrate --database=myapp myapp
#--database 的说明:
#Nominates a database to synchronize. Defaults to the "default" database.

结语

Django这个框架还是很不错的,其支持的功能也很丰富,但是网上的文档说明和教程等都是基于比较单个应用和数据库的,很少涉及多个数据库的情况,还是需要自己去探索。



DjangoPython Share Tweet +1