Django-Multitenant,分布式多租户数据库项目实战(Python/Django+Postgres+Citus)

简介: Django-Multitenant,分布式多租户数据库项目实战(Python/Django+Postgres+Citus)

Python/Django 支持分布式多租户数据库,如 Postgres+Citus

通过将租户上下文添加到您的查询来实现轻松横向扩展,使数据库(例如 Citus)能够有效地将查询路由到正确的数据库节点。


构建多租户数据库的架构包括:为每个租户创建一个数据库、为每个租户创建一个 schema 和让所有租户共享同一个表。这个库基于第三种设计,即让所有租户共享同一个表,它假设所有租户相关的模型/表都有一个 tenant_id 列来表示租户。


以下链接更多地讨论了何时以及如何为您的多租户数据库选择正确架构的权衡:

关于多租户的其他有用链接:

  1. https://www.citusdata.com/blog/2017/03/09/multi-tenant-sharding-tutorial/
  2. https://www.citusdata.com/blog/2017/06/02/scaling-complex-sql-transactions/


项目源码



https://github.com/citusdata/django-multitenant


安装



pip install --no-cache-dir django_multitenant


支持的 Django 版本/前提条件。



Python Django
3.X 2.2
3.X 3.2
3.X 4.0


用法



为了使用这个库,您可以使用 Mixins 或让您的模型从我们的自定义模型类继承。


模型变化


  1. 在要使用库的任何文件中导入它:


from django_multitenant.fields import *
from django_multitenant.models import *


  1. 所有模型都应继承 TenantModel 类。Ex: class Product(TenantModel):
  2. 定义一个名为 tenant_id 的静态变量,并使用该变量指定租户列。Ex: tenant_id='store_id'
  3. TenantModel 子类的所有外键都应使用 TenantForeignKey 代替 models.ForeignKey
  4. 实现上述 2 个步骤的示例模型:


class Store(TenantModel):
    tenant_id = 'id'
    name =  models.CharField(max_length=50)
    address = models.CharField(max_length=255)
    email = models.CharField(max_length=50)
  class Product(TenantModel):
    store = models.ForeignKey(Store)
    tenant_id='store_id'
    name = models.CharField(max_length=255)
    description = models.TextField()
    class Meta(object):
      unique_together = ["id", "store"]
  class Purchase(TenantModel):
    store = models.ForeignKey(Store)
    tenant_id='store_id'
    product_purchased = TenantForeignKey(Product)


使用 mixins 更改模型


  1. 在您要使用库的任何文件中,只需:


from django_multitenant.mixins import *


  1. 所有模型都应使用 TenantModelMixin 和 django models.Model 或您的客户模型类 Ex: class Product(TenantModelMixin, models.Model):
  2. 定义一个名为 tenant_id 的静态变量,并使用该变量指定租户列。Ex: tenant_id='store_id'
  3. TenantModel 子类的所有外键都应使用 TenantForeignKey 代替 models.ForeignKey
  4. 实现上述 2 个步骤的示例模型:


class ProductManager(TenantManagerMixin, models.Manager):
    pass
  class Product(TenantModelMixin, models.Model):
    store = models.ForeignKey(Store)
    tenant_id='store_id'
    name = models.CharField(max_length=255)
    description = models.TextField()
    objects = ProductManager()
    class Meta(object):
      unique_together = ["id", "store"]
  class PurchaseManager(TenantManagerMixin, models.Manager):
    pass
  class Purchase(TenantModelMixin, models.Model):
    store = models.ForeignKey(Store)
    tenant_id='store_id'
    product_purchased = TenantForeignKey(Product)
    objects = PurchaseManager()


db 层自动化复合外键:


  1. 使用 TenantForeignKey 在租户相关模型之间创建外键将自动将 tenant_id 添加到引用查询(例如 product.purchases)和连接查询(例如 product__name)。如果要确保在 db 层创建复合外键(带有 tenant_id),则应将 settings.py 中的数据库 ENGINE 更改为 django_multitenant.backends.postgresql


'default': {
      'ENGINE': 'django_multitenant.backends.postgresql',
      ......
      ......
      ......
    }


在哪里设置租户?


  1. 使用中间件编写身份验证逻辑,该中间件还为每个 session/request 设置/取消设置租户。这样,开发人员不必担心基于每个视图设置租户。只需在身份验证时设置它,库将确保其余部分(将 tenant_id 过滤器添加到查询中)。上面的示例实现如下:


from django_multitenant.utils import set_current_tenant
    class MultitenantMiddleware:
        def __init__(self, get_response):
            self.get_response = get_response
        def __call__(self, request):
            if request.user and not request.user.is_anonymous:
                set_current_tenant(request.user.employee.company)
            return self.get_response(request)


  1. 在您的设置中,您需要更新 MIDDLEWARE 设置以包含您创建的设置。


MIDDLEWARE = [
   # ...
   # existing items
   # ...
   'appname.middleware.MultitenantMiddleware'
]


  1. 在您希望基于租户范围的所有视图中使用 set_current_tenant(t)api 设置租户。这将自动(不指定显式过滤器)将所有 django API 调用范围限定为单个租户。如果未设置 current_tenant,则使用没有租户范围的 默认/原生 API。


支持的 API


  1. Model.objects.* 下的大部分 API
  2. Model.save() 为租户继承的模型注入 tenant_id


