When I add a column to an existing table, I’d like to set a default value for the rows already in the table, but I don’t want there to be a default value for any newly added rows. I also want it to be a not-null column.
The problem is that if I don’t set a default, the not null constraint gets violated and the migration fails. What I’m looking for is a simple way to specify a default for existing rows, while still causing any future inserts to fail if a value is not specified for that column.
This feels like a relatively common situation, and it would be nice not to have to break things out and write up() and down() functions and instead just use a change() and specify a “default for existing rows”.
An explicit mechanism to either specify a value or call a function to fill in data prior to proceeding with setting the column not null would seem like a natural way to solve this. I haven’t found any indication this exists, but the situation I am running into seems like it would be a fairly common problem.
Here’s an example of an approach I sometimes use. It feels like way too much code for what I’m wanting to achieve.
defmodule Rtphx.Repo.Migrations.ExampleAddColumn do
use Ecto.Migration
def up do
alter table(:example) do
add :newcolumn, :string, default: "defaultvalue", null: false
end
alter table(:example) do
modify :newcolumn, :string, default: nil, null: false
end
end
def down do
alter table(:example) do
remove :newcolumn, :string, null: false
end
end
end