• django同一个项目中连接多个数据库


    一、场景与思路

    同一个项目中需要连接多个数据库。

    二、代码

    代码中主要是三个部分,settings、models以及自己写的一个类。

    1.自己写的文件:database_app_router.py  类名:DatabaseAppsRouter

    # database_app_router.py
    # -*- coding: utf-8 -*-
    from django.conf import settings
    
    DATABASE_MAPPING = settings.DATABASES_APPS_MAPPING
    
    
    class DatabaseAppsRouter(object):
        """
        A router to control all database operations on models for different
        databases.
    
        In case an app is not set in settings.DATABASE_APPS_MAPPING, the router
        will fallback to the `default` database.
    
        Settings example:
    
        DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'}
        """
    
        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

     settings.py文件中修改

    # settings.py
    
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.mysql",
            "NAME": "integral_wall",
            "USER": "root",
            "PASSWORD": "123456",
            "HOST": "127.0.0.1",
            "PORT": "3306",
        },
        "sdk_51zhuan": {
            "ENGINE": "django.db.backends.mysql",
            "NAME": "sdk_51zhuan",
            "USER": "root",
            "PASSWORD": "123456",
            "HOST": "127.0.0.1",
            "PORT": "3306",
        },
    }
    
    DATABASES_APPS_MAPPING = {
        'integral_wall': 'default',
        'sdk_db': 'sdk_51zhuan',
    'admin': 'sdk_51zhuan',
    'auth': 'sdk_51zhuan',
    } DATABASE_ROUTERS = ['integral_wall_manager.database_app_router.DatabaseAppsRouter']

     models.py文件修改

    # models.py
    
    class SdkApplication(models.Model):
        """
        应用程序列表
        """
        sdk_type_choices = (
            (0, '不合作'),
            (1, '一定时间内合作'),
            (2, '永久合作'),
        )
        id = models.AutoField(primary_key=True)
        app_id = models.CharField('苹果商店里的APP id', max_length=16, default='')
        app_name = models.CharField('应用名称', max_length=64)
        bundle_id = models.CharField('包ID,域名倒序', max_length=64, default='')
        create_time = models.DateTimeField('创建时间', auto_now_add=True)
    
        class Meta:
            app_label = 'sdk_db'  # 连接的数据库
            db_table = "sdk_application"  # 表名
    
    
    class AdRecord(models.Model):
        """
        广告记录
        """
        type = models.CharField('操作类型', max_length=16)
        action = models.CharField('操作、行为', max_length=16)
        create_time = models.DateTimeField('创建时间', auto_now_add=True)
    
        class Meta:
            # app_label 不写,使用默认
            db_table = "ad_record"  # 表名

    三、执行

    执行的顺序就是大家熟悉的了:

    1.python manage.py makemigrations

    之后的稍有不同:

    2.python manage.py migrate --database=sdk_51zhuan

    ......

    python manage.py migrate(只有默认数据库不为空时才可以这么实用,若为空则是用上面的方法)

    其实在这里没有特别的执行顺序,但是我个人建议大家是最后执行migrate(即默认数据库)。另外要注意一点,admin、auth是一定要在一个app里被makemigrations放到一个XXXX_initial.py文件中的,不然你怎么migrate都不会有这些Django自建的表的!


    ****最后的最后一定要注意:不在一个库里了,没法跨库建立约束关系,放弃外键,老老实实一步步查!****

  • 相关阅读:
    Oracle存储过程小记DUAL
    线程私有数据(TSD)
    Unix 五种基本I/O模型的区别
    Redis系列(0)应用场景
    linux ubuntu引导 win7
    Redis系列(一)启动流程分析
    c++ 内存管理小结
    设计模式Facade模式应用场景
    学会理财不做穷人
    jquery 注册验证例子
  • 原文地址:https://www.cnblogs.com/aaron-agu/p/11019226.html
Copyright © 2020-2023  润新知