Django 的 ORM 有哪些限制?

发布于 2025-01-01 12:43:00 字数 43 浏览 0 评论 0原文

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

I've heard developers not wanting to use ORM, but don't know why. What are the shortcomings of the ORM?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

几味少女 2025-01-08 12:43:00

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

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

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

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

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

在实践层面上,您会发现总有解决方法;一些开发人员会在支持/反对 ORM 方面存在党派差异,但我更喜欢混合方法。 Django 非常适合这一点,因为您可以根据需要轻松地使用原始 SQL。例如:

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

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

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

  • 当您拥有经常通过多个联接和聚合检索的复杂数据时。通常,手动编写 SQL 会更清晰。
  • 表现。 ORM 非常擅长构建优化查询,但没有什么可以与编写漂亮、高效的 SQL 相媲美。

但是,总而言之,在广泛使用 Django 之后,ORM 不允许我做我想做的事情的次数一只手就能数得过来。

Let me start by saying that I fully advocate the use of the ORM for most simple cases. It offers a lot of convenience when working with a very straightforward (relational) data model.

But, since you asked for shortcomings...

From a conceptual point of view, an ORM can never be an effective representation of the underlying data model. It will, at best, be an approximation of your data - and most of the time, this is enough.

The problem is that an ORM will map on a "one class -> one table" basis, which doesn't always work.

If you have a very complex data model - one which, ideally, cannot be properly represented by a single DB table - then you may find that you spend a lot of time fighting against the ORM, rather than having it work for you.

On a practical level, you'll find that there is always a workaround; some developers will be partisan in their support for/against an ORM, but I favour a hybrid approach. The Django works well for this, as you can easily drop into raw SQL as needed. Something like:

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

ORMs take a lot of the work out of the 99.99% of other cases, when you're performing simple CRUD operations against your data.

In my experience, the two best reasons to avoid an ORM altogether are:

  • When you have complex data that is frequently retrieved via multiple joins and aggregations. Often, writing the SQL by hand will be clearer.
  • Performance. ORMs are pretty good at constructing optimised queries, but nothing can compete with writing a nice, efficient piece of SQL.

But, when all's said and done, after working extensively with Django, I can count on one hand the number of occasions that the ORM hasn't allowed me to do what I want.

夕色琉璃 2025-01-08 12:43:00

SQLAlchemy 的创建者对这个问题的回答是 django 现在被认为是 pythonic。。这显示了很多差异和对系统的深刻理解。

reddit 中的sqlalchemy_vs_django_db 讨论

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

creator of SQLAlchemy's response to the question is django considered now pythonic.. This shows a lots of difference and deep understanding of the system.

sqlalchemy_vs_django_db discussion in reddit

Note: Both the links are pretty long, will take time to read. I am not writing gist of them which may lead to misunderstanding.

︶葆Ⅱㄣ 2025-01-08 12:43:00

Django 粉丝的另一个答案,但是:

  • 如果您使用继承和查询父类,则无法获取子类(而使用 SQLAlchemy 可以)。
  • Group ByHaving 子句确实很难使用 aggregate/annotate 进行翻译。
  • ORM 所做的一些查询非常长,有时您会遇到诸如 model.id IN [1, 2, 3... 可笑的长列表] 之类的内容
  • 有一种方法可以询问原始位置使用 __contains 表示“内容在字段中”,而不是“字段在内容中”。由于没有跨 DBMS 的可移植方法来执行此操作,因此为其编写原始 SQL 确实很烦人。如果您的应用程序开始变得复杂,就会出现很多像这样的小边缘情况,因为正如 @Gary Chambers 所说,DBMS 中的数据并不总是与 OO 模型匹配。
  • 这是一个抽象,有时抽象会泄漏< /a>.

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

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

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

