django中动态切换数据库

2024年9月30日 11:26 by wst

django

问题

在大型项目开发中,特别是针对B端的产品,不同的用户可能会采用不同的数据库。

那么怎么在后台动态切换数据库呢?

思路

我们可以在客户端保存一个变量,比如storeId,每次给后台发请求的时候,带上这个storeId。后台根据storeId切换数据库。

实例

目录结构:

核心文件:

app/views.py

import json
from django.http import JsonResponse

from .models import ABC, DbConnector

# Create your views here.
def test_tables(request):
    db_id = int(request.GET.get('id'))
    # 根据id查找对应的数据库参数
    if db_id == 1:
        record = DbConnector(db_id).my_custom_sql()
    else:
        record = DbConnector(db_id).my_custom_sql()
    db = json.loads(record[0])
    print("record:", record)
    # 根据找到的数据库参数获取数据
    data = ABC(db).get_tables()
    print("data:", data)
    return JsonResponse(data={"data":data, "database": db['database']})

app/models.py

from django.db import models
import pymysql
import pymysql.cursors
from django.db import connection

# Create your models here.
class ABC:
    "连接数据库获取数据"
    def __init__(self, db) -> None:
        self.conn = pymysql.connect(**db)

    def get_tables(self):
        cur = self.conn.cursor(pymysql.cursors.DictCursor)
        cur.execute("select * from table_list where id in (54,18)")
        res = cur.fetchall()
        return res


class DbConnector:
    "根据ID查找对应的数据库参数"
    def __init__(self, id) -> None:
        self.id = id
    def my_custom_sql(self):
        with connection.cursor() as cursor:
            cursor.execute("select dbinfo from store_list where id=%s"%self.id)
            row = cursor.fetchone()
        return row

补充文件:dbtest/__init__.py

import pymysql

pymysql.install_as_MySQLdb()

请求示例:

id=1的情况:

id=2的情况:

如果还是不能理解,可关注如下公众号,发送“动态切换数据库”获取源码:

注意:源码中的数据库参数已经隐藏,实际运行时请切换成自己的。

 

如果还有不理解或跑不通的,请加v:wst_ccut,询问。

-----------------后续------------------------------------------

关于变量的传递,除了用参数形式,还可以使用cookie。

1. 比如登录时在前端种一个cookie,存储storeId的值。这样每次往后端发请求会自动带上;

2. 如果是小程序场景,那么需要手动把storeId存储到storage中,往后端发请求时把storeId写入Header中,代码如下:

if (!header["SXF-TOKEN"]) {
    header["SXF-TOKEN"] = wx.getStorageSync("token") || "";
    header["Cookie"] = "storeId=" + wx.getStorageSync("storeId");
  }

 


Comments(0) Add Your Comment

Not Comment!