由于性能原因,我不能使用Django的ORM查询方法,我必须使用原始SQL来处理一些复杂的问题。我想找到一种方法将SQL查询的结果映射到几个模型。
我知道我可以使用以下语句将查询结果映射到一个模型,但我无法想象如何使用它来映射到相关模型(就像我可以通过在Django中使用select_related语句来做到) )。
model_instance = MyModel(**dict(zip(field_names, row_data)))
是否有一种相对简单的方法可以映射同样位于查询结果集中的相关表的字段?
答案 0 :(得分:1)
首先,你能证明ORM会阻止你的表现吗?有时,性能问题只是糟糕的数据库设计或不正确的索引。通常这是因为尝试将Django的ORM强制适应遗留数据库设计。存储过程和触发器可能会对性能产生负面影响 - 尤其是在使用Django时,触发器代码应该在Python模型代码中。
有时性能不佳是一个应用问题。这包括在数据库中进行不必要的按订单操作。
最常见的性能问题是“过度提取”数据的应用程序。随便使用.all()
方法并创建大型内存中集合。这将破坏性能。必须尽可能少地触摸Django查询集,以便将查询集迭代器提供给模板进行显示。
一旦选择绕过ORM,就必须解决对象关系阻抗不匹配问题。再次。具体来说,关系“导航”没有“相关”的概念:它必须是使用外键的关系集的第一类获取。通过SQL组装复杂的内存中对象模型非常困难。循环引用使这很难;将FK解析为集合很难。
如果您要使用原始SQL,则有两种选择。
Eschew“选择相关” - 它不存在 - 实施起来很痛苦。
创建您自己的类似ORM的“选择相关”功能。一种常见的方法是添加有状态的getter,它们(a)检查私有缓存以查看它们是否已获取相关对象,如果该对象不存在,(b)从数据库中获取相关对象并更新缓存。
在发明你自己的有状态getter的过程中,你将重新发明Django,你可能会发现它不是ORM层,而是数据库设计或应用程序设计问题。