Django配置单APP对应多数据库避坑指南

本人python新手一枚,因业务需要使用到Django服务器。最先开始使用的是,单个数据库,因为Django当中对于单个APP对应单个数据库的情况,无需过多配置,所以本人并未花很长时间去配置数据库,直到今天业务需求改成了,单个APP对应多个数据库,因为是自学,所以只能上网查阅资料。陆续看了很多资料,也感谢各种大佬们提供的解决方案,也走过很多坑,历时四个小时最终搞定。

坑1

多个数据库的情况和单个的不一样。单个数据库无需额外创建APP,而多个数据库的情况,需要针对每个数据库都创建一个单独的APP。

坑2

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 'DjangoApp',
    # 'db1_app',
    # 'db2_app',
]

settings 当中不要注册任何的APP ,否则会在cmd 运行

python3.9 manage.py makemigrations  报一个重复注册DjangoApp的错误,注释掉所有的APP后程序顺利运行

坑3

DATABASES = {
    'default': {},
    'db1': {
        'ENGINE': 'django.db.backends.mysql',  # 使用的数据库引擎
        'NAME': '手机cookie',           # 数据库名称
        'USER': '手机cookie',           # 数据库用户名
        'PASSWORD': 'NFjrpk8SxEb8h4J4',   # 数据库密码
        'HOST': '127.0.0.1',           # 数据库服务器地址
        'PORT': '3306',           # 数据库端口(如果有必要)
        'OPTIONS': {
        'charset': 'utf8mb4',  # 或者 'utf8',根据 MySQL 版本和需求选择
        'init_command': "SET collation_connection = 'utf8_general_ci'",
        },
    },
    'db2': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '手机cookie_2',
        'USER': '手机cookie_2',
        'PASSWORD': 'AABEAEH2Gc3wNXH4',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'OPTIONS': {
            'charset': 'utf8mb4',  # 或者 'utf8'
            'init_command': "SET collation_connection = 'utf8_general_ci'",
        },
    },

}
#单个APP 如果要设置多个数据库 得在这里写上路由
DATABASE_APPS_MAPPING = {
    "db1_app": "db1",   # db1_app 对应 db1 数据库
    "db2_app": "db2"    # db2_app 对应 db2 数据库
}
DATABASE_ROUTERS = ['DjangoPro.database_router.DatabaseAppsRouter']

注意把default留空

坑4

#!/usr/bin/env python3.5
# -*- coding:utf-8 -*-


"""
file: database_router.py
date: 20180801
author: S_L_zheng@163.com
function: Multi-database use.
"""

from django.conf import settings
DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING


class DatabaseAppsRouter(object):
    """
    A router to control all database operations on models for different
    database.

    In case an app is not set in setting.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
        return None

    # Django 1.7 - Django 1.11
    def allow_migrate(self, db, app_label, model_name=None, **hints):
        print(db, app_label, model_name, hints)
        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(app_label) == db
        elif app_label in DATABASE_MAPPING:
            return False
        return None

上网部分资料当中的数据库路由是不可用的,我是在宝塔服务器当中部署的Django,因为宝塔的ide的识别不到错误代码,导致有些标红一大片的代码段被我直接粘贴到服务器中,调试多次后仍然失败。

坑5


#db1_app   
class MyModel(models.Model):
    # id = models.AutoField(primary_key=True)
    update_time = models.TextField()
    nick = models.TextField()
    cookie = models.TextField()

    class Meta:
        app_label  = 'db1_app'
        db_table = '手机cookie'

        

#db2_app   
class MyModel_2(models.Model):
    # id = models.AutoField(primary_key=True)
    update_time = models.TextField()
    nick = models.TextField()
    cookie = models.TextField()

    class Meta:
        app_label  = 'db2_app'
        db_table = '手机cookie_2'




        
            

meta 当中app_label   和 db_table 都不能省 省一个就报错

坑6

from db1_app.models import MyModel
from db2_app.models import MyModel_2

@csrf_exempt
def PhoneCkUpload(request):
    try:
        updatetime = datetime.datetime.now()
        tz_offset = datetime.timedelta(hours=8)  # UTC+8:00,即中国上海时区
        updatetime = datetime.datetime.now(datetime.timezone(tz_offset))
        updatetime = re.findall('(.*)\.', str(updatetime))[0]
        data = json.loads(request.body)
        nick = data.get('nick')
        cookie = data.get('cookie')
        nick = unquote(nick)
        #cookie = unquote(cookie)
     
        if updatetime and nick and cookie:
            try:
                # with transaction.atomic():
                #     MyModel.objects.create(update_time=updatetime, nick=nick, cookie=cookie)
                obj = MyModel(update_time=updatetime, nick=nick, cookie=cookie)
                obj.save()
                return JsonResponse({'message': 'Data written successfully!'})
            except Exception as e:
                return JsonResponse({'error': str(e)}, status=500)
        else:
            return JsonResponse({'error': 'Missing required fields.'}, status=400)

    except Exception as e:
        print(f"Exception occurred: {str(e)}")
        return JsonResponse({'error': 'Internal Server Error222.'}, status=500)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值