web-dev-qa-db-ja.com

Djangoフィルター呼び出しから返されるリストのデフォルトの順序は何ですか?

短い質問
PostgreSQLデータベースに接続したときにDjangoフィルター呼び出しから返されるリストのデフォルトの順序は何ですか?

背景
私自身の許可により、私hadは、アプリケーションレイヤーで、リストが返される順序は定数、つまり「order_by」を使用しない場合。私が問い合わせていた項目のリストはアルファベット順またはその他のdeliberate順ではありません。データベースに追加された順序と同じであると考えられていました。

この仮定は何百ものクエリに当てはまりましたが、無意識のうちに順序が変わったときに、アプリケーションによってエラーが報告されました。私の知る限り、DBを管理しているのは私だけなので、この間、これらのレコードは変更されませんでした。混乱を増すために、DjangoアプリをMac OS Xで実行すると、期待どおりに機能しましたが、Win XPでは順序が変更されました(前述の数百のクエリが勝利XPで)。

Djangoまたはオペレーティングシステムの違いを説明するPostgreSQLのドキュメントには何も見つからなかったので、これに対する洞察は役に立ちます。

サンプル呼び出し

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

[〜#〜]編集[〜#〜]
今日私の同僚の何人かと話した後、私はビョルンリンドクヴィストと同じ答えを思いつきました。

振り返ってみると、なぜこれが頻繁に間違っているのか、私は間違いなく理解しています。 ORM Djangoやsqlalchemyなどを使用する利点の1つは、接続先のデータベースを(詳細に)理解または理解していなくてもコマンドを記述できることです。確かに私はこれらのユーザーの1人でした。ただし、これとは逆に、データベースを詳細に理解していないと、このようなデバッグエラーは非常に厄介で、壊滅的な可能性があります。

52
Adam Lewis

NO DEFAULT ORDERがあります。これは、誰もが間違っているため十分に強調できないポイントです。

データベース内のテーブルは通常のhtmlテーブルではなく、順序付けされていないタプルのセットです。その特定のデータベースでは、いくつかの高度な最適化手法を利用していないため、行の順序が予測可能であることが多いため、MySQLにしか慣れていないプログラマーを驚かせることがよくあります。たとえば、どの行が返されるか、または次のクエリのいずれかでそれらの順序を知ることはできません。

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

最後のクエリでは、列xのすべての値が一意である場合にのみ、順序を予測できます。 RDBMSは、selectステートメントの条件を満たす限り、任意の行を任意の順序で自由に返すことができます。

Djangoレベルでデフォルトの順序を追加することができますが、これにより、順序付けされていないすべてのクエリにorder by句が追加されます。

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

何らかの理由で順序付けられた行が必要ない場合は、パフォーマンスが低下する可能性があることに注意してください。

71