bigint против целочисленной ошибки в Ecto с базой данных Legacy - PullRequest
1 голос
/ 07 февраля 2020

Я нахожусь в следующей ситуации: существует устаревшая база данных PostgreSQL из приложения Rails, с которой мне нужно взаимодействовать.

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

Теперь я начал играть с некоторыми предварительными запросами, и у меня возникают некоторые проблемы, которые я не получаю. т как решить. Например:

from(is in acc, or_where: ^current_user.id in [is.transcriber_id, is.radiologist_id, is.validator_id])

возвращает следующую ошибку

** (Postgrex.Error) ERROR 42P08 (ambiguous_parameter): inconsistent types deduced for parameter $2

bigint versus integer
    (ecto) lib/ecto/adapters/sql.ex:431: Ecto.Adapters.SQL.execute_and_cache/7
    (ecto) lib/ecto/repo/queryable.ex:133: Ecto.Repo.Queryable.execute/5
    (ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4

После некоторых исследований я обнаружил, что ActiveRecord в Rails хранит целые числа как bigints, но я Я не уверен, что Postgrex или Ecto (я действительно не знаю, кто за это отвечает) правильно интерпретирует целое число current_user.id, которое я использую в запросе.

У меня такое ощущение, что выражение in [is.transcriber_id, is.radiologist_id, is.validator_id] немного жадный и, возможно, мне следует go с фрагментами.

ОБНОВЛЕНИЕ :

is расшифровывается как ImagingStudy. Миграция Rails этой модели выглядит следующим образом:

class CreateImagingStudies < ActiveRecord::Migration[5.2]
  def change
    create_table :imaging_studies do |t|
      t.string :status_name
      t.bigint :validator_id
      t.bigint :radiologist_id
      t.bigint :transcriber_id

      t.timestamps
    end
  end
end

Схема Phoenix для манипулирования таблицей, соответствующей imaging_studies, выглядит следующим образом

defmodule Worklist.Studies.ImagingStudy do
  use Ecto.Schema

  schema "imaging_studies" do
    field :transcriber_id, :integer
    field :radiologist_id, :integer
    field :validator_id, :integer

    timestamps(inserted_at: :created_at, updated_at: :updated_at)
  end

Там нет схемы для пользователей, так как они управляются в другом сервисе. Рассмотрим current_user карту с целочисленным полем с именем id.

1 Ответ

2 голосов
/ 07 февраля 2020

Ecto добровольно явно отображает :integer тип в Postgres ':bigint.

Тем не менее, используя Ecto.Query.API.type/2 можно явно привести параметр к :bigint, чтобы помочь с правильным отображением типа:

from(
  is in acc,
  or_where:
    type(^current_user.id, :integer) in [
      is.transcriber_id, is.radiologist_id, is.validator_id
    ]
)
...