【问题标题】:How do you mix raw SQL with ORM APIs when you use django.db?使用 django.db 时,如何将原始 SQL 与 ORM API 混合使用?
【发布时间】:2011-03-26 21:51:54
【问题描述】:

当我们需要的查询是简单的 selectinsert 子句时,ORM 工具非常有用。

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

您如何处理从原始查询orm查询返回的对象之间的差异?

【问题讨论】:

    标签: python sql orm django-models


    【解决方案1】:

    SQLAlchemy 在制定queries 时允许相当复杂,因此您通常可以在没有原始 sql 的情况下摆脱困境。如果您确实需要使用原始 sql,可以使用 connection.execute。但是有像 textselect functions 这样的助手可以让编程时更容易。至于处理返回的对象,您会得到一个元组列表,这些元组很容易以 Python 方式处理。

    一般来说,如果您需要将行(元组列表等)视为 ORM 返回的内容,一种方法是编写一个模仿查询集接口的适配器类。这可以使用返回的元组的“模式”进行初始化,然后迭代并返回具有属性而不是元组的对象。我并不真正需要它,但我可以看到它可能很有用,例如,如果你有一个依赖于传递查询集的框架。

    【讨论】:

    • 但元组不是对象,当与ORM API返回的对象混合时,我们必须至少设计两组操作来不同地处理它们,是吗?
    • 好的,我想我之前错过了你的问题,请查看更新。但简短的回答是,是的。适配器将是处理接口不匹配问题的最佳方法(元组或其他与查询集或其他对象相比)。
    【解决方案2】:

    我个人努力设计我的模型,这样我就不必推迟编写原始 SQL 查询,或者回退到在 ContentTypes 框架中混合复杂关系,所以我没有这方面的经验。

    该文档涵盖了performing raw SQL queries 的 API 主题。您可以在模型上使用 Manager.raw() (MyModel.objects.raw()) 进行查询,您可以将列映射回实际模型字段,或者用户 cursor 在数据库连接上查询原始行。

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

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

    【讨论】:

    • 是的,Manager.raw() 在执行原始 SQL 查询时有很大帮助。我想知道 SQLAlchemy 是否有类似的东西。
    猜你喜欢
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    • 2020-10-21
    • 2012-12-08
    • 1970-01-01
    • 2015-12-23
    • 2018-02-23
    • 1970-01-01
    相关资源
    最近更新 更多