Django——多个数据库

Django——多个数据库

官方文档:https://docs.djangoproject.com/en/3.2/topics/db/multi-db/

主要介绍Django 对与多个数据库交互的支持。

1. 数据库服务器 DATABASES

在Django中使用多个数据库的第一步是告诉Django将要使用的数据库服务器。 这是通过使用 DATABASES 设置完成的。 这个设置将数据库别名映射到特定连接的设置字典中,别名是在Django中引用特定数据库的一种方式。 内部字典中的设置在DATABASES文档中有完整的描述。

数据库可以有您选择的任何别名。 但是,别名默认值有特殊的意义。 当没有选择其他数据库时,Django会使用default 别名的数据库。

下面是 settings.py 代码片段的一个例子,它定义了两个数据库——一个默认的 PostgreSQL 数据库和一个名为users的 MySQL 数据库:

DATABASES = {
    'default': {
        'NAME': 'app_data',
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'postgres_user',
        'PASSWORD': 's3krit'
    },
    'users': {
        'NAME': 'user_data',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'priv4te'
    }
}

如果默认数据库的概念在项目的上下文中没有意义,那么您需要始终谨慎地指定要使用的数据库。 Django要求定义一个默认的数据库条目,但是如果不使用的话,参数字典可以保留为空。 要做到这一点,你必须为所有应用程序的模型设置 DATABASE_ROUTERS,包括你正在使用的任何应用程序和第三方应用程序的模型,这样查询就不会路由到默认数据库

下面是 settings.py 代码段的一个示例,它定义了两个非默认数据库,默认条目故意为空:

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

如果你试图访问一个没有在 database 设置中定义的数据库,Django会抛出 Django.utils.connection. connectiondoesnotexist 异常。

2. 同步数据库

迁移管理命令一次操作一个数据库

(default是默认的数据库,在这里可以为{},但是一旦为空不可以执行 python manage.py migrate)

默认情况下,它在默认数据库上操作,但是通过提供 ——database 选项,可以告诉它同步一个不同的数据库。 因此,要将上面第一个例子中的所有模型同步到所有数据库,

您需要调用:

python manage.py makemigrations   # 生成迁移文件
python manage.py migrate --database=users

如果您不希望将每个应用程序同步到特定的数据库,那么可以定义一个数据库路由器,该路由器实现一个限制特定模型可用性的策略。

如果与上面的第二个示例一样,您将默认数据库保留为空,则必须在每次运行 migrate 时提供一个数据库名称(分多次迁移数据)。 省略数据库名称将引发错误。

对于第二个例子:

python manage.py migrate --database=users
python manage.py migrate --database=customers

3. 自动数据库路由(默认路由方案)

使用多个数据库的最简单方法是建立一个数据库路由方案

默认的路由方案确保对象保持“粘性”到他们的原始数据库(即,从 xxx 数据库检索的对象将保存在同一个数据库)。 默认路由方案确保如果没有指定数据库,所有查询都返回到默认数据库

你不需要做任何事情来激活默认路由方案——它是在每个Django项目中“开箱即用”提供的。

但是,如果您想实现更强大的数据库分配行为,您可以定义自己的数据库路由器

4. 自定义路由方案(数据库路由器)

一个 database Router 是一个提供了四个方法的类:

  • db_for_read(model, **hints)
    • 应用于读取类型对象的数据库模型,如果数据库提供附加信息会在hints字典中提供,最后如果没有则返回None
  • db_for_write(model, **hints)
    • 应用于写入类型对象的数据库模型,hints字典提供附加信息,如果没有则返回None
  • allow_relation(obj1, obj2, **hints)
    • 外键操作,判断两个对象之间是否是应该允许关系,是返回True,否则返回False,如果路由允许返回None
  • allow_migrate(db, app_label, model_name=None, **hints)
    • db确定是否允许在具有别名的数据库上运行迁移操作,操作运行返回True,否则返回False,或者返回None,如果路由器没有意见。
    • app_label:位置参数是正在迁移的应用程序的标签。
    • model_name:多个迁移操作设置模型的值,如:model._meta.app_label

路由器不必提供所有这些方法——它可以省略一个或多个。 如果其中一个方法被省略,Django将在执行相关检查时跳过该路由器。

4.1 使用路由器

使用 DATABASE_ROUTERS 设置安装数据库路由器。

这个设置定义了一个类名列表,每个类名指定一个主路由器(django.db.router)使用的路由器。

主路由器用于Django的数据库操作来分配数据库的使用。 每当查询需要知道使用哪个数据库时,它就调用主路由器,提供一个模型和一个提示(如果可用的话)。 然后Django依次尝试每个路由器,直到找到数据库建议。 如果找不到提示,则尝试提示实例的当前 instance._state.db。 如果没有提供提示实例,或者 instance._state.db 为None,主路由器将分配默认数据库。

