【问题标题】:What are the limitations of Django's ORM? [closed]Django 的 ORM 有什么限制? [关闭]
【发布时间】:2012-02-02 12:47:36
【问题描述】:

我听说开发人员不想使用 ORM,但不知道为什么。 ORM的缺点是什么?

【问题讨论】:

  • 一个很大的限制,至少对我来说,使用 Django 的 ORM 是它不能处理多个字段外键。
  • @JoachimPileborg:“多字段外键”——根据某些人的说法——是一个设计错误,可以通过使用代理键轻松解决。更重要的是。最好将您的答案作为答案发布,以便对其进行投票。
  • 它不支持复合主键,这是巨大的。除非架构超级简单或您首先了解 ORM 限制,否则不要使用它。我有过重要的表演。
  • 我在这里总结了一些让我重新考虑 Django 的要点:stackoverflow.com/q/18975376/781695

标签: python django orm


【解决方案1】:

首先,我完全提倡在大多数简单情况下使用 ORM。在使用非常简单的(关系)数据模型时,它提供了很多便利。

但是,既然你问的是缺点……

从概念的角度来看,ORM 永远不可能是底层数据模型的有效表示。它充其量只是您数据的近似值 - 大多数情况下,这已经足够了。

问题是 ORM 将映射在“一个类 -> 一个表”的基础上,这并不总是有效。

如果您有一个非常复杂的数据模型 - 理想情况下,它不能由单个 DB 表正确表示 - 那么您可能会发现您花费大量时间与 ORM 作斗争,而不是让它为您工作.

在实践层面上,您会发现总有一种解决方法;一些开发人员会在支持/反对 ORM 方面存在党派,但我更喜欢混合方法。 Django 对此非常有效,因为您可以根据需要轻松放入原始 SQL。比如:

Model.objects.raw("SELECT ...")

当您对数据执行简单的 CRUD 操作时,ORM 会从 99.99% 的其他情况中承担大量工作。

根据我的经验,完全避免使用 ORM 的两个最佳理由是:

  • 当您拥有通过多个联接和聚合频繁检索的复杂数据时。通常,手动编写 SQL 会更清晰。
  • 性能。 ORM 非常擅长构建优化的查询,但没有什么能比得上编写一段漂亮、高效的 SQL。

但是,总而言之,在与 Django 广泛合作之后,我一方面可以数出 ORM 不允许我做我想做的事的次数。

【讨论】:

  • 使用 Django,您可以创建代理模型,因此它不只是映射“一个类 -> 一个表”。
【解决方案2】:

creator of SQLAlchemy's response to the question is django considered now pythonic.。这显示了对系统的许多不同和深刻的理解。

sqlalchemy_vs_django_db discussion in reddit

注意:两个链接都很长,需要时间阅读。我不是在写它们的要点,这可能会导致误解。

【讨论】:

    【解决方案3】:

    来自 Django 粉丝的另一个回答,但是:

    • 如果对父类使用继承和查询,则无法获取子类(而使用 SQLAlchemy 可以)。
    • Group ByHaving 子句很难使用 aggregate/annotate 翻译。
    • ORM 提出的一些查询长得离谱,有时你会遇到model.id IN [1, 2, 3... ludicrous long list] 这样的问题
    • 有一种方法可以使用__contains 询问“字段中的内容”的原始位置,而不是“字段中的内容”。由于跨 DBMS 没有可移植的方法来执行此操作,因此为它编写原始 SQL 真的很烦人。如果您的应用程序开始变得复杂,就会出现很多像这样的小边缘情况,因为正如 @Gary Chambers 所说,DBMS 中的数据并不总是与 OO 模型匹配。
    • 这是一种抽象,有时是the abstraction leaks

    但我遇到的不想使用 ORM 的人往往出于错误的原因:智力上的懒惰。有些人不会努力公平地尝试某事,因为他们知道某事并想坚持下去。令人恐惧的是,您在计算机科学领域能找到多少这样的人,其中很大一部分工作就是跟上新事物的步伐。

    当然,在某些领域它只是有意义的。但通常有充分理由不使用它的人会在其他情况下使用它。我从来没有遇到过任何严肃的计算机科学家对这一切都说了,只是人们在某些情况下不使用它,并且能够解释原因。

    公平地说,很多程序员不是计算机科学家,有生物学家、数学家、教师或 Bob,隔壁的人只是想帮忙。从他们的角度来看,当您可以使用工具箱做自己想做的事情时,不花时间学习新东西是完全合乎逻辑的。

    【讨论】:

      【解决方案4】:

      似乎每个对象关系映射系统都会出现各种问题,我认为经典文章是由 Ted Neward 撰写的,他将主题描述为"The Vietnam of Computer Science"。 (还有一个 followup in response to comments on that post 和一些来自 Stack Overflow 自己的 Jeff Atwood here 的 cmets。)

      此外,ORM 系统的一个简单实际问题是,它们很难看出给定代码位实际运行了多少查询(以及哪些查询),这显然会导致性能问题。在 Django 中,在单元测试中使用assertNumQueries 断言确实有助于避免这种情况,就像使用django-devserver 一样,runserver 的替代品可以在执行查询时输出查询。

      【讨论】:

        【解决方案5】:

        想到的最大问题之一是在 Django ORM 中构建继承是困难的。本质上,这是因为(Django)ORM 层试图通过既是关系又是 OO 来弥合差距。另一件事当然是多字段外键。

        对 Django ORM 的一个指控是,它们抽象出太多的数据库引擎,以至于用它们编写高效、可扩展的应用程序是不可能的。对于某些类型的应用程序 - 具有数百万次访问和高度相关模型的应用程序 - 这种断言通常是正确的。

        绝大多数 Web 应用程序从未接触过如此庞大的受众,也没有达到那种复杂程度。 Django ORM 旨在快速启动项目并帮助开发人员进入数据库驱动的项目,而无需深入了解 SQL。随着您的网站变得越来越大,越来越受欢迎,您肯定需要按照本文第一部分的描述来审核性能。最终,您可能需要开始用原始 SQL 或存储过程(阅读 SQLAlchemy 等)替换 ORM 驱动的代码。

        令人高兴的是,Django 的 ORM 的功能不断发展。 Django V1.1 的聚合库向前迈出了一大步,它允许高效的查询生成,同时仍然提供熟悉的面向对象语法。为了获得更大的灵活性,Python 开发人员还应该研究 SQLAlchemy,尤其是对于不依赖 Django 的 Python Web 应用程序。

        【讨论】:

          【解决方案6】:

          恕我直言,Django ORM 的更大问题是缺少复合主键,这使我无法将一些遗留数据库与 django.contrib.admin 一起使用。

          我更喜欢 SqlAlchemy 而不是 Django ORM,对于 django.contrib.admin 不重要的项目,我倾向于使用 Flask 而不是 Django。

          Django 1.4 正在向 ORM 添加一些不错的“批处理”工具。

          【讨论】:

            猜你喜欢
            • 2015-03-31
            • 2014-08-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-08-22
            • 2010-10-01
            • 1970-01-01
            相关资源
            最近更新 更多