在开发laravel项目的时候,migrate的时候,出现离奇错误。
错误完整内容如下:
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'expiry_date_end' (SQL: create table `app_membership_card_user` (`id` int unsigned not null auto_increment primary key comment '记录自增ID', `user_id` int not null comment '用户ID', `kind_id` int not null comment '会员卡种类ID', `expiry_date_start` timestamp not null comment '有效期的起始日期', `expiry_date_end` timestamp not null comment '有效期的截止日期', `money` double not null comment '会员卡的实际办理金额', `created_at` timestamp null, `updated_at` timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci')
at /Users/icemoon/Projects/laravel-wash-car/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
660| // If an exception occurs when attempting to run a query, we'll format the error
661| // message to include the bindings with SQL, which will make this exception a
662| // lot more helpful to the developer instead of just the database's errors.
663| catch (Exception $e) {
> 664| throw new QueryException(
665| $query, $this->prepareBindings($bindings), $e
666| );
667| }
668|
Exception trace:
1 PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'expiry_date_end'")
/Users/icemoon/Projects/laravel-wash-car/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458
2 PDOStatement::execute()
/Users/icemoon/Projects/laravel-wash-car/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458
Please use the argument -v to see more details.
开发平台:macbook pro 13
MySQL:5.7.24
php:7.2.14
平台软件都是用brew安装的。
migration的代码如下:
public function up()
{
Schema::create('app_membership_card_user', function (Blueprint $table) {
$table->increments('id')->comment('记录自增ID');
$table->integer('user_id')->unique()->comment('用户ID');
$table->integer('kind_id')->unique()->comment('会员卡种类ID');
$table->timestamp('expiry_date_start')->comment('有效期的起始日期');
$table->timestamp('expiry_date_end')->comment('有效期的截止日期');
$table->double('money')->unique()->comment('会员卡的实际办理金额');
$table->timestamps();
});
}
初步判断错误原因是由于expiry_date_end来的,在migration删除对应行内容后,执行php artisan migrate好使,但字段不能删。在搜索引擎查了半天,应该是MySQL的设置的问题。
连接本地数据库,执行
select @@sql_mode
查看结果是如下一串
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
其中加粗的NO_ZERO_DATE是要删掉的字段,这个字段导致数据里的时间戳不能为0000-0-0 00:00:00的形式,资料上说删除这个字段应该可以结局问题。
按着教程中做,执行如下语句:
set @@sql_mode=‘ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION’
执行完语句,重启MySQL服务,结果没什么卵用,似乎这种改法改不掉这个字段,继续找资料,查到个方法是改配置文件my.ini,资料中说mac osx的中的MySQL的配置文件不存在,但是我找了半天,竟然找到了。
我的配置文件中的内容如下:
# Default Homebrew MySQL server config
[mysqld]
# Only allow connections from localhost
bind-address = 127.0.0.1
我直接在配置文件中加入如下内容,直接放空自己,本地开发环境。
#sql-mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
sql-mode=
再次重启MySQL服务,执行
select @@sql-mode
返回结果内容为空了,尝试migrate,依然是如上错误。把Laravel生成的SQL语句复制粘贴到数据库中可以完美执行,说明还是Laravel的问题。
哎,鄙视下自己,早没想到粘贴语句到数据库中…
后来在参考[1]中看到了default(DB::raw(‘CURRENT_TIMESTAMP’)) 的代码,粘贴过来试试,问题解决了。
最有解决办法:
$table->timestamp('expiry_date_end')->comment('有效期的截止日期')->default(DB::raw('CURRENT_TIMESTAMP'))
总结:
laravel应该有自己的timestamp的0校验,具体位置没找到,经过此次问题,对MySQL的配置又更加熟悉一步,检索问题的能力也有所提高。
参考:
[1]:https://github.com/laravel/framework/issues/3602
[2]:http://www.cnblogs.com/imor/p/7199240.html
[3]:https://blog.csdn.net/wyzxg/article/details/8787878