Django ORM 是不是在 sql where 子句中将已删除的字段映射到其他字段之前?

Posted

技术标签:

【中文标题】Django ORM 是不是在 sql where 子句中将已删除的字段映射到其他字段之前?【英文标题】:Does Django ORM map the deleted field before others in the sql where clause?Django ORM 是否在 sql where 子句中将已删除的字段映射到其他字段之前? 【发布时间】:2013-12-25 01:31:40 【问题描述】:

Django ORM 将映射这个查询集

TestModel.objects.filter(module="test", deleted=False)

到这个原始的 sql:

select coll1, coll2, coll3 from test_module where (TestModel.deleted=0 and TestModel.module="test")

无论你把“deleted”放在过滤器段落的什么位置,它都会排在where子句的首位。

我的第一个猜测是 Django 将所有 bool/tinyint 字段放在其他字段之前,但测试显示没有。似乎 Django 只是将名为“已删除”的字段放在其他人面前。很奇怪,但为什么呢?

因为我要给 mysql 表添加索引,所以顺序真的很重要。

【问题讨论】:

【参考方案1】:

关键字参数作为字典处理,具有任意顺序。 deleted 键恰好在该顺序中排在第一位:

>>> 'module': 'Test', 'deleted': False
'deleted': False, 'module': 'Test'

字典中的顺序由它们在底层哈希表中散列到的槽确定。一个小字典以 8 个插槽开头,'deleted' 散列到插槽 0,'module' 散列到插槽 6:

>>> hash('module') % 8
6
>>> hash('deleted') % 8
0

也就是说,由于Python字典的具体实现细节,'deleted'排在首位完全是巧合。 Django 确实决定故意首先列出该列。

这里的顺序无关紧要,SQL数据库也不在乎什么先出现。

【讨论】:

谢谢。但是当我过滤(模块=“测试”,删除=假,垃圾=假)时,删除仍然是第一位的,甚至在被删除之前。 为什么会出人意料?是什么让您认为'trashed' 会排在'deleted' 之前?本来可以,但事实并非如此。还有其他键可能也被插入哈希槽0,然后deleted 可能不是第一个。如果您创建更多的键,顺序也可能会改变。 Django 中没有任何东西 故意将deleted 放在首位。 巧合,只是因为Python字典的具体实现细节才把它列在前面。 我并不是说删除总是在先,我正在努力寻找它的规律。顺序很重要,因为我要添加 mysql 索引。 不,对于索引,顺序也无关紧要。有关 dict 排序的更多信息,请参阅***.com/questions/15479928/…。

以上是关于Django ORM 是不是在 sql where 子句中将已删除的字段映射到其他字段之前?的主要内容,如果未能解决你的问题,请参考以下文章

python测试开发django-78.ORM查询之extra

Django 使用 ORM 和条件 Where 子句连接表

在 WHERE 子句中使用函数编写 SQL SELECT 语句是不是有 Django 等效项?

Django ORM 替换额外的 where

Django ORM:带后续过滤的窗口函数

Django 补充ORM的extra过滤