django - SQL用户的ORM指南?

sie*_*iew 9 sql django orm

django内置了这个复杂的ORM,但是在花了很多时间之后,我仍然很难在SQL中进行非常简单的查询.甚至有一些简单的事情我无法通过django ORM找到方法(例如'select table1 from tablename').

是否有任何文档显示"对于常见的SQL语句,这里是如何在django中执行此操作"?

(我之前尝试过谷歌,但要么它不在那里,要么我想不出正确的查询...)

jcd*_*yer 8

在SQL中有一些非常简单的东西,通过ORM很难或不可能.这被称为" 物体 - 关系阻抗不匹配".本质上,ORM将数据库中的每一行视为一个单独的对象.因此,涉及将值与其行分开处理的操作变得相当具有挑战性.Django(1.1+)的最新版本通过聚合支持在某种程度上改善了这种情况,但对于许多事情,只有SQL可以工作.

为此,django提供了几种让你简单地下载到原始sql的方法.其中一些将模型对象作为结果返回,而另一些则将您一直带到DBAPI2连接器.最低级别看起来像这样:

from django.db import connection

cursor = connection.cursor()
cursor.execute("SELECT DISTINCT column1 FROM tablename")
row = cursor.fetchone()
Run Code Online (Sandbox Code Playgroud)

如果要从SQL查询返回查询集,请使用模型管理器上的raw():

qs = ModelName.objects.raw("""SELECT first_name 
                              FROM myapp_modelname 
                              WHERE last_name = 'van Rossum'")
for person in qs:
     print person.first_name # Result already available
     print person.last_name  # Has to hit the DB again
Run Code Online (Sandbox Code Playgroud)

注意: raw()仅在Django的开发版本中可用,它应该从1.2开始合并到trunk中.

有关完整信息,请参阅执行原始SQL查询下的文档.


S.L*_*ott 6

这样想吧.

"对于常见的SQL hack-arounds,我本来应该做的面向对象的事情是什么?"

问题不在于ORM是复杂的.这就是你的大脑在SQL模型中被扭曲,使得很难清楚地看到物体.

通用规则:

  • 如果您认为这是一个简单的SELECT FROM WHERE,请停止.询问您需要在结果集中查看哪些对象.然后找到这些对象并使用对象管理器.

  • 如果您认为这是一个简单的JOIN,请停止.询问你想要什么主要对象.请记住,对象不使用外键.加入并不意味着什么.对象似乎打破1NF并包含其中的整个相关对象集.然后找到"主要"对象并使用对象管理器.使用相关对象查询来查找相关对象.

  • 如果您认为这是一个外部加入,请停止.询问您希望在结果集中看到哪两件事.外连接是将UNIONED与不会加入的东西连接起来的东西.首先是什么东西.然后找到"主要"对象并使用对象管理器.有些会有一组相关的对象.有些人不会.

  • 如果您认为它是子查询的WHERE EXISTS或WHERE IN,则您的模型可能不完整.有时,它需要花哨的加入.但如果您正在进行此类检查,通常意味着您需要在模型中使用属性.

  • 如果您认为需要SELECT DISTINCT,那么您完全错过了这艘船.那只是一个Python集.您只需将列值放入Python集中即可.这些是不同的价值观.

  • 如果您认为需要GROUP BY,则忽略Python collections.defaultdict.使用Python到GROUP BY通常比使用SQL更快.

    除了数据仓库.你不应该在Django做什么.您必须使用SQLAlchemy进行数据仓库.