Postgresql сортирует хэш после его спасения

Когда я сохраняю хеш-таблицу, я хочу иметь определенный порядок (как в записи). Но Postgres сортирует это по-своему. Как мне указать сортировку для записи?

Пример:

INSERT INTO "items" ("nested_params") VALUES ($1)  [["nested_params", "\"Turbo\"=>\"Some variable\",\"TV\"=>\"Some variable\",\"FM\"=>\"Some variable\"];
SELECT  "items".* FROM "items"  WHERE "items"."id" = $2 LIMIT 1 ["id", 5]];

Выход (рубиновый хеш):

{"FM"=>"Some variable", "TV"=>"Some variable", "Turbo"=>"Some variable"}

В записи Turbo - 1-й ключ.

PS Я использую неанглийские ключи в хэше. Но они сортируются не по буквам в кодировке UTF-8, а случайным образом

1 ответ

Решение

Ни hstore, ни JSON изначально не упорядочены. Из прекрасного руководства hstore:

Порядок пар не имеет значения (и не может быть воспроизведен на выходе).

и из тонкой спецификации JSON:

Объект - это неупорядоченный набор пар имя / значение.

Таким образом, никому не гарантируется забота о порядке, и база данных может свободно переставлять их так, как считает нужным. То, что версия JSON поддерживает порядок, не означает, что это произойдет в следующий раз или будет после обновления, поэтому не зависит от этого неуказанного поведения.

Если вы заботитесь о порядке в вашем хэше, вам придется сделать это самостоятельно в Ruby. Простой способ сделать это - переопределить стандартный метод доступа ActiveRecord:

def nested_params
  super.sort_by(&:first).to_h
end

Если ваша версия Ruby не имеет Array#to_h тогда вы можете сказать:

def nested_params
  Hash[super.sort_by(&:first)]
end

Вы можете использовать hstore или же json типы столбцов с этими переопределениями. Если вы хотите, чтобы сортировка не учитывала регистр, вам придется соответствующим образом настроить сортировку.

Другие вопросы по тегам