проблемы сортировкой результатов выборки

57 views
Skip to first unread message

Евгений Марьев

unread,
Mar 12, 2019, 4:30:46 AM3/12/19
to Django russian
Всем привет.
Столкнулся с таким багом:
Есть метод, который отдает следующий и предыдущий id записи.
works = Case.objects \
    .filter(active=active) \
    .order_by(sort)

if kwargs.get("language") is not None:
    works = works.filter(language__code=kwargs.get("language"))
works = list(works.values_list("id", flat=True))
Так вот проблема вот в чем, на локальной машине все запросы возвращают совершенно одинаковый ответ, допустим:
Works IDs: 50, 51, 53, 55, 118, 104, 108, 57, 59, 62, 63, 65, 67, 69, 71, 110, 82, 83, 85, 87, 90, 92, 94, 96, 73, 75, 77, 79, 112, 113, 114, 115,
116, 117, 98, 100, 102, 106, 111
Но на боевом серваке, тот же код, начинает чудить, и каждый раз меняет порядок элементов в списке.


Works IDs: 50, 51, 104, 108, 53, 55, 118, 65, 67, 69, 71, 110, 57, 59, 62, 63, 73, 75, 77, 79, 82, 83, 85, 87, 90, 92, 94, 96, 98, 100, 102, 106, 111, 112, 113, 114, 115, 116, 117


Works IDs: 50, 51, 53, 55, 118, 104, 108, 57, 59, 62, 63, 65, 67, 69, 71, 110, 85, 87, 90, 92, 94, 96, 73, 75, 77, 79, 82, 83, 114, 115, 116, 117, 98, 100, 102, 106, 111, 112, 113


Works IDs: 50, 51, 118, 104, 108, 53, 55, 59, 62, 63, 65, 67, 69, 71, 110, 57, 92, 94, 96, 73, 75, 77, 79, 82, 83, 85, 87, 90, 117, 98, 100, 102, 106, 111, 112, 113, 114, 115, 116


И я никак не пойму в чем может быть проблема.









Arcady Chumachenko

unread,
Mar 12, 2019, 4:37:42 AM3/12/19
to django-...@googlegroups.com
Sort откуда берется?


p
.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco; color: #f4f4f4; background-color: #000000; background-color: rgba(0, 0, 0, 0.85)}
span
.s1 {font-variant-ligatures: no-common-ligatures}









--
Вы получили это сообщение, поскольку подписаны на группу "Django russian".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес django-russia...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

Ivan Fedorov

unread,
Mar 12, 2019, 4:39:37 AM3/12/19
to django-...@googlegroups.com

Евгений Марьев

unread,
Mar 12, 2019, 4:42:10 AM3/12/19
to Django russian
Вот метод целиком:
def resolve_next_prev_work(self, info, **kwargs):
"""получение следующего и предыдущего id кейса"""
logger = logging.getLogger("schema")
work_id = kwargs.get("work_id")
active = kwargs.get("active", True)
sort = kwargs.get("sort", "desc")

if sort == "asc":
sort = "active_to"
else:
sort = "-active_to"

works = Case.objects \
.filter(active=active) \
.order_by(sort)

if kwargs.get("language") is not None:
works = works.filter(language__code=kwargs.get("language"))
    logger.debug("\n{}\n".format(works.query))

works = list(works.values_list("id", flat=True))
    logger.debug("Works IDs: {}\n".format(", ".join(str(work_id) for work_id in works)))

len_works = len(works) - 1
if len_works >= works.index(work_id) + 1:
next_id = works[works.index(work_id) + 1]
else:
next_id = works[0]
prev_id = works[works.index(work_id) - 1]
return NextPrevWork(next_id=next_id,
prev_id=prev_id,
next_code=Case.objects.get(pk=next_id).sef_url,
prev_code=Case.objects.get(pk=prev_id).sef_url,
next_title=Case.objects.get(pk=next_id).title,
prev_title=Case.objects.get(pk=prev_id).title)


вторник, 12 марта 2019 г., 12:37:42 UTC+4 пользователь Arcady Chumachenko написал:

Arcady Chumachenko

unread,
Mar 12, 2019, 4:44:32 AM3/12/19
to django-...@googlegroups.com
Убедитесь, что значение sort в обоих случаях одинаково и что в базе active_to не пустое.

Евгений Марьев

unread,
Mar 12, 2019, 5:01:20 AM3/12/19
to Django russian
sort точно во всех случаях одинаково, потому что запросы делаются с разницей меньше секунды, вручную.
Вот 3 запроса подряд:

