Laravel迁移报错:nullable默认值异常,Homestead迁移至Valet后失效
Got it, let's break down why this error is popping up after moving from Homestead to Valet, and how to fix it.
Why This Happens
The core issue is MySQL's strict mode settings. Homestead typically uses a more permissive sql_mode configuration by default, while Valet (especially if you're using a local MySQL install via Homebrew or default system MySQL) often enables strict modes like NO_ZERO_DATE, NO_ZERO_IN_DATE, and STRICT_TRANS_TABLES.
When you run $table->date('end_date')->nullable()->change();, MySQL in strict mode rejects the change because it detects an invalid default value (likely 0000-00-00 from your existing schema, which isn't allowed when strict mode is on and the field is nullable).
Solutions to Try
1. Adjust MySQL's Global sql_mode Configuration
This is a permanent fix for your local environment:
- Locate your MySQL config file. For Homebrew-installed MySQL on macOS, this is usually
/usr/local/etc/my.cnfor/usr/local/etc/my.cnf.d/mysql-server.cnf. On Linux, check/etc/my.cnfor/etc/mysql/my.cnf. - Find the
sql_modeline and modify it to remove the strict mode flags causing the issue. For example:sql_mode = "ONLY_FULL_GROUP_BY,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" - Restart MySQL to apply changes:
# For Homebrew brew services restart mysql # For system MySQL (Linux) sudo systemctl restart mysql
2. Explicitly Set a Valid Default Value in the Migration
If you don't want to mess with global MySQL settings, update your migration to explicitly define a valid default (like null):
public function up() { Schema::table('your_table_name', function (Blueprint $table) { // Explicitly set default to null before making it nullable $table->date('end_date')->default(null)->nullable()->change(); }); }
This tells MySQL exactly what default value to use, avoiding the invalid 0000-00-00 that strict mode rejects.
3. Temporarily Disable Strict Mode for the Migration
If you need a one-off fix without changing global settings, override the sql_mode just for this migration:
public function up() { // Temporarily remove NO_ZERO_DATE from sql_mode DB::statement("SET sql_mode=(SELECT REPLACE(@@sql_mode,'NO_ZERO_DATE',''));"); Schema::table('your_table_name', function (Blueprint $table) { $table->date('end_date')->nullable()->change(); }); }
This will only affect the current migration execution, leaving your global MySQL settings intact.
Verify the Fix
To confirm the issue was strict mode, run this in your MySQL terminal:
SELECT @@sql_mode;
If you see NO_ZERO_DATE or STRICT_TRANS_TABLES in the output, that's definitely the culprit. After applying any of the fixes, re-run your migration with php artisan migrate and it should work.
内容的提问来源于stack exchange,提问作者user88432

