跳转到主要内容

使用PostgreSQL模式为Django提供租户支持。

项目描述

PyPi version PyPi downloads Python versions Travis CI PostgreSQL

此应用程序使由django驱动的网站能够通过PostgreSQL模式拥有多个租户。这是每个SaaS网站的必备功能。

Django目前没有简单的方法来支持使用相同项目实例的多个租户,即使只有数据不同。因为我们不希望您运行许多项目副本,您将能够拥有

  • 多个客户在同一实例上运行

  • 共享和租户特定数据

  • 租户视图路由

什么是模式

模式可以看作是操作系统中的一个目录,每个目录(模式)都有自己的文件集(表和对象)。这允许在不同模式中使用相同的表名和对象而不冲突。有关模式的确切描述,请参阅PostgreSQL关于模式的官方文档

为什么使用模式

通常有三种解决多租户问题的方案。

  1. 隔离方法:独立数据库。每个租户都有自己的数据库。

  2. 半隔离方法:共享数据库,独立模式。一个数据库供所有租户使用,但每个租户有一个模式。

  3. 共享方法:共享数据库,共享模式。所有租户共享同一个数据库和模式。存在一个主租户表,其他所有表都通过外键指向它。

此应用程序实现了第二种方法,我们认为这代表了简单性和性能之间的理想折中。

  • 简单性:几乎不需要对您的现有代码进行任何更改即可支持多租户。此外,您只需管理一个数据库。

  • 性能:利用共享连接、缓冲区和内存。

每种解决方案都有其优缺点,对于更深入的讨论,请参阅微软关于多租户数据架构的优秀文章。

它的工作原理

租户通过其主机名(例如 tenant.domain.com)进行识别。此信息存储在public模式的一个表上。每当有请求时,都会使用主机名来匹配数据库中的租户。如果找到匹配项,则更新搜索路径以使用此租户的模式。因此,从现在起所有查询都将在此租户的模式中执行。例如,假设您有一个位于http://customer.example.com的租户customer。任何进入customer.example.com的请求将自动使用customer的模式并使租户在请求中可用。如果没有找到租户,将引发404错误。这也意味着您应该为您的主域名有一个租户,通常使用public模式。有关更多信息,请阅读设置部分。

此应用程序能做什么?

您想要的任何数量的租户

每个租户在其特定的模式上都有自己的数据。使用单个项目实例来服务尽可能多的租户。

租户特定和共享应用程序

租户特定的应用程序不会在租户之间共享其数据,但您也可以拥有共享应用程序,其中信息始终可用并可共享。

租户视图路由

您可以针对http://customer.example.com/http://example.com/使用不同的视图,即使Django只使用主机名后面的字符串来识别要服务的视图。

魔法

每个人都喜欢魔法!您几乎不需要更改代码就能拥有所有这些功能!

设置与文档

这只是一个简短的设置指南,强烈建议您在django-tenant-schemas.readthedocs.io上阅读完整版本。

您的DATABASE_ENGINE设置需要更改为

DATABASES = {
    'default': {
        'ENGINE': 'tenant_schemas.postgresql_backend',
        # ..
    }
}

将中间件tenant_schemas.middleware.TenantMiddleware添加到MIDDLEWARE_CLASSES的顶部,以便每个请求都可以设置为使用正确的模式。

MIDDLEWARE_CLASSES = (
    'tenant_schemas.middleware.TenantMiddleware',
    #...
)

tenant_schemas.routers.TenantSyncRouter添加到您的DATABASE_ROUTERS设置中,以便根据同步的内容(共享或租户)同步正确的应用程序。

DATABASE_ROUTERS = (
    'tenant_schemas.routers.TenantSyncRouter',
)

tenant_schemas添加到您的INSTALLED_APPS中。

创建您的租户模型

from django.db import models
from tenant_schemas.models import TenantMixin

class Client(TenantMixin):
    name = models.CharField(max_length=100)
    paid_until =  models.DateField()
    on_trial = models.BooleanField()
    created_on = models.DateField(auto_now_add=True)

settings.py中定义您的租户模型。假设您在一个名为customers的应用程序中创建了Client,则您的TENANT_MODEL应如下所示

TENANT_MODEL = "customers.Client" # app.Model

现在运行migrate_schemas以将您的应用程序同步到public模式。

python manage.py migrate_schemas --shared

就像正常的Django模型一样创建您的租户。调用save将自动创建和同步/迁移模式。

from customers.models import Client

# create your public tenant
tenant = Client(domain_url='tenant.my-domain.com',
                schema_name='tenant1',
                name='My First Tenant',
                paid_until='2014-12-05',
                on_trial=True)
tenant.save()

tenant.my-domain.com 发出的任何请求现在将自动将您的 PostgreSQL 的 search_path 设置为 tenant1public,从而使共享应用程序也变得可用。这意味着对 filtergetsavedelete 或涉及数据库连接的任何其他函数的调用现在将在租户的模式下执行,因此您不需要在视图中进行任何更改。

您已设置完毕,但我们没有在这个简短的教程中提供关键细节,例如创建公共租户和配置共享和特定于租户的应用程序。完整说明可在 django-tenant-schemas.readthedocs.io 找到。

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源分发

django-tenant-schemas-1.12.0.tar.gz (60.5 kB 查看散列)

上传时间

构建分发

django_tenant_schemas-1.12.0-py3-none-any.whl (42.4 kB 查看散列)

上传时间 Python 3

支持者:

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面