我有一个多租户应用程序,它为所有租户使用共享表(只有一个数据库,只有一个模式)。
我的表存储来自不同客户的远程系统的实体,所有这些实体都有一个有效的主键(tenant,remote_id):
class Tenant(models.Model):
company_name = models.TextField()
class Post(models.Model):
tenant = models.ForeignKey(Tenant)
remote_id = models.IntegerField()
class Meta:
unique_together = (('tenant', 'remote_id'))
index_together = (('tenant', 'remote_id'))
(从技术上讲,我有自动增量整数主键,但它对我的问题并不重要,如果有所不同,我可以删除它们。)
在彼此之间,实体通过远程ID相互引用,租户总是相同的(租户之间没有交叉引用):
class Comment(models.Model):
tenant = models.ForeignKey(Tenant)
remote_id = models.IntegerField()
post_remote_id = models.IntegerField()
class Meta:
unique_together = (('tenant', 'remote_id'))
index_together = (('tenant', 'remote_id'))
Django不支持多值外键,因此我无法声明我的外键'就这样。
现在,当从本地数据库中检索实体时,我想通过SQL JOIN检索同一查询中的外键引用实体。通常情况下,你会使用Django的select_related(),但由于我还没有将它们声明为外键,我无法使用它。
这是我想要做的一个例子(并且只用一个查询就可以访问数据库!):
comments = Comment.objects.filter(author='Ernest').select_related()
commented_post_titles = [comment.post.title for comment in comments]
还有另一种方法可以以干净的方式获得相同的东西吗?我可以覆盖管理器类并使用JOIN执行自定义SQL。但是,我如何干净地创建模型实例并使它们相互链接而不会完全破坏Django的模型系统?
我首选的解决方案当然是某种models.ForeignKey
子类,其行为与常规外键(支持select_related(),遍历等)相同,但需要额外的tenant
列条件考虑到了。可以写出类似的东西吗?
强调:这些是简单的1对n关系。引用的实体可能不存在于我的本地数据库中(这就是为什么我不首先将这些关系转换为人工外键),但是那里有保证完全是0..1相关实体,绝不是多个实体。