Ecto insert with string keys only

Hi, right now when I insert a JSON object into the db using ecto.insert() The primary keys are all atom. However when a value of a key is a map the keys of the map are all string. These things are causing inconsistencies and thus I want to store any kind of key as string. Any way to do that?

Can you provide an example?

How do you put and retrieve to/from database?
How does your schema look like?

@primary_key {:id, :binary_id, autogenerate: true}
  @derive {Phoenix.Param, key: :id}
  schema "dealers" do
    field :latitude, :float
    field :longitude, :float
    field :name, :map

  def create_dealer(attrs \\ %{}) do
    %Dealer{id: Ecto.UUID.generate()}
    |> Dealer.changeset(attrs)
    |> Repo.insert()

def get_dealer!(id), do: Repo.get!(Dealer, id)

  __meta__: #Ecto.Schema.Metadata<:loaded, "dealers">,
  id: "08b8fbdd-5976-4da2-a1ce-715c07135c76",
  inserted_at: ~N[2017-12-01 14:35:26.646483],
  latitude: 51.53448,
  longitude: -0.11778,
  name: %{"en" => "Example dealer"},
  updated_at: ~N[2017-12-01 14:35:26.646493],

An embedded schema would allow you to have maps with atom keys, but there might be a lot of values with nil if not every field is supposed to have the same keys.

Another option is to create a custom type that converts the string keys back into atoms.

I actually want the quite opposite. Inserting to the db with string keys only. But I guess it’s not possible with Ecto

If your database supports JSON fields, it does store keys as strings, since this is the only keytype supported by JSON.

If though you want to have the keys of your scheme struct to be keys, then no you can’t do that at all with elixir. Structs do have atom keys and they have a fixed number of those.

Ok, thanks a lot for the help. Have a good day :slight_smile: