spencer.christensen
Ecto Migration: `not_null_violation` when modifying column null->non-null & adding default value
Howdy y’all,
I’m brand new to Elixir and have what is likely a simple problem. I created an Ecto schema with a votes column that is type :integer and nullable. I later realized it should be non-nullable and default to 0. I made a migration to perform this update, however I am getting the error:
** (Postgrex.Error) ERROR 23502 (not_null_violation) column "votes" of relation "faqs" contains null values
Migration
defmodule Pento.Repo.Migrations.AlterFaqsAddDefaultVoteValue do
use Ecto.Migration
def change do
alter table(:faqs) do
modify :votes, :integer, default: 0, null: false
end
end
end
See below for my existing table and full error output. I found a comment from Jose Valim stating “The default value in migration is used to set the value for existing rows.” in 2015. I read that as stating that the default value in a migration should change any existing null fields to the stipulated value. Is that not the case and should I just use a separate execute for altering existing rows?
Existing Table
| id | question | answer | votes | inserted_at | updated_at |
|---|---|---|---|---|---|
| 1 | Question 1 | Answer 1 | NULL | 2024-02-04 02:54:39 | 2024-02-04 12:51:01 |
| 2 | Question 2 | Answer 2 | NULL | 2024-02-04 02:56:24 | 2024-02-04 02:56:24 |
CREATE TABLE "public"."faqs" (
"id" int8 NOT NULL DEFAULT nextval('faqs_id_seq'::regclass),
"question" varchar(255),
"answer" varchar(255),
"votes" int4,
"inserted_at" timestamp(0) NOT NULL,
"updated_at" timestamp(0) NOT NULL,
PRIMARY KEY ("id")
);
Output
07:05:36.729 [info] == Running 20240204125254 Pento.Repo.Migrations.AlterFaqsAddDefaultVoteValue.change/0 forward
07:05:36.730 [info] alter table faqs
** (Postgrex.Error) ERROR 23502 (not_null_violation) column "votes" of relation "faqs" contains null values
table: faqs
column: votes
(ecto_sql 3.11.1) lib/ecto/adapters/sql.ex:1054: Ecto.Adapters.SQL.raise_sql_call_error/1
(elixir 1.16.0) lib/enum.ex:1700: Enum."-map/2-lists^map/1-1-"/2
(ecto_sql 3.11.1) lib/ecto/adapters/sql.ex:1161: Ecto.Adapters.SQL.execute_ddl/4
(ecto_sql 3.11.1) lib/ecto/migration/runner.ex:348: Ecto.Migration.Runner.log_and_execute_ddl/3
(elixir 1.16.0) lib/enum.ex:1700: Enum."-map/2-lists^map/1-1-"/2
(ecto_sql 3.11.1) lib/ecto/migration/runner.ex:311: Ecto.Migration.Runner.perform_operation/3
(stdlib 5.2) timer.erl:270: :timer.tc/2
(ecto_sql 3.11.1) lib/ecto/migration/runner.ex:25: Ecto.Migration.Runner.run/8
Thank you for any help!
Trending in Questions
Hello!
Suppose you are building workflow (order / task / payment) processing system with the following requirements:
Each workflow con...
New
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
Using Phoenix.LiveView.TagEngine as an EEx.Engine is deprecated!
To compile HEEx, use Phoenix.LiveView.TagEngine.compile/2 instead.
Sta...
New
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app?
Looking for hints regarding:
Addi...
New
Hi all, I wanted to ask how the community is dealing with post-release steps.
Today we have Ecto migrations, which make sure that the db...
New
I am using Oban and occasionally, shortly after a deployment, a handful of jobs can fail because of dependency on other parts of the syst...
New
Other Trending Topics
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #hex
- #performance










First 5 of 5 Posts
dimitarvp
Either make one migration that only introduces the default (without the non-null constraint) or just make a data migration that fills up all null column values with the default value.
I am not sure the former would work at all so I’d go for the latter i.e. something like this:
After this one above, make the one that introduces the non-null constraint.
al2o3cr
You may need to split this into two migrations, since the
alterimplementation will always change theNOT NULLconstraint before theDEFAULT:I’d guess this was more relevant in older PGs when setting a default on a nullable column was an expensive “rewrite every row that has a
NULL” operation.spencer.christensen
Thank you for pointing me to that file! I’m no expert in Postgres, but it looks like this is in fact a limitation in PG as running both:
ALTER TABLE faqs ALTER COLUMN votes SET NOT NULL, ALTER COLUMN votes SET DEFAULT 0(the unquoted ordering fromconnection.ex)and
ALTER TABLE faqs ALTER COLUMN votes SET DEFAULT 0, ALTER COLUMN votes SET NOT NULLresults in the same error:
ERROR: column "votes" of relation "faqs" contains null valuesChanging the order of the statements has no effect.
Thus it looks like this is indeed a multi-step migration: fill existing rows and then set the default and not null:
dimitarvp
Will you not lose information this way? What about rows that have, say, faqs = 10?
spencer.christensen