Laravel Migrations - 创建时间戳时出现的问题

时间:2015-05-31 09:25:55

标签: php mysql laravel migration

我正在尝试在Laravel实例上运行迁移。它们只是默认迁移(用户和密码重置),但是当它尝试生成时间戳时会抛出此错误:

 [Illuminate\Database\QueryException]
 SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'created_at' (SQL: create table `
 users` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `email` varchar(255) n
 ot null, `password` varchar(60) not null, `remember_token` varchar(100) null, `created_at` timestamp default 0 not
 null, `updated_at` timestamp default 0 not null) default character set utf8 collate utf8_unicode_ci)

以及PDOException:

SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'created_at'

我该如何解决这个问题?

感谢。

9 个答案:

答案 0 :(得分:10)

这是因为MySQL不接受零作为有效的默认日期,因此表创建失败了对创建的约束检查。

您的MySQL配置可能已启用NO_ZERO_DATE。将此设置为off将允许您创建表格,或者删除默认值0或将其更改为CURRENT_TIMESTAMP

您可以在此处找到有关此确切问题的更多信息:https://github.com/laravel/framework/issues/3602

答案 1 :(得分:4)

听起来像严格的模式。

您可以通过以下两种方式之一禁用严格模式:

在MySQL安装目录中打开my.ini文件,然后查找文本sql-mode。

查找

SQL模式= “STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”

并改为

SQL模式= “NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”

或者您可以在phpMyAdmin

中运行以下命令

SET @@ global.sql_mode ='';

答案 2 :(得分:4)

这是因为MySQL不接受零作为有效的默认日期,因此您可以编写

$table->timestamp('created_at')->nullable();
$table->timestamp('updated_at')->nullable();

$table->nullableTimestamps();

而不是$table->timestamps();

答案 3 :(得分:2)

在严格模式失败后,这对我有用:

$table->timestamp('published_on')->useCurrent();

答案 4 :(得分:2)

您可以使用nullableTimestamps()代替timestamps()

否则

$table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP'));

另外,检查数据库服务器版本

请查看以下参考链接:

https://github.com/laravel/framework/issues/3602

https://laracasts.com/discuss/channels/forge/syntax-error-or-access-violation-1067-invalid-default-value-for-created-at

答案 5 :(得分:1)

我使用了以下方法:

$table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(\DB::raw('CURRENT_TIMESTAMP'));

真的很有效!

答案 6 :(得分:0)

迁移旧表的方式如下:

Schema::table(
            'table',
            function (Blueprint $table) {
                $table->dateTime('created_at')->nullable()->default(NULL)->change();
                $table->dateTime('updated_at')->nullable()->default(NULL)->change();
            }
        );

来自https://github.com/laravel/framework/issues/3602

答案 7 :(得分:0)

您应该在Laravel上禁用MySQL严格模式。 从5.1版本开始,MySQL就采用了严格的模式,但是在5.7版本中,它成为了默认模式。 在Laravel中,您可以使用代码解决此问题:编辑database.php配置文件,并添加一个值为strict的密钥false

面向非Laravel用户:

如果您使用的是非Laravel应用程序,则没有该选项。以下是全局禁用严格模式的方法。找到您的MySQL配置文件my.cnfmy.ini 默认的MySQL配置将保存在/etc/mysql/my.cnf

打开文件并找到[mysqld]部分。我们将添加一个新密钥sql_mode 在MySQL 5.7上,此键的默认值为:

STRICT_TRANS_TABLES,ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

严格模式来自STRICT_TRANS_TABLES。因此,让我们将sql_mode覆盖为:

[mysqld]
sql_mode=ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

就是这样!保存文件,然后重新启动 MySQL

答案 8 :(得分:0)

MySQL 5.7.28

The MySQL docs建议以下内容(注意使用GLOBAL):

SET GLOBAL sql_mode = 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';