IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 刨析django----配置多个数据库 -> 正文阅读

[大数据]刨析django----配置多个数据库

django配置多个db

如下,配置两个数据库:

DATABASES = {
	# 默认的数据库,没有选择其他数据库时,就使用默认的,不使用时,可以配置一个空字典
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        "HOST": "xxxx",
        "PORT": "xxx",
        'USER': 'postgres_user',
        'PASSWORD': 's3krit',
        'NAME': 'app_data',
    },
    # users应用连接的数据库
    'users': {
        'ENGINE': 'django.db.backends.mysql',
        "HOST": "xxx",
        "PORT": 3306,
        'USER': 'mysql_user',
        'PASSWORD': 'priv4te',
        'NAME': 'users_data',
    }
}

迁移时,一次操作一个数据库:

# 仅操作默认的db
python manage.py migrate

# 操作users(别名)数据库
python manage.py migrate --database=users

默认的数据库,不使用时,可以配置一个空字典,但必须得定义,如下:


DATABASES = {
    'default': {},
    'users': {
        'ENGINE': 'django.db.backends.mysql',
        "HOST": "xx",
        "PORT": 3306,
        'USER': 'mysql_user',
        'PASSWORD': 'superS3cret',
        'NAME': 'user_data',
    },
    'customers': {
        'ENGINE': 'django.db.backends.mysql',
        "HOST": "xxx",
        "PORT": "3306",
        'USER': 'mysql_cust',
        'PASSWORD': 'veryPriv@ate',
        'NAME': 'customer_data',
    }
}

此时,必须定义模型类的数据库路由
?

数据库路由

在主应用下创建database_router.py,内部定义数据库路由类。
数据库路由是一个,提供如下四个方法:
db_for_read(model, **hints),模型类对象的读取

db_for_write(model, **hints),模型类对象的写入

allow_relation(obj1, obj2, **hints),表关系

allow_migrate(db, app_label, model_name=None, **hints), 是否允许迁移

1. 安装数据库路由:

# settings.py
# 配置数据库 一主两从
DATABASES = {
    'default': {},
    'auth_db': {
        'NAME': 'auth_db_name',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'swordfish',
    },
    'primary': {
        'NAME': 'primary_name',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'spam',
    },
    'replica1': {
        'NAME': 'replica1_name',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'eggs',
    },
    'replica2': {
        'NAME': 'replica2_name',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'bacon',
    },
}

# 配置 数据库路由
DATABASE_ROUTERS = ["project_name.database_router.AuthRouter", "xxx"]

# 按照顺序逐一查找

2. 定义数据库路由

# database_router.py
class AuthRouter:
    """
    A router to control all database operations on models in the
    auth and contenttypes applications.
    """
    # 指定使用某db的应用
    route_app_labels = {'auth', 'contenttypes'}

    def db_for_read(self, model, **hints):
        """
        Attempts to read auth and contenttypes models go to auth_db.
        """
        # 判断模型类的元类中的app_label
        if model._meta.app_label in self.route_app_labels:
            return 'auth_db'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write auth and contenttypes models go to auth_db.
        """
        if model._meta.app_label in self.route_app_labels:
            return 'auth_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """
        Allow relations if a model in the auth or contenttypes apps is
        involved.
        """
        if (
            obj1._meta.app_label in self.route_app_labels or
            obj2._meta.app_label in self.route_app_labels
        ):
           return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        Make sure the auth and contenttypes apps only appear in the
        'auth_db' database.
        app_label, 表示使用的数据库别名
        """
        if app_label in self.route_app_labels:
            return db == 'auth_db'
        return None

# 其他的应用  操作主从数据库
import random

class PrimaryReplicaRouter:
    def db_for_read(self, model, **hints):
        """
        Reads go to a randomly-chosen replica.
        """
        return random.choice(['replica1', 'replica2'])

    def db_for_write(self, model, **hints):
        """
        Writes always go to primary.
        """
        # 写入主库
        return 'primary'

    def allow_relation(self, obj1, obj2, **hints):
        """
        Relations between objects are allowed if both objects are
        in the primary/replica pool.
        """
        db_set = {'primary', 'replica1', 'replica2'}
        if obj1._state.db in db_set and obj2._state.db in db_set:
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        All non-auth models end up in this pool.
        """
        return True

在配置文件中,加入如下:


DATABASE_ROUTERS = ['project_name.database_router.AuthRouter', 'project_name.database_router。PrimaryReplicaRouter']

还需为应用下的模型类,指定使用的数据库:

class User(models.Model):
	...
	class Meta:
		db_table = "user"
		managed = True # 托管模式
		app_label = "users" # 通过users应用,使用指定的的db

# 迁移
python manage.py makemigratins users
python manage.py migrate users --database=auth_db

手动选择一个db

CRUD可以通过using(“xxx”)指定数据库,
优先级高于数据库路由

>>> # run on the 'default' database.
>>> Author.objects.all()
>>> Author.objects.using('default').all()

>>> # run on the 'other' database.
>>> Author.objects.using('other').all()

# 保存到指定数据库
>>> my_object.save(using='users_db')


# 主键重复问题
>>> p = Person(name='Fred')
>>> p.save(using='firstDB') # 先保存到第一个db 
>>> p.save(using='secondDB') # 再保存到第二个db,此时p是带有主键的,在写入第二个数据库时,会覆盖相同主键的数据,从而造成数据的丢失。采用如下方式解决: 
>>> p.pk = None # Clear the primary key.
>>> p.save(using='second') # 没有主键会被当成新对象,插入
或者采用强制插入的方式:
>>> p.save(using='second', force_insert=True)

# 保存与删除
>>> user_obj.save(using='new_users')
>>> user_obj.delete(using='legacy_users')

# 使用users_db 创建用户对象
>>> User.objects.db_manager('users_db').create_user(...)

django官网配置多个db

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-24 18:15:37  更:2022-05-24 18:19:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:44:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码