s=Store.objects.all()[0]
set_current_tenant(s)
#All the below API calls would add suitable tenant filters.
#Simple get_queryset()
Product.objects.get_queryset()
#Simple join
Purchase.objects.filter(id=1).filter(store__name='The Awesome Store').filter(product__description='All products are awesome')
#Update
Purchase.objects.filter(id=1).update(id=1)
#Save
p=Product(8,1,'Awesome Shoe','These shoes are awesome')
p.save()
#Simple aggregates
Product.objects.count()
Product.objects.filter(store__name='The Awesome Store').count()
#Subqueries
Product.objects.filter(name='Awesome Shoe');
Purchase.objects.filter(product__in=p);


相关文章
|
2月前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
14天前
|
消息中间件 canal 缓存
项目实战:一步步实现高效缓存与数据库的数据一致性方案
Hello,大家好!我是热爱分享技术的小米。今天探讨在个人项目中如何保证数据一致性,尤其是在缓存与数据库同步时面临的挑战。文中介绍了常见的CacheAside模式,以及结合消息队列和请求串行化的方法,确保数据一致性。通过不同方案的分析,希望能给大家带来启发。如果你对这些技术感兴趣,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!
48 6
项目实战:一步步实现高效缓存与数据库的数据一致性方案
|
2月前
|
存储 SQL 分布式数据库
OceanBase 入门:分布式数据库的基础概念
【8月更文第31天】在当今的大数据时代,随着业务规模的不断扩大,传统的单机数据库已经难以满足高并发、大数据量的应用需求。分布式数据库应运而生,成为解决这一问题的有效方案之一。本文将介绍一款由阿里巴巴集团自主研发的分布式数据库——OceanBase,并通过一些基础概念和实际代码示例来帮助读者理解其工作原理。
119 0
|
16天前
|
机器学习/深度学习 人工智能 算法
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
植物病害识别系统。本系统使用Python作为主要编程语言,通过收集水稻常见的四种叶片病害图片('细菌性叶枯病', '稻瘟病', '褐斑病', '稻瘟条纹病毒病')作为后面模型训练用到的数据集。然后使用TensorFlow搭建卷积神经网络算法模型,并进行多轮迭代训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地模型文件。再使用Django搭建Web网页平台操作界面,实现用户上传一张测试图片识别其名称。
68 21
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
|
16天前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
44 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
12天前
|
机器学习/深度学习 人工智能 算法
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
文本分类识别系统。本系统使用Python作为主要开发语言,首先收集了10种中文文本数据集("体育类", "财经类", "房产类", "家居类", "教育类", "科技类", "时尚类", "时政类", "游戏类", "娱乐类"),然后基于TensorFlow搭建CNN卷积神经网络算法模型。通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型,并保存为本地的h5格式。然后使用Django开发Web网页端操作界面,实现用户上传一段文本识别其所属的类别。
24 1
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
28天前
|
前端开发 搜索推荐 算法
中草药管理与推荐系统Python+Django网页界面+推荐算法+计算机课设系统+网站开发
中草药管理与推荐系统。本系统使用Python作为主要开发语言,前端使用HTML,CSS,BootStrap等技术和框架搭建前端界面,后端使用Django框架处理应用请求,使用Ajax等技术实现前后端的数据通信。实现了一个综合性的中草药管理与推荐平台。具体功能如下: - 系统分为普通用户和管理员两个角色 - 普通用户可以登录,注册、查看物品信息、收藏物品、发布评论、编辑个人信息、柱状图饼状图可视化物品信息、并依据用户注册时选择的标签进行推荐 和 根据用户对物品的评分 使用协同过滤推荐算法进行推荐 - 管理员可以在后台对用户和物品信息进行管理编辑
57 12
中草药管理与推荐系统Python+Django网页界面+推荐算法+计算机课设系统+网站开发
|
12天前
|
机器学习/深度学习 人工智能 算法
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台。果蔬识别系统,本系统使用Python作为主要开发语言,通过收集了12种常见的水果和蔬菜('土豆', '圣女果', '大白菜', '大葱', '梨', '胡萝卜', '芒果', '苹果', '西红柿', '韭菜', '香蕉', '黄瓜'),然后基于TensorFlow库搭建CNN卷积神经网络算法模型,然后对数据集进行训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地文件方便后期调用。再使用Django框架搭建Web网页平台操作界面,实现用户上传一张果蔬图片识别其名称。
32 0
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
2月前
|
搜索推荐 前端开发 数据可视化
基于Python协同过滤的旅游景点推荐系统,采用Django框架,MySQL数据存储,Bootstrap前端,echarts可视化实现
本文介绍了一个基于Python协同过滤算法的旅游景点推荐系统,该系统采用Django框架、MySQL数据库、Bootstrap前端和echarts数据可视化技术,旨在为用户提供个性化的旅游推荐服务,提升用户体验和旅游市场增长。
130 9
基于Python协同过滤的旅游景点推荐系统,采用Django框架,MySQL数据存储,Bootstrap前端,echarts可视化实现
|
2月前
|
人工智能 BI 数据处理
【优秀python django系统案例】基于python的医院挂号管理系统,角色包括医生、患者、管理员三种
本文介绍了一个基于Python开发的医院挂号管理系统,该系统包含医生、患者、管理员三种角色,旨在优化挂号流程,提高医疗服务质量和管理效率,并通过信息化手段提升患者就医体验和医院运营决策的数据支持能力。
【优秀python django系统案例】基于python的医院挂号管理系统,角色包括医生、患者、管理员三种
下一篇
无影云桌面