gpt4 book ai didi

python - 避免在 Django ORM 中多次引用同一个对象

转载 作者:太空狗 更新时间:2023-10-29 21:55:39 30 4
gpt4 key购买 nike

我们有一个具有高度相关数据的应用程序,即在许多情况下,两个对象可能通过关系引用同一个对象。据我所知,如果您尝试通过一个不同的、之前未评估的关系获取它,Django 不会尝试返回对已获取对象的引用。

例如:

class Customer( Model ):
firstName = CharField( max_length = 64 )
lastName = CharField( max_length = 64 )

class Order( Model ):
customer = ForeignKey( Customer, related_name = "orders" )

然后假设我们有一个客户在数据库中有两个订单:

order1, order2 = Order.objects.all()
print order1.customer # (1) One DB fetch here
print order2.customer # (2) Another DB fetch here
print order1.customer == order2.customer # (3) True, because PKs match
print id( order1.customer ) == id( order2.customer ) # (4) False, not the same object

当您拥有高度相关的数据时,对象的访问关系导致对数据库重复查询相同数据的程度会增加并成为一个问题。

我们也为 iOS 编程,关于 CoreData 的优点之一是它维护上下文,因此在给定的上下文中,给定的模型只有一个实例。在上面给出的示例中,CoreData 不会在 (2) 处进行第二次提取,因为它会使用内存中已有的客户来解决关系。

即使第 (2) 行被替换为旨在强制另一个数据库提取的虚假示例(如 print Order.objects.exclude( pk = order1.pk ).get( customer = order1.customer )),CoreData 会意识到第二次获取的结果解析为内存中的模型,并返回现有模型而不是新模型(即 (4) 会在 CoreData 中打印 True,因为它们实际上是同一个对象)。

为了对冲 Django 的这种行为,我们正在编写所有这些可怕的东西来尝试通过它们的 (type, pk) 在内存中缓存模型,然后检查与 _id 的关系 后缀尝试在盲目地用另一个获取命中数据库之前将它们从缓存中拉出。这会降低数据库吞吐量,但感觉确实很脆弱,如果通过属性进行的正常关系查找意外发生在我们无法控制的某些 contrib 框架或中间件中,则可能会导致问题。

Django 是否有任何最佳实践或框架来帮助避免此问题?有没有人试图将某种线程本地上下文安装到 Django 的 ORM 中以避免重复查找和将多个内存中实例映射到同一数据库模型?

我知道像 JohnnyCache 这样的查询缓存的东西在那里(并且有助于减少数据库吞吐量)但是仍然存在多个实例映射到相同底层模型的问题,即使这些措施已经到位。

最佳答案

大卫克莱默的 django-id-mapper是这样做的一种尝试。

关于python - 避免在 Django ORM 中多次引用同一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8914168/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com