django-SQL用户ORM指南?

django-SQL用户ORM指南?,sql,django,orm,Sql,Django,Orm,django内置了这个复杂的ORM,但在花了很多时间之后,我仍然很难用SQL进行非常简单的查询。甚至有一些简单的事情我无法通过django ORM实现(例如“从tablename中选择distinct column1”) 是否有任何文档显示“对于常见的SQL语句,这里是如何在django中实现的” (我确实先尝试了谷歌,但要么它不存在,要么我就是想不出正确的查询…进行Django查询的一个好起点是Django文档本身 以下是几个例子: select * from table = ModelNa

django内置了这个复杂的ORM,但在花了很多时间之后,我仍然很难用SQL进行非常简单的查询。甚至有一些简单的事情我无法通过django ORM实现(例如“从tablename中选择distinct column1”)

是否有任何文档显示“对于常见的SQL语句,这里是如何在django中实现的”


(我确实先尝试了谷歌,但要么它不存在,要么我就是想不出正确的查询…

进行Django查询的一个好起点是Django文档本身

以下是几个例子:

select * from table
=
ModelName.objects.all()
筛选:

select * from table where column = 'foo'
=
ModelName.objects.filter(column='foo')
特别是关于distinct的使用,您可以使用Django queryset的distinct()方法

以下是文档中的相关链接。

更新: ORM通过允许您对数据使用面向对象的交互来帮助您。您不会编写将查询结果集转换为一组对象的代码。它是自动完成的。这是你必须在思维过程中做出的根本性改变

你开始考虑‘我有这个对象,我需要得到所有其他类似的对象’,然后你可以向ORM索要这些对象。ORM,我需要Product类中所有属性为“蓝色”的对象

Django的特定ORM语言是:

products = Product.objects.filter(color='blue')
这样做,而不是:

  • 编写sql查询
  • 正确地避开所有的争论
  • 连接到数据库
  • 查询数据库并处理连接/查询错误
  • 获取结果集
  • 在结果集中迭代,将返回的值转换为可以调用方法的适当对象

这就是使用ORM的价值所在。代码简化和开发时间缩短。

在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()
MyModel.objects.values_list('column1', flat=True).distinct()
如果要从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
注意:raw()仅在Django的开发版本中可用,从1.2开始应该合并到主干中


下的文档中提供了完整信息

这样想吧

“对于常见的SQL黑客,我首先应该做的面向对象的事情是什么?”

问题不是ORM很复杂。这是因为你的大脑在SQL模型中扭曲了,很难清晰地看到对象

一般规则:

  • 如果你认为这是一个简单的选择从哪里,停止。询问您需要在结果集中看到哪些对象。然后找到这些对象并使用对象管理器

  • 如果您认为这是一个简单的连接,请停止。询问您想要的主要对象。记住,对象不使用外键。加入并不意味着什么。一个对象似乎打破了1NF,并包含一组完整的相关对象。然后找到“主要”对象并使用对象管理器。使用相关对象查询查找相关对象

  • 如果你认为这是一个外部连接,停止。询问您希望在结果集中看到的两件事。外部连接是将与不连接的事物联合的事物。首先是什么。然后找到“主要”对象并使用对象管理器。有些将有一组相关的对象。有些人不会

  • 如果您认为它是一个WHERE-EXISTS或WHERE-IN子查询,那么您的模型可能是不完整的。有时,它需要一个奇特的连接。但是,如果要进行这种检查,通常意味着您需要模型中的属性

  • 如果你认为你需要选择,那你就完全错过了机会。这只是一个Python集。只需将列值放入Python集中即可。这些是不同的价值观

  • 如果您认为需要一个分组依据,则忽略Python
    collections.defaultdict
    。使用Python分组通常比使用SQL快

    除了数据仓库。你不应该在Django这样做。数据仓库必须使用SQLAlchemy


对于您的具体操作,您可以这样做:

from django.db import connection

cursor = connection.cursor()
cursor.execute("SELECT DISTINCT column1 FROM tablename")
row = cursor.fetchone()
MyModel.objects.values_list('column1', flat=True).distinct()

但是其他海报说你不应该思考“我如何在ORM中编写SQL”是正确的。当你学习了Python,来自java或者C++或者其他什么东西,你很快就学会了如何从“Python中编写java代码”的思维方式出发,只专注于用Python解决这个问题。使用ORM也应该如此。

当然,我在询问之前阅读了文档,但在现代世界,我可以理解为什么您可能会做出相反的假设。我的问题是,文档没有非常有效地回答我的问题。我从未发现RDBMS很难理解,ORM应该如何“帮助”我也一点也不清楚。我希望能找到“旅行者的短语手册:SQL演讲者的Django”。为您更新了我的答案,我希望这有助于解释更多的思考过程。这为我做到了。关键点是ORM提取一组对象(“对象”~=“整行”),但SELECT DISTINCT的结果行不能连接到单个对象。所以,如果你需要ob