步骤

1.创建虚拟环境
2.创建一个 Django 项目
3.创建数据库服务器

定义您的数据库

在 Django 中使用多个数据库的第一步是告诉 Django 您将使用的数据库服务器。这是使用DATABASES设置完成的。数据库可以有您选择的任何别名。但是,别名默认值具有特殊意义。当没有选择其他数据库时,Django 使用别名为 default 的数据库

以下是settings.py定义两个数据库的示例片段——一个默认的 PostgreSQL 数据库和一个名为users_db的 MySQL 数据库

DATABASES = {
    'default': {
        'NAME': 'app_data',
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'postgres_user',
        'PASSWORD': 's3krit'
    },
    'users_db': {
        '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'
    }
}

如果您尝试访问未在DATABASES设置中定义的数据库,Django 将引发django.utils.connection.ConnectionDoesNotExist异常

同步数据库

该迁移管理命令在一个数据库上同时运行。默认情况下,它在默认数据库上运行,但通过提供--database选项,您可以告诉它同步不同的数据库。因此,要将所有模型同步到上面第一个示例中的所有数据库,您需要调用

./manage.py migrate
./manage.py migrate --database=users

如果您不希望每个应用程序都同步到一个特定的数据库,您可以定义一个数据库路由器来实现一个策略来限制特定模型的可用性。如果像上面的示例一样,您将默认数据库留空,则每次运行migrate时都必须提供一个数据库名称

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

大多数其他与数据库交互的django-admin命令的操作方式与migrate相同——它们一次只对一个数据库进行操作,使用--database来控制所使用的数据库

此规则的一个例外是makemigrations命令。它会验证数据库中的迁移历史记录,以在创建新迁移之前发现现有迁移文件的问题。默认情况下,它只检查默认数据库,但如果安装了路由器,它会查询路由器的allow_migrate()方法

自动数据库路由

一旦您在DATABASES设置中定义了数据库,现在我们需要处理自动路由。

1.创建一个名为routers的文件夹
2.在文件夹内创建一个名为 db_routers.py
3.创建一个名为AuthRouter的数据库路由器来控制对auth和contenttypes 中模型的所有数据库操作- 在db_routers.py文件中添加以下代码

class AuthRouter:
    route_app_labels = {'auth', 'contenttypes'}

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'auth_db'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'auth_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        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):
        if app_label in self.route_app_labels:
            return db == 'auth_db'
        return None

如果模型的应用程序名称与其中的任何值匹配,则它将返回并使用所选数据库。在这种情况下,只有用户和帐户应用程序可以访问users_db数据库,因为它在route_app_labelsroute_app_labels

数据库路由器是一个类,最多提供四种方法:

1.db_for_read(model, **hints)
2.db_for_write(model, hints)
3.allow_relation(obj1, obj2, **hints)
4.allow_migrate(db, app_label, model_name=None, **hints)

连接路由器

使用DATABASE_ROUTERS设置安装数据库路由器。此设置定义了一个类名列表,每个类名都指定了一个应该由主路由器使用的路由器。

Django 的数据库操作使用主路由器来分配数据库使用。每当查询需要知道要使用哪个数据库时,它就会调用主路由器,提供模型和提示(如果可用)。然后 Django 依次尝试每个路由器,直到找到数据库建议。

最后,在设置文件中,我们添加以下代码(将path.to.替换为定义路由器的模块的实际 Python 路径)

DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.UsersRouter']

处理路由器的顺序很重要。路由器将按照它们在DATABASE_ROUTERS设置中列出的顺序进行查询。

在这个例子中,AuthRouter是之前处理UsersRouter,作为结果,作出任何其他决定之前,关于身份验证模型决定处理

手动选择数据库

Django 还提供了一个 API,允许您在代码中保持对数据库使用的完全控制。手动指定的数据库分配将优先于路由器分配的数据库。

您可以在 QuerySetchain中的任何一点为QuerySet选择数据库。在QuerySet上调用using()以获取另一个使用指定数据库的 QuerySet。

using()接受一个参数:要在其上运行查询的数据库的别名

例如

>>> # This will run on the 'default' database.
>>> Publisher.objects.all()

>>> # So will this.
>>> Publisher.objects.using('default').all()

>>> # This will run on the 'users' database.
>>> Publisher.objects.using('users').all()
点赞(0)

评论列表 共有 0 评论

暂无评论

微信服务号

微信客服

淘宝店铺

support@elephdev.com

发表
评论
Go
顶部