Django项目让本地和服务器环境数据库配置自动切换

Web开发中通常在本地进行开发,然后将代码部署到服务器上,这里就涉及本地环境和服务器环境数据库的配置。
我使用的服务器环境是新浪云(SAE),代码部署是通过git上传到指定的GIT仓库。
要切换两个数据库配置选项,最笨的办法是部署代码时设置为服务器数据库环境,本地测试时再把配置改回本地数据库环境。
这样就面临一个开发效率问题:如何在使用一套代码的情况下,让本地和服务器自动选择正确的数据库配置呢?

记得之前在浏览Django官网时有看到multi database配置,估计跟这有关系,上去找一下,果然看到有数据库路由设置。

一个Django项目可以设置多个数据库,比如设置数据库读写分离需要设置主从数据库,而究竟选择哪个数据库需要有负责路由的类来决定。
在settings.py中,DATABASES 设置数据库的配置表,而 DATABASE_ROUTERS 则设置路由数据库的类。
指定的Router类可以实现 db_for_read,db_for_write等方法
参考官网说明:https://docs.djangoproject.com/en/1.8/topics/db/multi-db/#topics-db-multi-db-routing

如何区分当前环境是本地还是服务器呢?

有几种方法:


1.使用导入服务器特有模块来判断,比如sae环境,如果导入sae模块成功说明是在服务器环境了。

@settings.py

# 数据库配置表
DATABASES = {
	# 默认使用本地数据库
    'default': { 
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_gallery',
        'USER': 'xxx',
        'PASSWORD': 'xxx',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    },
    # SAE数据库配置
    'remote': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'xxx',
        'USER': 'xxx',
        'PASSWORD': 'xxx',
        'HOST': 'w.rdc.sae.sina.com.cn',
        'PORT': '3307',
    }
}

#设置路由类
DATABASE_ROUTERS = ['Gallery.db_router.LocalRemoteRouter']

@db_router.py

import logging

logger = logging.getLogger('items')

class LocalRemoteRouter(object):
    """
    A router to decide select local or remote sae db
    """
    init = True
    local = True

    def is_local_env(self):
        local_env = False
        try:
            import sae
        except(ImportError):
            local_env = True
            logger.info("import sae error")
        else:
            local_env = False
            logger.info("import sae ok")
        return local_env

    def db_for_read(self, model, **hints):
        if self.init == True:
            self.init = False
            self.local = self.is_local_env()

        if self.local == True:
            return 'default'
        else:
            return 'remote'

    def db_for_write(self, model, **hints):
        if self.init == True:
            self.init = False
            self.local = self.is_local()

        if self.local == True:
            return 'default'
        else:
            return 'remote'


2.使用os模块变量判断

@db_router.py

import os

class LocalRemoteRouter(object):
    def db_for_read(self, model, **hints):
        if 'SERVER_SOFTWARE' in os.environ:
            # SAE
            return 'remote'
        else:
            # Local
            return 'default'


    def db_for_write(self, model, **hints):
        if 'SERVER_SOFTWARE' in os.environ:
            # SAE
            return 'remote'
        else:
            # Local
            return 'default'


部署代码到服务器上,打开首页,可以看到熟悉的画面了!


这样不论以后在本地还是服务器测试,数据库配置的代码不需要再改变!


====================================  更新 ===============================================

通常本地与服务器环境切换配置的不止数据库,还有其他参数,于是想到创建个文件专门处理:

@config.py  

import os
import logging
logger = logging.getLogger('items')

#本地配置参数
class Local():
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'xxx',
            'USER': 'xxx',
            'PASSWORD': 'xxx',
            'HOST': '127.0.0.1',
            'PORT': '3306',
        },
    }

#服务器配置参数
class Remote():
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'xxx',
            'USER': 'xxx',
            'PASSWORD': 'xxx',
            'HOST': 'w.rdc.sae.sina.com.cn',
            'PORT': '3307',
        }
    }

class MyConfig():
    __conf = None
    __is_remote = 'SERVER_SOFTWARE' in os.environ

    def is_remote_env(self):
        return self.__is_remote

    def get_config(self):
        if self.__conf == None:
            if self.__is_remote:
                logger.info("set remote config")
                self.__conf = Remote()
            else:
                logger.info("set local config")
                self.__conf = Local()
        return self.__conf

@settings.py 

使用MyConfig得到正确的配置对象,访问正确的配置参数

from config import MyConfig
my_config = MyConfig()

MEDIA_URL = my_config.get_config().MEDIA_URL
MEDIA_ROOT = my_config.get_config().MEDIA_ROOT

DATABASES = my_config.get_config().DATABASES

#DATABASE_ROUTERS = ['Gallery.db_router.LocalRemoteRouter']

该方法没有使用数据库Router,因此把原来设置的 DATABASE_ROUTERS 注释掉。

通过这种方法,两种环境下分别设置各自的参数即可。


展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读