Django配置多个数据库、算是一种负载均衡吧

 

以下内容是个人的随手记录,就是介绍了下简单的使用;

欢迎大家吐槽,接下来就是激情的时刻,准备好啤酒饮料矿泉水,开整!!!

 

项目使用环境:

- Python3.6.3

- Django==2.0.6

- Sqlite3

第一步:配置settings.py文件

# 这里是主配置我只是把我的配置贴出来(自己要对应上自己的项目)
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'authpermission',
    'webshow',
    'captcha',
    'commons',
    'accounts',
    'django_celery_results',
    'webshielddata'
]

################################################
#                                              #
#       database Configuration                 #
#                                              #
################################################
DATABASES = {
    'default': {},
    "webshield_web_db": {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(DBS_DIR, "webshield_web.db"),
    },
    "webshield_db": {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(DBS_DIR, "webshield.db"),
    }
}
DATABASE_ROUTERS = ['commons.database_router.Webshieldauthrouter']

DATABASE_APPS_MAPPING = {
    # Example
    # appname : database
    "admin": "webshield_web_db",
    "auth": "webshield_web_db",
    "contenttypes": "webshield_web_db",
    "sessions": "webshield_web_db",
    "accounts": "webshield_web_db",
    "authpermission": "webshield_web_db",
    "webshow": "webshield_web_db",
    "webshielddata": "webshield_db",
}

"default": Django默认选择使用的数据库、这里设置为空

"webshield_web_db": 数据库一

"webshield_db": 数据库二

"DATABASE_ROUTERS": 数据库路由配置配置内容见database_router.py文件,配置的路径为database_router.py文件的路径

"DATABASE_APPS_MAPPING": 数据库与app做映射,每个app对应使用的数据库

appname: 在主配置文件中INSTALLED_APPS列表中的名

注意:为了使django自己的表也创建到你自己定义的数据库中,你可以指定 : admin, auth, contenttypes, sessions 到设定的数据库中,如果不指定则会自动创建到默认(default)的数据库中.

 

第二步:创建database_router.py文件(此文件名可以自己随意起)

我的路径是: commons/database_router.py,此路径DATABASE_ROUTERS会使用

from django.conf import settings

DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING


class Webshieldauthrouter(object):
    """
        数据库路由、读写配置
    """
    def db_for_read(self, model, **hints):
        """
            设置从哪个表读取数据
        """
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None

    def db_for_write(self, model, **hints):
        """
            设置写入数据到哪个表
        """
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """
            表一(obj1)与表二(obj2)是否可以产生关联
        """
        db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)
        db_obj2 = DATABASE_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):
        """
            确定migrate操作是否可以在别名为db的数据库上运行
        """
        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(app_label) == db
        elif app_label in DATABASE_MAPPING:
            return False
        return None

 解释:

db_for_read():每个app从哪个数据库读取数据

db_for_write(): 每个app写数据写入那个数据库

allow_relation(): 允许同一数据库中每个app的表之间差生关系(Foreignkey, OneToOneField, ManyToManyField)

allow_migrate(): 确定migrate操作统一,要app与对应映射的数据库统一

 

第三步: django创建表例子

project_name(项目名)/appname1(app名)/models.py

from django.db import models


class Webshield_data(models.Model):
    """
        硬件提供数据表
    """
    access_id = models.IntegerField(
        verbose_name="访客id",
        null=True
    )

    def __unicode__(self):
        return self.id

    class Meta:
        app_label = "webshielddata"  # 这里很重要,是settings.py中INSTALLED_APPS列表对应的数据
        db_table = "webshield_data"
        verbose_name = "硬件提供数据"
        verbose_name_plural = verbose_name

提示:此表数据会存入webshield_db数据库

 

project_name(项目名)/appname2(app名)/models.py

from django.db import models


class data1(models.Model):
    """
        硬件提供数据表
    """
    name = models.Charfield(
        verbose_name="名称",
        max_length=521,
        null=True
    )

    def __unicode__(self):
        return self.name

    class Meta:
        app_label = "accounts"  # 这里很重要,是settings.py中INSTALLED_APPS列表对应的数据
        db_table = "data1"
        verbose_name = "测试数据"
        verbose_name_plural = verbose_name

提示:此表数据会存入webshield_web_db数据库

 

第四步:生成数据表

python3 manage.py makemigrations

# 创建表app对应的表到webshield_web_db数据库中
python3 manage.py migrate --database=webshield_web_db

# 创建表app对应的表到webshield_db数据库中
python3 manage.py migrate --database=webshield_db

# 创建表app对应的表到default数据库中(如果default配置存在)
python3 manage.py migrate

注意:与此相应的,dbshell,dumpdata,loaddata命令都有--database选项。

指定数据表导出:


python3 manage.py dumpdata app1.modelname --database=db1 > app1_fixture.json
python3 manage.py dumpdata app2.modelname --database=db2 > app2_fixture.json

第五步:使用CURD时注意事项

查询:

#### 查询(select)

# 查询 'default' 数据库.
Author.objects.all()

# 查询 'default' 数据库.
Author.objects.using('default').all()

# 查询 'webshield_web_db' 数据库.
Author.objects.using('webshield_web_db').all()

第一种添加方式: 

#### 添加

my_object.save(using='webshield_web_db')

第二种添加方式:  

#### 保存
p = Person(name='Fred')
p.save(using='first')  # (statement 1)
p.save(using='second') # (statement 2)

注意:第二种添加方式的代码会产生问题,当p在first数据库中第一次保存时,会默认生成一个主键,这样使用second数据库保存时,p已经有了主键,这个主键如果未被使用不会产生问题,但如果先前被使用了,就会覆盖原先的数据。

主键冲突问题解决办法:

解决方案一:

#### 解决办法一
p = Person(name='Fred')
p.save(using='first')
p.pk = None # Clear the primary key.
p.save(using='second') # Write a completely new object.

解决方案二:

#### 解决办法二
p = Person(name='Fred')
p.save(using='first')
p.save(using='second', force_insert=True)

删除:

u = User.objects.using('webshield_web_db').get(username='fred')
u.delete() # 从 `webshield_web_db` 库删除

将对象从B数据库移动到A数据库:

user_obj.save(using='A')
user_obj.delete(using='B')

总结:以上内容不仅仅是针对sqlite数据库、同时也适用mysql;

 

 

注意:以上内容是个人使用的随手记录, 就是介绍了下简单的使用

欢迎大家来吐槽,准备好瓜子饮料矿泉水,开整!!!

---------------------------------------------------------------------------------------

搞笑一则:能动手尽量别吵吵

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值