0
votes

I'm trying to rename the primary key from :id to :account_id.

I've got the following Schema and migration. When I try to insert a record, I get a 'cannot be null' error from Postgres on the account_id column.

Did I set up the autogenerate bit right? I feel like that should be in the migration.

  def change do
    create table(:accounts) do
      add :account_id, :integer, primary_key: true
      add :email, :string
      timestamps()
    end
  end


  @primary_key {:account_id, :id, autogenerate: true}
  schema "accounts" do
    field :email, :string
    timestamps()
  end
2

2 Answers

3
votes

This isn't obvious from the docs or other guides. The trick is to the :bigserial type for the :id field.

  def change do
    create table(:accounts, primary_key: false) do
      add :account_id, :bigserial, primary_key: true
      add :email, :string
      timestamps()
    end
  end
2
votes

You should pass primary_key: false option:

  def change do
    create table(:accounts, primary_key: false) do
      add :account_id, :integer, primary_key: true
      add :email, :string
      timestamps()
    end
  end

[Edit]

As the questioner himself wrote in his answer, we can use :bigserial instead of :integer here.

The :bigserial takes 8 bytes and the :integer takes 4 bytes.

From Ecto 2.0 (released 2016) the default type of primary keys is :bigserial, but we can safely use :integer for ordinary purpose as it is still very big (1 to 2,147,483,647).