2011-08-23 69 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

相關問題