SELECT `Case_case`.`id`, `Case_case`.`title`, `Case_case`.`active_from`, `Case_case`.`active_to`, `Case_case`.`active`, `Case_case`.`best`, `Case_case`.`content`, `Case_case`.`sef_url`, `Case_case`.`url`, `Case_case`.`logo`, `Case_case`.`logo_webp`, `Case_case`.`image`, `Case_case`.`image_preview`, `Case_case`.`image_webp`, `Case_case`.`image_preview_webp`, `Case_case`.`color`, `Case_case`.`created_at`, `Case_case`.`language_id`, `Case_case`.`is_pushed` FROM `Case_case` INNER JOIN `Language_language` ON (`Case_case`.`language_id` = `Language_language`.`id`) WHERE (`Case_case`.`active` = True AND `Language_language`.`code` = ru) ORDER BY `Case_case`.`active_to` ASC


Works IDs: 50, 51, 118, 104, 108, 53, 55, 59, 62, 63, 65, 67, 69, 71, 110, 57, 92, 94, 96, 73, 75, 77, 79, 82, 83, 85, 87, 90, 117, 98, 100, 102, 106, 111, 112, 113, 114, 115, 116



SELECT `Case_case`.`id`, `Case_case`.`title`, `Case_case`.`active_from`, `Case_case`.`active_to`, `Case_case`.`active`, `Case_case`.`best`, `Case_case`.`content`, `Case_case`.`sef_url`, `Case_case`.`url`, `Case_case`.`logo`, `Case_case`.`logo_webp`, `Case_case`.`image`, `Case_case`.`image_preview`, `Case_case`.`image_webp`, `Case_case`.`image_preview_webp`, `Case_case`.`color`, `Case_case`.`created_at`, `Case_case`.`language_id`, `Case_case`.`is_pushed` FROM `Case_case` INNER JOIN `Language_language` ON (`Case_case`.`language_id` = `Language_language`.`id`) WHERE (`Case_case`.`active` = True AND `Language_language`.`code` = ru) ORDER BY `Case_case`.`active_to` ASC


Works IDs: 50, 51, 104, 108, 53, 55, 118, 65, 67, 69, 71, 110, 57, 59, 62, 63, 73, 75, 77, 79, 82, 83, 85, 87, 90, 92, 94, 96, 98, 100, 102, 106, 111, 112, 113, 114, 115, 116, 117



SELECT `Case_case`.`id`, `Case_case`.`title`, `Case_case`.`active_from`, `Case_case`.`active_to`, `Case_case`.`active`, `Case_case`.`best`, `Case_case`.`content`, `Case_case`.`sef_url`, `Case_case`.`url`, `Case_case`.`logo`, `Case_case`.`logo_webp`, `Case_case`.`image`, `Case_case`.`image_preview`, `Case_case`.`image_webp`, `Case_case`.`image_preview_webp`, `Case_case`.`color`, `Case_case`.`created_at`, `Case_case`.`language_id`, `Case_case`.`is_pushed` FROM `Case_case` INNER JOIN `Language_language` ON (`Case_case`.`language_id` = `Language_language`.`id`) WHERE (`Case_case`.`active` = True AND `Language_language`.`code` = ru) ORDER BY `Case_case`.`active_to` ASC


Works IDs: 50, 51, 53, 55, 118, 104, 108, 57, 59, 62, 63, 65, 67, 69, 71, 110, 85, 87, 90, 92, 94, 96, 73, 75, 77, 79, 82, 83, 114, 115, 116, 117, 98, 100, 102, 106, 111, 112, 113


вторник, 12 марта 2019 г., 12:44:32 UTC+4 пользователь Arcady Chumachenko написал:

Евгений Марьев

unread,
Mar 12, 2019, 5:05:32 AM3/12/19
to Django russian
active_to во всех записях не пустой, везде дата стоит.

вторник, 12 марта 2019 г., 12:30:46 UTC+4 пользователь Евгений Марьев написал:

マギクアルセニ

unread,
Mar 12, 2019, 5:07:44 AM3/12/19
to django-...@googlegroups.com
Попробуйте вывести вместе ID вместе с датой.

Евгений Марьев

