Как я могу использовать сортировку ICU как мой по умолчанию в Rails? - PullRequest
0 голосов
/ 25 марта 2020

Я занимаюсь разработкой приложения Rails / Postgres. Я развиваю на Ма c. Другие используют Linux. Производство на Heroku.

На Ma c сломаны сопоставления, поэтому сортировка немного отличается от Linux и Heroku. Это приводит к тому, что тесты, включающие сортировку, иногда терпят неудачу или действуют непоследовательно. Обходной путь заключается в использовании сортировки ICU для получения последовательной сортировки, но я не могу понять, как сделать это по умолчанию.

Postgres не создаст базу данных с сортировкой ICU . Если я установлю для сортировки значение en-US-x-icu в database.yml ...

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: <%= ENV['DB_HOST'] || 'localhost' %>
  username: <%= ENV['DB_USER'] || 'postgres' %>
  password: <%= ENV['DB_PASSWORD'] || '' %>
  collation: en-US-x-icu

, я получу ошибку invalid locale name: "en-US-x-icu", несмотря на то, что в pg_collation.

$ rails db:migrate:reset
Dropped database 'email_integrator_development'
Dropped database 'email_integrator_test'
PG::WrongObjectType: ERROR:  invalid locale name: "en-US-x-icu"
Couldn't create 'email_integrator_development' database. Please check your configuration.
rails aborted!
ActiveRecord::StatementInvalid: PG::WrongObjectType: ERROR:  invalid locale name: "en-US-x-icu"

Возможно, есть способ заставить Rails установить коллапс для соединения или таблицы?

Я использую Rails 6 и Postgres 11, но я могу перейти к Postgres 12, если необходимо.

1 Ответ

1 голос
/ 27 марта 2020

Боюсь, что вам придется добавлять параметры сортировки в каждое определение столбца строки.

В настоящее время нельзя использовать параметры сортировки ICU в качестве базы данных по умолчанию. Предпринимались попытки улучшить это , но пока еще ничего не получилось.

Но потом легко исправить вашу базу данных. Используя psql, вы можете запустить

SELECT format(
          'ALTER TABLE %I.%I ALTER %I TYPE %I%s;',
          table_schema,
          table_name,
          column_name,
          data_type,
          '(' || character_maximum_length || ')'
       )
FROM information_schema.columns
WHERE data_type IN ('character', 'character varying', 'text')
  AND table_schema NOT IN ('pg_catalog', 'information_schema', 'pg_toast') \gexec
...