Rails jsonb - предотвращает изменение порядка ключей JSON при сохранении jsonb в базу данных Postgresql - PullRequest
0 голосов
/ 01 сентября 2018

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

Как запретить Rails / Postgres jsonb автоматически сортировать ключи JSON при сохранении в базу данных? (для создания или обновления)

Похоже, пытается отсортировать по алфавиту, но плохо справляется с этим.

Вот что я экономлю:

{
    "str_fee": 3.17,       # key 1
    "eva_fee": 14.37,      # key 2
    "fran_royalty": 14.37, # key 3
    "fran_amount": 67.09   # key 4
}

Вот как это на самом деле экономит:

{
    "eva_fee": 14.37,     # key 2
    "str_fee": 3.17,      # key 1
    "fran_amount": 67.09, # key 4
    "fran_royalty": 14.37 # key 3
}

Назначение:

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

Мне нужно, чтобы ключи сортировались так, как они мне нужны, потому что клиентский интерфейс, который использует этот JSON, отображает JSON для разработчиков, которым необходимо, чтобы ключи были в порядке, указанном в документации их в. И причина, по которой он должен быть в таком порядке, состоит в том, чтобы отобразить процесс вычислений, в каком порядке сначала:

Правильный порядок говорит разработчику:

Сначала был применен str_fee, затем eva_fee, затем fran_royalty ..., делающий fran_amount конечной суммой.

Но, исходя из того, как jsonb сортирует это, он неверно говорит нашим разработчикам, что:

Сначала был применен eva_fee, затем str_fee, затем fran_amount ..., делающий fran_royalty конечной суммой.

Ответы [ 3 ]

0 голосов
/ 17 сентября 2018

На самом деле они сортируются не по алфавиту, а по длине ключа, а не по алфавиту, что объясняет порядок, который вы получаете. Тип jsonb был создан как лучшая версия типа json для записи и доступа к данным, и, вероятно, для целей индексации и поиска они меняют порядок ключей. Если вы хотите, чтобы порядок ключей не менялся, вы можете использовать тип json, который не меняет порядок ключей при хранении данных в базе данных.

Надеюсь, это поможет.

0 голосов
/ 01 июля 2019

Документы Postgres предлагают использовать тип json для сохранения порядка ключей объектов:

Как правило, большинство приложений предпочитают хранить данные JSON как JSONB, если нет особых потребностей, таких как наследие предположения о порядке расположения ключей объекта.

0 голосов
/ 01 сентября 2018

Я не могу найти ничего о том, как изменить jsonb поведение сохранения / обновления, но вы можете контролировать, как вы возвращаете as_json из вашей модели Rails.

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

ПРИМЕЧАНИЕ: это будет работать только в том случае, если вы заранее знаете имена своих ключей ... если имена ключей создаются динамически, прежде чем вы их знаете, вам нужно попробовать что-то другое ... скорее всего сохраните ваш JSON как строку, а не как хеш.

class Transaction < ApplicationRecord
  store_accessor :amount_splits, :str_fee, :eva_fee, :fran_royalty, :fran_amount

  [...]

  def as_json(options={})
    # simple JSON response:
    json = {
      [...]
      "amount_splits"   => {
        "str_fee"       => self.str_fee,
        "eva_fee"       => self.eva_fee,
        "fran_royalty"  => self.fran_royalty,
        "fran_amount"   => self.fran_amount
      },
      [...]
    }
    return json
  end

  [...]

end

ПРИМЕЧАНИЕ: Я значительно сократил свой пользовательский метод as_json, оставив только ту часть JSON, которая будет возвращена

...