unread,
Mar 12, 2019, 5:13:51 AM3/12/19
to Django russian
SELECT `Case_case`.`id`, `Case_case`.`active_to` FROM `Case_case` INNER JOIN `Language_language` ON (`Case_case`.`language_id` = `Language_language`.`id`) WHERE (`Case_case`.`active` = True AND `Language_language`.`code` = 'ru') ORDER BY `Case_case`.`active_to` ASC
id active_to
50 2013-06-01
51 2014-06-01
53 2015-06-01
55 2015-06-01
118 2015-06-01
104 2015-06-01
108 2015-06-01
57 2016-06-01
59 2016-06-01
62 2016-06-01
63 2016-06-01
65 2016-06-01
67 2016-06-01
69 2016-06-01
71 2016-06-01
110 2016-06-01
85 2017-06-01
87 2017-06-01
90 2017-06-01
92 2017-06-01
94 2017-06-01
96 2017-06-01
73 2017-06-01
75 2017-06-01
77 2017-06-01
79 2017-06-01
82 2017-06-01
83 2017-06-01
114 2018-06-01
115 2018-06-01
116 2018-06-01
117 2018-06-01
98 2018-06-01
100 2018-06-01
102 2018-06-01
106 2018-06-01
111 2018-06-01
112 2018-06-01
113 2018-06-01
 Вот если делать запрос напрямую в базу, то все нормально выводит, проблема именно в коде, да еще и только на боевом серваке.

вторник, 12 марта 2019 г., 12:30:46 UTC+4 пользователь Евгений Марьев написал:
Всем привет.

Евгений Марьев

unread,
Mar 12, 2019, 5:16:33 AM3/12/19
to Django russian
works = list(works.values_list("id", flat=True))
Не может ли values_list менять порядок списка?

вторник, 12 марта 2019 г., 12:30:46 UTC+4 пользователь Евгений Марьев написал:
Всем привет.

Ivan Fedorov

unread,
Mar 12, 2019, 5:17:33 AM3/12/19
to django-...@googlegroups.com
Значит проблема в драйвера коннекшина

вт, 12 бер. 2019, 11:13 користувач Евгений Марьев <kadr...@gmail.com> пише:

Евгений Марьев

unread,
Mar 12, 2019, 5:24:58 AM3/12/19
to Django russian
я использую 
import pymysql
pymysql.install_as_MySQLdb()
И почему тогда на локальной машине нет проблем? 

вторник, 12 марта 2019 г., 12:30:46 UTC+4 пользователь Евгений Марьев написал:
Всем привет.

Олег Комков

unread,
Mar 12, 2019, 5:55:25 AM3/12/19
to django-...@googlegroups.com
Я может чего не понимаю? Вы делаете сортировку по active_to - вам и возвращается курсор сортированный по active_to. Порядок id вам никто не гарантировал. Если нужно добавьте id в условие сортировки.

вт, 12 мар. 2019 г. в 16:25, Евгений Марьев <kadr...@gmail.com>:

iddqd

unread,
Mar 12, 2019, 6:26:28 AM3/12/19
to Django russian
Вы все правильно понимаете, а вот топикстартер не понимает чего хочет

вторник, 12 марта 2019 г., 14:55:25 UTC+5 пользователь PooH написал:

Евгений Марьев

unread,
Mar 12, 2019, 7:09:30 AM3/12/19
to Django russian
И ведь правда, не подумал, что поля с одинаковой датой могут меняться местами. Добавил id в order_by(sort, "id"). Вроде проблема ушла.

вторник, 12 марта 2019 г., 13:55:25 UTC+4 пользователь PooH написал:

Евгений Марьев

unread,
Mar 12, 2019, 7:31:19 AM3/12/19
to Django russian
Всех благодарю.


вторник, 12 марта 2019 г., 12:30:46 UTC+4 пользователь Евгений Марьев написал:
Всем привет.

Za Ars

unread,
Mar 13, 2019, 5:34:36 AM3/13/19
to Django russian
У вас sort идет  по active_to, как я понял - дата. много записей с одной итой же датой. postgresql работает так, что если не указана явная сортировка, то он сортирует так как ему удобнее. В этом случае это происходит для объектов с одной и той же датой. Либо поменяйте дату на datetime либо добавьте еще один параметр сортировки, например id

sort = ['-active_to', 'id']
...
... .order_by(*sort)

вторник, 12 марта 2019 г., 11:30:46 UTC+3 пользователь Евгений Марьев написал:

Za Ars

unread,
Mar 13, 2019, 5:35:15 AM3/13/19
to Django russian
ой, я слоупок, сорян, не увидел что ответили


вторник, 12 марта 2019 г., 11:30:46 UTC+3 пользователь Евгений Марьев написал:
Всем привет.

マギクアルセニ

unread,
Mar 13, 2019, 5:41:35 AM3/13/19
to django-...@googlegroups.com
Всё равно ваш ответ имел смысл, потому что вы подробнее объяснили, почему так происходит. :)

Иван Земцов

unread,
Mar 14, 2019, 3:13:37 AM3/14/19
to google groups
так у вас много повторяющихся дат, 2018-06-01. поэтому в рамках этих дат выборка записей не может быть упорядочена 

--
Вы получили это сообщение, поскольку подписаны на группу "Django russian".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес django-russia...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.


--
С уважением, Иван
Reply all
Reply to author
Forward
0 new messages