sasafister's avatar

How to get rid of Sqlite default in migration

As you know, when you use Sqlite you have to specify default value in your migrations, otherwise, error is thrown.

Anyone knows how to avoid that?

I'm using now MySql as test DB, but it's little bit to slow.

0 likes
3 replies
rodrigo.pedra's avatar

Can you share a migration where this happens? I never had such problem nor heard of it

sasafister's avatar

This is error when I run tests

Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 Cannot add a NOT NULL column with default value NULL (SQL: alter table "clubs" add column "slug" varchar not null)

This is migration

 public function up()
    {
        Schema::table('clubs', function (Blueprint $table) {
            $table->string('slug')->after('name');
        });
    }

so if i put default value then it works fine

$table->string('slug')->after('name')->default(';);

I'm using this setup for PHPUNIT

 <server name="DB_CONNECTION" value="sqlite"/>
 <server name="DB_DATABASE" value=":memory:"/>
rodrigo.pedra's avatar

I see, as most of the apps I work have to run on both MS-SQLServer and MySQL, I never add a not null column without a default value or without filling its values. Sorry for assuming it wasn't a problem.

Searching a bit, it seems MySQL defines implicit defaults when it needs to fill a not null column without a user specified value (not only in ALTER, but in INSERT too):

https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html#data-types-defaults-implicit

As this is a custom MySQL behavior I guess you are out of luck on making SQLite behave like MySQL.

If it helps anyhow, when I need to add a not null column and don't want it to have a default constraint I generally:

  1. Add as nullable
  2. Fill the values
  3. Change to not null

Example:

Schema::create('sample', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
});

// add nullable
Schema::table('sample', function (Blueprint $table) {
    $table->string('email')->nullable()->after('name');
});

// update values - dummy example here
DB::statement("UPDATE sample SET email = '[email protected]'");

// make not null
Schema::table('sample', function (Blueprint $table) {
    // requires doctrine/dbal
    $table->string('email')->nullable(false)->change();
});

If defining the defaults or circumventing the not null defaults using the snippet above seems too much of a hassle, you can try extending SQLite Grammar (in Laravel) and adding default constraint automatically.

Please or to participate in this conversation.