Хранение данных JSONB через экто - PullRequest
0 голосов
/ 28 апреля 2018

Я пытаюсь передать данные jsonb в postgres через ecto. Я хотел бы иметь возможность взять допустимую строку JSON, добавить ее в качестве аргумента graphql и увидеть этот json в моей таблице.

миграция

defmodule MyApp.CreateJsonTable do
  use Ecto.Migration

  def change do
    create table(:geodata) do
      add(:json, :map)

      timestamps(type: :utc_datetime)
    end
  end
end

Насколько я понимаю, вам нужно определить структуру для Poison для JSONB, а затем декодировать в нее при вставке.

defmodule Geodatajson do
  use MyApp, :model

  embedded_schema do
    field(:latitude, :float)
    field(:longitude, :float)
  end
end

сейчас модель:

defmodule MyApp.Geodata do
  use MyApp, :model

  alias MyApp.Repo
  alias MyApp.Geodata

  schema "geodata" do
    embeds_one(:json, Geodatajson)

    timestamps()
  end

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:json])
  end

  def add_geodata(str) do
    json = str |> Poison.decode!(as: Geodatajson)
    data = %Geodata{json: json}
    Repo.insert(data)
  end
end

Я пытаюсь передать данные следующим образом:

iex> MyApp.Geodata.add_geodata("{\"latitude\": 1.23, \"longitude\": 4.56}")

но JSONB не декодируется:

{:ok,
 %MyApp.Geodata{
   __meta__: #Ecto.Schema.Metadata<:loaded, "geodata">,
   id: 26,
   inserted_at: ~N[2018-04-28 13:28:42.346382],
   json: %Geodatajson{
     id: "3b22ef94-92eb-4c64-8174-9ce1cb88e8c5",
     latitude: nil,
     longitude: nil
   },
   updated_at: ~N[2018-04-28 13:28:42.346392]
 }}

Что я могу сделать, чтобы получить эти данные в postgres?

1 Ответ

0 голосов
/ 04 мая 2018

Poison as: требует, чтобы вы передавали экземпляр структуры, а не только имя модуля.

json = str |> Poison.decode!(as: Geodatajson)

должно быть:

json = str |> Poison.decode!(as: %Geodatajson{})
...