Каков порядок по умолчанию для списка, возвращаемого вызовом фильтра Django? - PullRequest
43 голосов
/ 23 августа 2011

Короткий вопрос
Каков порядок по умолчанию для списка, возвращаемого вызовом фильтра Django при подключении к базе данных PostgreSQL?

Фон
По моему собственному признанию, я сделал неверное предположение на прикладном уровне в том, что порядок, в котором возвращается список, будет постоянным, то есть без использования order_by. Список пунктов, которые я запрашивал, не в алфавитном порядке или в любом другом преднамеренном порядке. Предполагалось, что он останется в том же порядке, в каком они были добавлены в базу данных.

Это предположение подтвердилось для сотен запросов, но мое приложение сообщило об ошибке, когда заказ изменился по незнанию. Насколько мне известно, ни одна из этих записей не была затронута за это время, так как я единственный человек, который ведет БД. Чтобы добавить путаницу, при запуске приложения Django в Mac OS X оно все еще работало, как и ожидалось, но в Win XP оно изменило порядок. (Обратите внимание, что упомянутые сотни запросов были на Win XP).

Любое понимание этого было бы полезно, так как я не смог найти ничего в документации Django или PostgreSQL, объясняющей различия в операционных системах.

Пример вызова

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

EDIT
После сегодняшней беседы с одним из моих коллег я получил тот же ответ, что и Бьерн Линдквист.

Оглядываясь назад, я определенно понимаю, почему это часто делается неправильно. Одним из преимуществ использования ORM Django, sqlalchemy или чего-либо еще является то, что вы можете писать команды без необходимости знать или понимать (подробно) базу данных, к которой она подключена. По общему признанию, я был одним из этих пользователей. Однако, с другой стороны, это то, что, не зная базы данных в деталях, ошибки отладки, подобные этой, являются довольно хлопотными и потенциально катастрофическими.

Ответы [ 2 ]

69 голосов
/ 23 августа 2011

Существует НЕТ ЗАКАЗА ПО УМОЛЧАНИЮ , точка, которую нельзя подчеркнуть достаточно, потому что все делают это неправильно.

Таблица в базе данных - это не обычная HTML-таблица, это неупорядоченный набор кортежей.Это часто удивляет программистов, привыкших только к MySQL, потому что в этой конкретной базе данных порядок строк часто предсказуем, поскольку он не использует некоторые передовые методы оптимизации.Например, невозможно узнать, какие строки будут возвращены, или их порядок в любом из следующих запросов:

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

В последнем запросе порядок является предсказуемым, только если все значения в столбце xуникальны.СУБД может свободно возвращать любые строки в любом порядке, в котором она пожелает, при условии, что она удовлетворяет условиям оператора select.

Хотя вы можете добавить порядок по умолчанию на уровне Django, что приведет к добавлению порядкапредложением by для каждого неупорядоченного запроса:

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

Обратите внимание, что это может быть перетаскивание производительности, если по какой-то причине вам не нужны упорядоченные строки.

0 голосов
/ 18 февраля 2016

Если вы хотите, чтобы они были возвращены в том порядке, в котором они были вставлены:

Добавьте в вашу модель следующее:

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
...