【问题标题】:Dynamic database routing in DjangoDjango中的动态数据库路由
【发布时间】:2014-03-12 19:43:55
【问题描述】:

在我的数据库中,我在我的数据库中定义了一个 Customer 表,所有其他表都是外键的。

class Customer(models.Model):
    ...

class TableA(models.Model):
    Customer = models.ForeignKey(Customer)
    ...

class TableB(models.Model):
    Customer = models.ForeignKey(Customer)
    ...

我正在尝试实现一个数据库路由器,该路由器根据Customer 表的主键确定要连接的数据库。例如,ids 在 1 - 100 范围内将连接到数据库 A,ids 在 101 - 200 范围内将连接到数据库 B。

我已经阅读了routers 上的 Django 文档,但我不确定我所问的是否可行。具体来说,db_for_read(model, **hints)db_for_write(model, **hints) 方法适用于对象的 type。这对我来说没用,因为我需要基于对象实例的内容进行路由。该文档进一步指出,此时提供的唯一**hints 是适用的instance 对象,在某些情况下根本没有提供instance。这并不能激发我的信心,因为它没有明确说明没有提供instance 的情况。

我实际上是在尝试实现数据库的应用程序级分片。这在 Django 中可行吗?

【问题讨论】:

  • @ChrisWesseling 什么都没有。我已阅读文档并试图确定我正在尝试的内容是否可行。我更新了问题,详细说明了我的预期方法以及让我担心的原因。

标签: database django sharding


【解决方案1】:

解决鸡和蛋

在保存新客户时,您必须解决先有鸡还是先有蛋的问题。您必须保存才能获得 id,但您必须知道 id 才能知道保存位置。

您可以通过首先将所有客户保存在 DatabaseA 中来解决这个问题,然后检查 id 并将其也保存在目标数据库中。见Django multidb: write to multiple databases。如果您因此而这样做,您将不会遇到these problems。但请务必关注deleting 客户。

然后使用 **hints 路由

如果提示中有instance,剩下的路由问题就很简单了。要么它客户,您将返回“DatabaseA”,或者它客户,您将决定它的 customer_id 或 customer.id。

试着记住,没有勺子。

如果提示中没有实例,但它是来自您的应用程序的模型,则会引发错误,以便您可以更改创建查询集的代码。当提示不是自动添加时,您应该始终提供提示。

什么会真正烤出你的饼干

如果对于大多数查询,您有一个认识的客户,这没关系。但是想想像TableA.objects.filter(customer__name__startswith='foo')这样的查询

【讨论】:

  • 这看起来非常好,很有前途。我会试一试,看看我最终会得到什么。
  • 如果你对客户进行分片,并且所有东西都有客户。为什么不为每个客户制作一个设置文件和 SITE_ID?甚至可能从应用中删除客户?
  • 当我对客户进行分片时,我不希望每个客户都在他们自己的分片中。许多客户共享同一个分片,只有大客户才分配到他们自己的分片。我们目前都在一个数据库上,但我们将在接下来的 12 个月内进行分片。我已经设法根据您的帖子进行路由工作。再次感谢。
猜你喜欢
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-28
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多