Рельсы, изменяющие тип данных первичного ключа / внешнего ключа

#ruby-on-rails #postgresql #foreign-keys #primary-key

Вопрос:

Мое приложение rails импортирует кучу ресурсов из стороннего сервиса, который является источником истины для приложения. API отвечает с помощью ресурса json и его идентификатора, например :

  {"_id"=>"604d3d6ed64d52b8bfe84b",
 "name"=>"Advanced Stock Trading Course   Strategies",
 "author"=>"davd@fullsts.com",
}
 

Мое приложение импортирует эти ресурсы и воспроизводит их в своих собственных таблицах в базе данных postgres. Что-то, что выглядит как :

   create_table "programs", force: :cascade do |t|
    t.jsonb "lms_data", default: "{}", null: false
    t.bigint "author_id"
    t.jsonb "default_lms_image", default: "{}", null: false
    t.index ["account_id"], name: "index_programs_on_account_id"
    t.index ["author_id"], name: "index_programs_on_author_id"
    t.index ["lms_data"], name: "index_programs_on_lms_data", using: :gin
  end
 

где lms_data хранит исходный json из стороннего API.

Первоначально я создал эту таблицу с классическим первичным ключом Bigint ID в режиме автоматического увеличения. Поскольку сторонняя служба-мой единственный источник правды. Я бы на самом деле хотел, чтобы их идентификатор стал моим первичным ключом «_id»=>»604d3d6ed64d52b8bfe84b», то есть строкой «604d3d6ed64d52b8bfe84b».

Однако у меня есть другие таблицы, которые уже ссылаются на program_id в качестве внешнего ключа, и, например, когда я пытаюсь запустить эту миграцию :

   def change
    change_column :sessions, :program_id, :string
    change_column :tickets, :program_id, :string
    change_column :programs, :id, :string
  end

  def down
    change_column :sessions, :program_id, :bigint
    change_column :tickets, :program_id, :bigint
    change_column :programs, :id, :bigint
  end
 

Я получаю эту ошибку :

 Caused by:
ActiveRecord::StatementInvalid: PG::DatatypeMismatch: ERROR:  foreign key constraint "fk_rails_35ef875d99" cannot be implemented
DETAIL:  Key columns "program_id" and "id" are of incompatible types: character varying and bigint.
 

Есть ли способ перенести мой основной и внешний ключи в этой ситуации ?

Комментарии:

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

2. В качестве альтернативы, сохраните свои собственные идентификаторы внутри, и пусть Rails сделает это, и сохраните удаленный идентификатор в uuid столбце или что-то в этом роде, и просто используйте его при вызове третьей стороны.