2010-08-08 38 views
2
当我们需要的查询是简单的 selectinsert子句时,

ORM工具非常棒。使用django.db时,如何将原始SQL与ORM API混合使用?

但有时我们可能不得不退回使用原始SQL查询,因为我们可能需要使查询变得如此复杂以至于只使用ORM API无法为我们提供高效且有效的解决方案。

你如何处理从原始查询 orm查询返回的对象之间的区别?

回答

2

我个人努力设计我的模型,所以我不必为了编写原始SQL查询而退化,或者在复杂的关系中混合使用ContentTypes框架,所以我没有关于该主题的经验。

的文件覆盖了API,用于performing raw SQL queries的话题。您可以使用您的模型(MyModel.objects.raw())的Manager.raw(),进行查询,你可以映射回柱实际示范田,或用户cursor到你的数据库连接上查询原始行。

如果您打算使用Manager.raw(),您将使用RawQuerySet而不是通常的QuerySet。对于所有涉及的问题,当使用结果对象时,两个模拟容器是相同的,但QuerySet是一个更具功能的monad。

我可以想象,在Django中执行原始SQL查询比使用不支持ORM支持的框架更有价值 - Django可以管理数据库模式并为您提供数据库连接,而且只需手动创建查询和定位查询参数。生成的行可以作为列表或词典访问,这两者都适合在模板中显示或执行额外提升。

+0

是的,执行原始SQL查询时,'Manager.raw()'有很多帮助。我想知道SQLAlchemy是否有类似的东西。 – satoru 2010-08-08 11:20:27

1

的SQLAlchemy让复杂的制定queries公平一点,所以你通常可以得到远没有原始的SQL。如果你确实需要倾听原始的sql,你可以使用connection.execute。但是,编程时,像textselectfunctions这样的助手可以使这更容易。至于处理返回的对象,你会得到一个元组清单,这些元组可以用pythonic的方式处理。

在一般情况下,如果你需要把行(元组的列表等)作为你的ORM的回报,一个办法是写一个适配器类,它模仿的queryset接口。这可以使用返回的元组的“模式”进行初始化,然后迭代并返回具有属性而不是元组的对象。我没有真正需要这个,但是我可以看到它是如何有用的,例如,如果你有一个依赖查询集传递的框架。

+0

但元组不是对象,当与ORM API返回的对象混合时,我们必须设计至少两组操作来处理它们,是这样吗? – satoru 2010-08-09 00:03:35

+0

好的,我想我错过了你的问题的重点,请看更新。但简短的回答是,是的。一个适配器将是处理这个不匹配接口(元组或其他对象与查询集或其他对象)问题的最佳方式。 – ars 2010-08-09 00:46:04