189 8069 5689

django对多个数据库支持-创新互联

数据库自动路由

使用多数据库最简单的方法是建立一个数据库路由模式。默认的路由模式确保对象’粘滞‘在它们原始的数据库上(例如,从foo 数据库中获取的对象将保存在同一个数据库中)。默认的路由模式还确保如果没有指明数据库,所有的查询都回归到default数据库中。

创新互联建站是专业的夷陵网站建设公司,夷陵接单;提供成都网站设计、成都网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行夷陵网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

你不需要做任何事情来激活默认的路由模式 —— 它在每个Django项目上’直接‘提供。然而,如果你想实现更有趣的数据库分配行为,你可以定义并安装你自己的数据库路由。

数据库路由

数据库路由是一个类,它提供4个方法:

  • db_for_read(model, **hints)

  • 建议model类型的对象的读操作应该使用的数据库。

    如果一个数据库操作能够提供其它额外的信息可以帮助选择一个数据库,它将在hints字典中提供。合法的hints 的详细信息在下文给出。

    如果没有建议,则返回None

  • db_for_write(model, **hints)

  • 建议Model 类型的对象的写操作应该使用的数据库。

    如果一个数据库操作能够提供其它额外的信息可以帮助选择一个数据库,它将在hints字典中提供。 合法的hints 的详细信息在下文给出。

    如果没有建议,则返回None

  • allow_relation(obj1, obj2, **hints)

  • 如果obj1 和obj2 之间应该允许关联则返回True,如果应该防止关联则返回False,如果路由无法判断则返回None。这是纯粹的验证操作,外键和多对多操作使用它来决定两个对象之间是否应该允许一个关联。

  • allow_migrate(db, app_label, model_name=None, **hints)

  • 定义迁移操作是否允许在别名为db的数据库上运行。如果操作应该运行则返回True ,如果不应该运行则返回False,如果路由无法判断则返回None

    位置参数app_label 是正在迁移的应用的标签。

    大部分迁移操作设置model_name的值为正在迁移的模型的model._meta.model_name(模型的__name__ 的小写)。对于RunPythonRunSQL 操作它的值为None,除非这两个操作使用hint 提供它。

    hints 用于某些操作来传递额外的信息给路由。

    当设置了model_name时,hints 通常通过键'model'包含该模型的类。注意,它可能是一个历史模型,因此不会有自定的属性、方法或管理器。你应该只依赖_meta

    这个方法还可以用来决定一个给定数据库上某个模型的可用性。

    注意,如果这个方法返回False,迁移将默默地不会在模型上做任何操作。这可能导致你应用某些操作之后出现损坏的外键、表多余或者缺失。

    Changed in Django 1.8:

    allow_migrate的签名与以前的版本相比发生了显着更改。有关详细信息,请参阅deprecation notes。

路由不必提供所有这些方法 —— 它可以省略一个或多个。如果某个方法缺失,在做相应的检查时Django 将忽略该路由。

例子:

DATABASES = {
    'auth_db': {
        'NAME': 'auth_db',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'swordfish',
    },
    'primary': {
        'NAME': 'primary',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'spam',
    },
    'replica1': {
        'NAME': 'replica1',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'eggs',
    },
    'replica2': {
        'NAME': 'replica2',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'bacon',
    },}

现在我们将需要处理路由。首先,我们需要一个路由,它知道发送auth 应用的查询到auth_db

class AuthRouter(object):
    """    A router to control all database operations on models in the    auth application.    """
    def db_for_read(self, model, **hints):
        """        Attempts to read auth models go to auth_db.        """
        if model._meta.app_label == 'auth':
            return 'auth_db'
        return None

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

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

    def allow_migrate(self, db, app_label, model=None, **hints):
        """        Make sure the auth app only appears in the 'auth_db'        database.        """
        if app_label == 'auth':
            return db == 'auth_db'
        return None

我们还需要一个路由,它发送所有其它应用的查询到primary/replica 配置,并随机选择一个replica 来读取:

import randomclass PrimaryReplicaRouter(object):
    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_list = ('primary', 'replica1', 'replica2')
        if obj1._state.db in db_list and obj2._state.db in db_list:
            return True
        return None

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

最后,在设置文件中,我们添加如下内容(替换path.to.为该路由定义所在的真正路径):

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

创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


分享文章:django对多个数据库支持-创新互联
网页网址:http://cdxtjz.cn/article/cdhdce.html

其他资讯