UUID is not being generated when used as primary key

Hey all! Im having an issue what something that should be simple (?)

I have this migration

defmodule MyApp.Repo.Migrations.CreateEvents do
  use Ecto.Migration

  def change do
    create table(:events, primary_key: false) do
      add :id, :uuid, primary_key: true
      add :name, :string, null: false
      add :source, :string, null: false
      add :data, :map, default: "{}"

      timestamps()
    end
  end
end

My model look like

defmodule MyApp.Event do
  use Ecto.Schema
  import Ecto.Changeset

  @primary_key {:id, :binary_id, autogenerate: true}
  @derive {Phoenix.Param, key: :id}

  schema "events" do
    field :name, :string
    field :source, :string
    field :data, :map

    timestamps()
  end

  @doc false
  def changeset(event, attrs) do
    event
    |> cast(attrs, [:name, :source, :data])
    |> validate_required([:name, :source])
  end
end

And when I try to insert an event, it doesn’t generate the ID

Repo.insert! event
[debug] QUERY ERROR db=7.0ms queue=1.9ms
INSERT INTO "events" ("data","name","source","inserted_at","updated_at") VALUES ($1,$2,$3,$4,$5) RETURNING "id" [%{"email" => "testing@testing.com"}, "Something happened", "test", ~N[2019-05-07 17:14:22], ~N[2019-05-07 17:14:22]]
** (Postgrex.Error) ERROR 23502 (not_null_violation) null value in column "id" violates not-null constraint

    table: events
    column: id

Failing row contains (null, Something happened, test, {"email": "testing@testing.com"}, 2019-05-07 17:14:22, 2019-05-07 17:14:22).
    (ecto_sql) lib/ecto/adapters/sql.ex:605: Ecto.Adapters.SQL.raise_sql_call_error/1
    (ecto) lib/ecto/repo/schema.ex:649: Ecto.Repo.Schema.apply/4
    (ecto) lib/ecto/repo/schema.ex:262: anonymous fn/15 in Ecto.Repo.Schema.do_insert/4
    (ecto) lib/ecto/repo/schema.ex:164: Ecto.Repo.Schema.insert!/4

Ive tried using different combinations of autogenerate: false/true, :binnary_id/Ecto.UUID but same result.

Im using:

ecto: 3.1.3
elixir: 1.8.1
phoenix: 1.4.4
postgrex: 0.14.2

Any clue? :confused:

Hmm, and you are using Repo.insert! and not something like Repo.insert_all?

@OvermindDL1 that’s just an example, but it doesn’t work no matter the way to use to insert the record. It is not generating the ID.

Hmm, might need a full reproducible example then (preferably something to just copy/paste into IEx with Ecto loaded into it and set up with a Repo), as I use UUID’s just as the above with no issues with auto-generation.

1 Like

I just recreated the whole app again and it’s working :man_facepalming:

Model:

  @primary_key {:id, :binary_id, autogenerate: true}
  @derive {Phoenix.Param, key: :id}
  schema "events" do
    field :data, :map
    field :name, :string
    field :source, :string

    timestamps()
  end

Migration

  def change do
    create table(:events, primary_key: false) do
      add :id, :uuid, primary_key: true
      add :name, :string, null: false
      add :source, :string, null: false
      add :data, :map, default: "{}"

      timestamps()
    end
  end

Not sure what I did wrong previously :confused:

1 Like

If you keep the old app’s directory, run this and you will find out:

diff -u -r old_dir new_dir
5 Likes