Django的ORM有哪些局限性?

时间:2012-02-02 12:47:37

标签: python django orm

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

6 个答案:

答案 0 :(得分:8)

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

sqlalchemy_vs_django_db discussion in reddit

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

答案 1 :(得分:7)

首先我要说的是,我完全主张在大多数简单案例中使用ORM。使用非常简单(关系)的数据模型时,它提供了很多便利。

但是,既然你要求缺点......

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

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

如果您有一个非常复杂的数据模型 - 理想情况下,无法通过单个数据库表正确表示 - 那么您可能会发现您花费了大量时间来对抗ORM,而不是让它为您工作

在实际层面上,你会发现总有一种解决方法;一些开发人员将支持/反对ORM,但我赞成采用混合方法。 Django适用于此,因为您可以根据需要轻松地放入原始SQL。类似的东西:

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

当您针对数据执行简单的CRUD操作时,ORM会从99.99%的其他案例中完成大量工作。

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

  • 当您拥有经常通过多个联接和聚合检索的复杂数据时。通常,手工编写SQL会更清楚。
  • 性能。 ORM非常擅长构建优化查询,但没有什么可以与编写一个漂亮,高效的SQL竞争。

但是,当所有人都说完了,在与Django广泛合作之后,我可以一方面指望ORM不允许我按照自己的意愿行事的次数。

答案 2 :(得分:5)

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的人出于错误的原因这样做:智力懒惰。有些人不会努力做出公平的尝试,因为他们知道某些事情,并希望坚持下去。你可以在计算机科学中发现其中有多少是可怕的,其中很大一部分工作就是要跟上新的东西。

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

公平地说,很多程序员都不是计算机科学家,有生物学家,数学家,老师或鲍勃,隔壁的人只是想帮忙。从他们的角度来看,当你可以用你的工具箱做你想做的事情时,花几个小时学习新东西是完全合乎逻辑的。

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

我想到的最大问题之一是将继承构建到Django ORM中很困难。基本上这是因为(Django)ORM层试图通过兼顾和关系来弥补差距。 OO。另一件事当然是多个字段外键。

对Django ORM的一个指责是,它们抽象了大量的数据库引擎,因此用它们编写高效,可扩展的应用程序是不可能的。对于某些类型的应用程序 - 具有数百万次访问和高度相关的模型的应用程序 - 这种说法通常都是正确的。

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

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

答案 5 :(得分:0)

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

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

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