4.2 案例
4.2.1 创建数据库路由

settings.py 同级目录下创建 数据库路由器( db_router.py ),app应用会根据指定的路由选择数据库:

from .settings import DATABASE_APPS_MAPPING

DATABASE_MAPPING = DATABASE_APPS_MAPPING


# 数据库路由分发
class database_router(object):

    def db_for_read(self, model, **hints):
        """"Point all read operations to the specific database."""
        """将所有读操作指向特定的数据库。"""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None
    
    def db_for_write(self, model, **hints):
        """Point all write operations to the specific database."""
        """将所有写操作指向特定的数据库。"""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """Allow any relation between apps that use the same database."""
        """允许使用相同数据库的应用程序之间的任何关系"""
        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
        else:
            return None

    def allow_syncdb(self, db, model):
        """Make sure that apps only appear in the related database."""
        """确保这些应用程序只出现在相关的数据库中。"""
        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(model._meta.app_label) == db
        elif model._meta.app_label in DATABASE_MAPPING:
            return False
        return None

    def allow_migrate(self, db, app_label, model=None, **hints):

        """Make sure the auth app only appears in the 'auth_db' database."""
        """确保身份验证应用程序只出现在“authdb”数据库中。"""

        if db in DATABASE_MAPPING.values():

            return DATABASE_MAPPING.get(app_label) == db
        elif app_label in DATABASE_MAPPING:
            return False
        return None
4.2.2 settings.py 配置

setting.py 中配置 DATABASE_ROUTERS 指定自由路由文件:

# 数据库设置, xxxx0001为项目名称
DATABASE_ROUTERS = ['xxxx0001.db_router.database_router']

setting.pyDATABASE_ROUTERS 下面设置app与数据库匹配路由表,采用字典方式app名对应数据库映射名:

DATABASE_APPS_MAPPING = {
    'app01':'default',
    'app02':'db2',
}
4.2.3 生成表并同步数据

分别在app01和app02下创建model类,用于生成数据表:

此处只定义了 app02 的模型,注意:加上app_label以后就会指明所属的app

from django.db import models

class IntelligentTableView(models.Model):
    table_name = models.CharField(max_length=255, verbose_name='报表名称')
    center = models.CharField(max_length=50, verbose_name='所属中心')
    on_line = models.CharField(max_length=50, verbose_name='所属线条')
    remake = models.CharField(max_length=255, verbose_name='备注')
    create_name = models.CharField(max_length=50, verbose_name='创建人')
    create_date = models.DateTimeField(auto_now=True, verbose_name='创建时间')
    is_del = models.BooleanField(default=False, verbose_name='是否删除')

    class Meta:
        db_table = 'intelligent_table'   # 表名
        verbose_name = '智能报表'
        app_label = 'app02'  # 指明app名称,用来对应app 和 数据库的map表

migrate管理命令一次只能操作一个数据库,默认操作default数据库,使用–database指定同步的数据库:

python manage.py migrate                # 生成表数据同步
python manage.py makemigrations         # # 生成迁移文件
python manage.py migrate --database=default # 同步指定数据库
python manage.py migrate --database=db2
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django中配置多个数据库,你需要进行以下步骤: 1. 在Django项目的settings.py文件中,找到DATABASES配置项。默认情况下,该配置项包含一个名为"default"的数据库配置。 2. 添加一个新的数据库配置,可以使用任何你想要的名称,例如"second_db"。在DATABASES中添加一个新的字典,类似于以下示例: ```python DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'first_database', 'USER': 'your_username', 'PASSWORD': 'your_password', 'HOST': 'localhost', 'PORT': '3306', }, 'second_db': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'second_database', 'USER': 'your_username', 'PASSWORD': 'your_password', 'HOST': 'localhost', 'PORT': '3306', } } ``` 在上面的示例中,我们添加了一个名为"second_db"的数据库配置,并提供了相应的数据库连接信息。 3. 在你的Django应用程序中,如果你希望使用新的数据库配置,你可以在models.py中为特定模型指定数据库。在模型类的内部,可以使用`using`属性来指定要使用的数据库配置。例如: ```python class MyModel(models.Model): # 模型字段定义... class Meta: using = 'second_db' ``` 通过将模型的`Meta`类中的`using`属性设置为你想要使用的数据库配置名称,你可以将该模型与特定的数据库关联起来。 这样,你就可以在Django中配置多个数据库,并根据需要在应用程序中使用不同的数据库配置。记得根据实际情况修改数据库引擎、数据库名、用户名、密码、主机和端口等信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值