如何在使用django.db时将原始SQL与ORM API混合?

4 投票
2 回答
1998 浏览
提问于 2025-04-16 02:29

ORM工具在我们需要简单的查询,比如select(选择)或insert(插入)时非常好用。

但是有时候,我们可能需要使用原始SQL查询,因为有些查询太复杂了,单靠ORM的接口无法提供高效和有效的解决方案。

那么,你会怎么处理从原始查询ORM查询返回的对象之间的差异呢?

2 个回答

1

SQLAlchemy 让我们在写 查询 时可以处理很多复杂的事情,所以通常不需要直接写原始的 SQL 语句。如果确实需要用到原始 SQL,可以使用 connection.execute。不过,还有一些辅助工具,比如 textselect 函数,可以让编程变得更简单。当你处理返回的对象时,你会得到一个元组的列表,这在 Python 中处理起来非常方便。

一般来说,如果你想把行(比如元组列表等)当作 ORM 返回的结果来处理,一种方法是写一个适配器类,模拟查询集的接口。这个适配器可以用返回的元组的“结构”来初始化,然后遍历这些元组,返回带有属性的对象,而不是简单的元组。我个人并没有真正需要这样做,但我能理解如果你有一个依赖于查询集传递的框架,这样做可能会很有用。

3

我个人的目标是设计我的模型,这样就不需要直接写原始的SQL查询,或者在复杂关系中使用ContentTypes框架,所以我在这个话题上没有经验。

文档中讲到了如何使用API来执行原始SQL查询。你可以在你的模型上使用Manager.raw()(比如MyModel.objects.raw()),适用于那些可以将列映射回实际模型字段的查询,或者使用cursor来直接查询数据库中的原始数据。

如果你打算使用Manager.raw(),那么你将处理RawQuerySet,而不是通常的QuerySet。在处理结果对象时,这两者的表现是一样的,但QuerySet功能更丰富。

我可以想象,在Django中执行原始SQL查询会比在没有ORM支持的框架中工作要更有成就感——Django可以管理你的数据库结构,并为你提供数据库连接,你只需要手动创建查询和设置查询参数。得到的结果可以作为列表或字典来访问,这两种方式都适合在模板中显示或进行进一步处理。

撰写回答