2011-08-23 72 views
31

Short Question
连接到PostgreSQL数据库时,从Django过滤器调用返回的列表的默认顺序是什么?从Django过滤器调用返回的列表的默认顺序是什么?

背景
通过我自己也承认,我提出在应用一个糟糕的假设层,在其返回一个列表中的顺序将是常数,即不使用“ORDER_BY”。我查询的项目列表不是按照字母顺序或其他任何故意的顺序。它被认为保持与它们被添加到数据库中的顺序相同。

这种假设数百查询召开真实的,但一个故障报告了我的应用程序时的顺序不知不觉改变。据我所知,在这段时间内没有任何这些记录被触动,因为我是维护数据库的唯一人员。为了增加混淆,在Mac OS X上运行Django应用程序时,它仍然按预期工作,但在Win XP上,它改变了顺序。 (请注意,提到的数百个查询是在Win XP上)。

任何有识之士这将是有益的,因为我无法找到解释操作系统的差异的Django或PostgreSQL文档中的任何东西。

如通话

required_tests = Card_Test.objects.using(get_database()).filter(name__icontains=key) 

编辑
一些同事我的今天来说,我想出了相同的答案比约恩·林奎斯特。

回想起来,我肯定明白这是为什么错了,所以经常做。使用ORM Django,sqlalchemy或其他的好处之一是你可以编写命令,而不必知道或详细了解它所连接的数据库。无可否认,我恰好是这些用户之一。然而,另一方面,如果不详细地了解数据库,调试这样的错误非常麻烦并且可能是灾难性的。

回答

50

没有默认订单,这一点不能强调,因为每个人都错了。

在数据库中的表是不是一个普通的HTML表格,它是一个无序的元组的集合。它经常让仅仅用于MySQL的程序员感到意外,因为在那个特定的数据库中,行的顺序通常是可预测的,因为它没有利用一些先进的优化技术。例如,它是不可能知道哪个行会被退回,或者他们在以下任何的查询顺序:

select * from table limit 10 
select * from table limit 10 offset 10 
select * from table order by x limit 10 

在过去的查询,订单仅仅是可预见的,如果在列X的所有值都是唯一的。只要满足select语句的条件,RDBMS就可以随意返回任意顺序的行。

虽然你可能会增加对Django的水平默认的排序,这导致它BY子句添加以每个非有序查询:

class Table(models.Model): 
    ... 
    class Meta: 
     ordering = ['name'] 

注意,它可能是一个表现拖累,如果某些原因你不需要有序的行。

+0

尼斯公司交付:) – kronosapiens

-1

如果你想要让他们返回他们的顺序插入:

以下内容添加到你的模型:

created = models.DateTimeField(auto_now_add=True, db_index=True) 
# last_modified = models.DateTimeField(auto_now=True, db_index=True) 

class Meta: 
    ordering = ['created',] 
    # ordering = ['-last_modified'] # sort last modified first 
+0

而不是修改你的模型增加一个新的字段,为什么不只是通过大多数模型具有的自动递增ID来排序?它不受精度问题的影响(您不必担心DateTimeField的细微程度)或被系统时间更改所欺骗。 – aggieNick02

+0

只有在确定插入始终使用auto-incr时才有效。序列,并且从不重复使用未使用的ID,从其他DB或表创建的转储会设置创建的时间,但不会反映在主键的顺序中。当你真的想按日期进行排序时 - 使用ID并不透明 - 而且通常你真的想按last_modified排序 - 并且在这种情况下ID不起作用。 – Risadinha

+0

我同意有一些角落案例,你可能想要做一些自定义的事情,但默认情况下,每个模型都会得到一个自动递增的id,并且没有未使用的id重用。此外,使用DateTimeField时,如果两个模型的DateTimeField中的值相同,则会出现问题。这可能发生,取决于由于django版本/数据库后端的精度。 – aggieNick02

相关问题