Laravel migration with SQLite 'Cannot add a NOT NULL column with default value NULL' Laravel migration with SQLite 'Cannot add a NOT NULL column with default value NULL' sqlite sqlite

Laravel migration with SQLite 'Cannot add a NOT NULL column with default value NULL'


It looks like this is a SQLite oddity. According to a Laracast forum thread about the same issue:

When adding a table from scratch, you can specify NOT NULL. However, you can't do this when adding a column. SQLite's specification says you have to have a default for this, which is a poor choice.

Looking further to the SQLite ALTER TABLE docs, I found:

If a NOT NULL constraint is specified, then the column must have a default value other than NULL.

I suppose in the world of SQLite, not providing a default value is the same thing as saying the default value should be NULL (as opposed to meaning there is no default value for this non-nullable column, so a value must be provided for it on each insert).

It seems SQLite simply leaves you in a bad state if you need to add a non-nullable column to an existing table, which column should also not have a default value.


A workaround I've used successfully is to check which database driver is being used and slightly modify the migration for SQLite.

For example:

class MyMigration extends Migration{    public function up()    {        $driver = Schema::connection($this->getConnection())->getConnection()->getDriverName();        Schema::table('invoices', function (Blueprint $table) use ($driver) {            $table->string('stripe_invoice')->nullable()->change();            if ('sqlite' === $driver) {                $table->string('stripe_invoice_number')->default('');            } else {                $table->string('stripe_invoice_number')->after('stripe_invoice');            }        });    }}


If you don't want the column to be nullable - then you need to let Laravel know what the default should be.

One option is an empty string "" like this

public function up() {    Schema::create('users', function($table) {      $table->date('birthday')->after('id')->default('');      $table->string('last_name')->after('id')->default('');      $table->string('first_name')->after('id')->default('');    });  }