Django多酒店独立数据部署及django-tenant-schemas迁移报错咨询
问题原因&解决方案
报错原因
- 核心配置错误:你将存放
TENANT_MODEL(也就是Hotel模型)的rooms应用放在了TENANT_APPS中,而django-tenant-schemas要求存放租户模型的应用必须加入SHARED_APPS,否则public schema不会创建Hotel表,执行migrate_schemas时无法读取租户列表,就会抛出TenantQueryset不可迭代的错误。 - 迁移顺序错误:你没有先执行public schema的独立迁移,直接执行全量迁移,导致租户表还未创建就尝试遍历租户。
- TENANT_APP的表不会在public schema生成属于正常逻辑:TENANT_APP的表是每个租户独立schema下单独创建的,public schema仅存储共享应用的表。
修复步骤
- 修改
settings.py配置,将rooms从TENANT_APPS移到SHARED_APPS中:
SHARED_APPS = [ 'tenant_schemas', 'rooms', # 新增到共享应用列表 'users', 'rosetta', 'widget_tweaks', 'import_export', # 其余原有共享应用保持不变 'django.contrib.contenttypes', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] TENANT_APPS = [ # 移除rooms,保留其余业务应用 'vistors', 'booking', 'costs', 'payments', 'cancel', ]
- 完善
Hotel模型配置,新增自动创建schema属性:
class Hotel(TenantMixin): hotel_name = models.CharField(max_length=40,unique=True) auto_create_schema = True # 新增该行,创建租户时自动生成对应schema def __str__(self): return self.hotel_name
- 按正确顺序执行迁移:
- 首先执行
python manage.py migrate_schemas --shared,仅迁移public schema,此时会在public中创建Hotel等所有共享应用的表 - 进入Django Shell,创建两个酒店租户实例,并绑定对应访问域名(django-tenant-schemas默认通过子域名区分租户,如
hotelA.yourdomain.com对应酒店A,hotelB.yourdomain.com对应酒店B) - 最后执行
python manage.py migrate_schemas,此时会遍历所有已创建的租户,为每个租户的独立schema生成TENANT_APP对应的业务表
- 首先执行
需求实现相关问题解答
该需求是否可以实现?
完全可以实现。配置完成后,你可以在public schema对应的首页视图中查询所有Hotel实例,渲染为指向对应子域名的跳转链接,用户点击进入对应子域名后,django-tenant-schemas会自动切换到对应租户的schema,所有业务查询默认仅访问当前租户的独立数据,完全符合你“菜单结构一致、数据完全隔离”的要求。
是否需要为两个酒店分别创建独立的模型?
不需要。所有租户共用同一套业务模型,每个租户的schema下会生成独立的表存储对应数据,不需要为不同酒店重复定义模型。
其他可选实现方案
如果不想引入多schema的租户配置复杂度,你也可以选择单schema加租户ID逻辑隔离的方案:
- 给所有业务模型新增
hotel外键字段,关联Hotel模型 - 编写中间件,根据用户访问的域名/路径参数识别当前访问的酒店,存入请求上下文
- 所有业务查询默认加上
hotel=当前酒店的过滤条件
该方案配置更简单,无需依赖PostgreSQL schema特性,仅2个租户的场景下完全够用,缺点是数据为逻辑隔离,若查询代码编写失误存在跨租户泄漏数据的风险。
内容的提问来源于stack exchange,提问作者artiest
相关产品推荐
相关产品推荐

