Framework: Laravel 5.4 failing on php artisan migrate

Created on 3 Mar 2017  路  8Comments  路  Source: laravel/framework

  • Laravel Version: 5.4.15
  • PHP Version: 7
    Database Driver & Version: MySQL 5.6

As in the issues #17714 #17508
That error is very annoying :angry: each time you make migration in each new project. laravel should have it own default max length for example (191 as default).

// AppServiceProvider.php
use Illuminate\Support\Facades\Schema;

function boot()
{
    Schema::defaultStringLength(191);
}

Or you may add it to database configuration as configable setting in config/database.php file
Or it can be added in the user migration (I think this is the best solution without effecting other tables)

Schema::defaultStringLength(191); 
Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('email')->unique();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});

It should be added in the laravel framework by default.

Most helpful comment

Why are we telling people to use defaultStringLength() without also mentioning that they can configure their mysql to work with their migrations?

  1. Set innodb_file_format=Barracuda in my.cnf
  2. Set innodb_large_prefix=1 in my.cnf
  3. Either set $table->engine = 'innodb row_format=dynamic'; in the migration, or set innodb_default_row_format=dynamic in my.cnf if you're running mysql 5.7.9 or later.

All 8 comments

Laravel's default string length is 255. You'll find it set in Illuminate\Database\Schema\Builder under Builder::$defaultStringLength.

Using Schema::defaultStringLength(191); provides backwards compatibility for applications using MySQL older than 5.7.7.

Why are we telling people to use defaultStringLength() without also mentioning that they can configure their mysql to work with their migrations?

  1. Set innodb_file_format=Barracuda in my.cnf
  2. Set innodb_large_prefix=1 in my.cnf
  3. Either set $table->engine = 'innodb row_format=dynamic'; in the migration, or set innodb_default_row_format=dynamic in my.cnf if you're running mysql 5.7.9 or later.

I know defaultStringLength does exists in laravel dahh
As you know the cause of the error is the email and token fields length in the create users table and password reset table.

// That will solve the problem but you have to use 191 as default length only (not good solution)
// I think 191 is not enough
// create_users_table.php
Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('email', 191)->unique();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});
// create_password_resets_table.php
Schema::create('password_resets', function (Blueprint $table) {
    $table->string('email', 191)->index();
    $table->string('token', 191)->index();
    $table->timestamp('created_at')->nullable();
});

Thanks @sisve :+1: . That did work great (the best solution)
You saved my life

# my.ini or my.cnf
innodb_file_format = Barracuda
innodb_large_prefix = 1
# only work in mysql 5.7.9 or later
innodb_default_row_format = dynamic
// you need to add this to the migration if your mysql before v 5.7.9
$table->engine = 'innodb row_format=dynamic';
// a better way is to add it to Laravel config/database.php ( So you don't add that line in any migration):
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',

@sisve your guess is as good as mine. It's my preferred option.

The docs do state that you can use innodb_large_prefix but refer you to the documentation of your chosen database. I would assume because it's a short sentence below a code block, it gets overlooked by a readers. https://laravel.com/docs/5.4/migrations#indexes

If you don't need emojis you can always set the encoding to utf8 here. That's at least how I handle these errors.

EDIT: Be careful though. When using utf8 encoding instead of utf8mb4 you will not have access to other Unicode characters as @sisve described below in more detail.

@KKSzymanowski Please, mention that you're throwing away support for many more characters than emoticons. Tell people what collations are, and how your suggestion is limiting them, and not a simplistic "That's at least how I handle these errors." Tell them which scripts you have tested your solution with so they can evaluate if your suggestion works for them.

The utf8mb4 collation is _required_ for unicode support. The utf8 collation can only encode the basic plane, while utf8mb4 can encode all supplementary planes too. If you simplify that as "if you don't need emojis" you're way off base here. You are not only throwing away support for emojis, but entire scripts you havn't tested when making that claim.

A list of blocks (used for script) that are present in the current SMP can be found at https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane

@sisve You are of course correct. It was an oversimplification on my part caused by Docs' argumentation behind the encoding choice and being used to utf8 being sufficient in my day-to-day work.

I apologize if I mislead anyone, I have suplemented my comment.

Thanks everyone for the help, I'm closing this issue since the documentation is clear about that backward compatibility issue with MySQL.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iivanov2 picture iivanov2  路  3Comments

shopblocks picture shopblocks  路  3Comments

Fuzzyma picture Fuzzyma  路  3Comments

lzp819739483 picture lzp819739483  路  3Comments

ghost picture ghost  路  3Comments