【问题标题】:Map raw SQL to multiple related Django models将原始 SQL 映射到多个相关的 Django 模型
【发布时间】:2010-10-20 01:49:33
【问题描述】:

由于性能原因,我不能使用 Django 的 ORM 查询方法,我必须使用原始 SQL 来处理一些复杂的问题。我想找到一种方法将 SQL 查询的结果映射到多个模型。

我知道我可以使用以下语句将查询结果映射到一个模型,但我不知道如何使用它来映射到相关模型(就像我可以在 Django 中使用 select_related 语句一样)。

model_instance = MyModel(**dict(zip(field_names, row_data)))

是否有一种相对简单的方法可以映射查询结果集中的相关表的字段?

【问题讨论】:

    标签: python sql mysql django django-models


    【解决方案1】:

    首先,你能证明 ORM 正在阻止你的表现吗?有时性能问题只是糟糕的数据库设计或不正确的索引。通常这是因为试图将 Django 的 ORM 强制安装到遗留数据库设计中。存储过程和触发器可能会对性能产生不利影响——尤其是在使用 Django 时,触发器代码应该在 Python 模型代码中。

    有时性能不佳是应用程序问题。这包括在数据库中进行的不必要的排序操作。

    最常见的性能问题是“过度获取”数据的应用程序。随便使用.all() 方法并创建大型内存集合。这会破坏性能。 Django 查询集必须尽可能少地被触及,以便将查询集迭代器提供给模板进行显示。

    一旦您选择绕过 ORM,您就必须解决对象关系阻抗不匹配问题。再次。具体来说,关系“导航”没有“相关”的概念:它必须是使用外键对关系集进行的一级提取。通过 SQL 组装一个复杂的内存对象模型非常困难。循环引用使这非常困难。将 FK 解析为集合很难。

    如果您要使用原始 SQL,您有两个选择。

    1. 避开“选择相关”——它不存在——实施起来很痛苦。

    2. 发明您自己的类似 ORM 的“选择相关”功能。一种常见的方法是添加有状态的 getter,它们 (a) 检查私有缓存以查看它们是否获取了相关对象,如果该对象不存在,(b) 从数据库中获取相关对象并更新缓存。

    在发明自己的有状态 getter 的过程中,您将重新发明 Django,您可能会发现它不是 ORM 层,而是数据库设计或应用程序设计问题。

    【讨论】:

    • 性能问题是由于我不得不绕过 ORM 本身的一些限制。数据库设计很好(没有遗留数据库)。也许我应该问是否有更简单的方法来用 Django 编写查询。在 SQL 中,查询非常简单。但这本身就是一个话题。 ;-)
    • 这就是我的观点——让 Django ORM 查询在 Django ORM 中实际工作,一切都会变得更好。无论“限制”是什么,都可能是一个简单的误解或可以修复的应用程序设计问题。
    • Answer 没有解决问题,而是表明问题可能出在其他地方。投了反对票。由于平台的缺点,即使是设计良好的数据库模式在特定数据库平台上扩展时也可能存在性能问题。这些缺点可以通过优化原始查询完全克服,暗示这是应用程序或模式设计问题是毫无根据的。有时问题/是/数据库,这就是被问到的问题。
    猜你喜欢
    • 2010-11-12
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多