Another answer from a Django fan, but:

  • If you use inheritance and query for parent classes, you can't get children (while you can with SQLAlchemy).
  • Group By and Having clauses are really hard to translate using the aggregate/annotate.
  • Some queries the ORM make are just ridiculously long, and sometimes you and up with stuff like model.id IN [1, 2, 3... ludicrous long list]
  • There is a way ask for raw where "stuff is in field" using __contains, but not "field is in stuff". Since there is no portable way to do this accross DBMS, writting raw SQL for it is really annoying. A lot of small edge cases like this one appear if your application starts to be complex, because as @Gary Chambers said, data in the DBMS doesn't always match the OO model.
  • It's an abstraction, and sometimes, the abstraction leaks.

But more than often, the people I meet that don't want to use an ORM do it for the wrong reason: intellectual laziness. Some people won't make the effort to give a fair try to something because they know something and want to stick to it. And it's scary how many of them you can find in computer science, where a good part of the job is about keeping up with the new stuff.

Of course, in some area it just make sense. But usually someone with good reason not to use it, will use it in other cases. I never met any serious computer scientist saying to it all, just people not using it in some cases, and being able to explain why.

And to be fair, a lot of programmers are not computer scientists, there are biologists, mathematician, teachers or Bob, the guy next door that just wanna help. From their point of view, it's prefectly logical to not spend hours to learn new stuff when you can do what you want with your toolbox.

酒与心事 2025-01-08 12:43:00

每个对象关系映射系统似乎都会出现各种问题,我认为关于这些问题的经典文章是 Ted Neward 写的,他将主题描述为 “计算机科学的越南”。 (还有一个针对该帖子评论的后续内容 以及来自 Stack Overflow 自己的 Jeff Atwood 此处.)

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

There are various problems that seem to arise with every Object-Relational Mapping system, about which I think the classic article is by Ted Neward, who described the subject as "The Vietnam of Computer Science". (There's also a followup in response to comments on that post and some comments from Stack Overflow's own Jeff Atwood here.)

In addition, one simple practical problem with ORM systems is they make it hard to see how many queries (and which queries) are actually being run by a given bit of code, which obviously can lead to performance problems. In Django, using the assertNumQueries assertion in your unit tests really helps to avoid this, as does using django-devserver, a replacement for runserver that can output queries as they're being performed.

遮了一弯 2025-01-08 12:43:00

我想到的最大问题之一是在 Django ORM 中构建继承是很困难的。本质上,这是由于 (Django) ORM 层试图通过关系型和关系型来弥合差距。哦。另一件事当然是多个字段外键。

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

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

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

One of the biggest problem that come to mind is that Building inheritance into Django ORM's is difficult. Essentially this is due to the fact that (Django) ORM layers are trying to bridge the gap by being both relational & OO. Another thing is of course multiple field foreign keys.

One charge leveled at Django ORM is that they abstract away so much of the database engine that writing efficient, scalable applications with them is impossible. For some kinds of applications - those with millions of accesses and highly interrelated models — this assertion is often true.

The vast majority of Web applications never reach such huge audiences and don't achieve that level of complexity. Django ORMs are designed to get projects off the ground quickly and to help developers jump into database-driven projects without requiring a deep knowledge of SQL. As your Web site gets bigger and more popular, you will certainly need to audit performance as described in the first section of this article. Eventually, you may need to start replacing ORM-driven code with raw SQL or stored procedures (read SQLAlchemy etc).

Happily, the capabilities of Django's ORMs continue to evolve. Django V1.1's aggregation library is a major step forward, allowing efficient query generation while still providing a familiar object-oriented syntax. For even greater flexibility, Python developers should also look at SQLAlchemy, especially for Python Web applications that don't rely on Django.

情绪少女 2025-01-08 12:43:00

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

我确实更喜欢 SqlAlchemy 而不是 Django ORM,对于 django.contrib.admin 不重要的项目,我倾向于使用 < a href="http://flask.pocoo.org/" rel="nofollow">Flask 而不是 Django。

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

IMHO the bigger issue with Django ORM is the lack of composite primary keys, this prevents me from using some legacy databases with django.contrib.admin.

I do prefer SqlAlchemy over Django ORM, for projects where django.contrib.admin is not important I tend to use Flask instead of Django.

Django 1.4 is adding some nice "batch" tools to the ORM.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文