Laravel 迁移 - 创建时间戳时的问题

Posted

技术标签:

【中文标题】Laravel 迁移 - 创建时间戳时的问题【英文标题】:Laravel Migrations - Issues while creating timestamps 【发布时间】:2015-08-13 20:53:32 【问题描述】:

我正在尝试在我的 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'

我该如何解决这个问题?

谢谢。

【问题讨论】:

created_at 列中你有任何默认值吗?你不应该拥有它!您应该只将日期时间列作为其数据类型 阅读此github.com/cartalyst/sentry/issues/137 【参考方案1】:

我也遇到了同样的错误。鉴于解决方案确实可以正常工作,我仍然想帮助 laravel 开发人员。 只需在 config/database.php 中添加以下行

'mysql' => array(
   'strict'    => true
),

【讨论】:

在使用 Laravel 派生应用程序 (Snipe-IT) 时,这解决了我的问题。比其他选择干净得多。 我必须将'strict' 设置为false,但它的工作原理都是一样的。谢谢。【参考方案2】:

这是由于 MySQL 不接受零作为有效的默认日期,因此表创建未通过创建约束检查。

您可能在 MySQL 配置中启用了NO_ZERO_DATE。将此设置为关闭将允许您创建表或删除默认值 0 或将其更改为 CURRENT_TIMESTAMP

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

【讨论】:

【参考方案3】:

听起来像是严格模式。

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

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

查找:

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

改成

sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

或者您可以在 phpMyAdmin 中运行以下命令

SET @@global.sql_mode='';

【讨论】:

【参考方案4】:

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

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

$table->nullableTimestamps();

而不是$table->timestamps();

【讨论】:

【参考方案5】:

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

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

【讨论】:

【参考方案6】:

我使用了以下方法:

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

真的成功了!

【讨论】:

【参考方案7】:

迁移旧表的工作方式如下:

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

【讨论】:

【参考方案8】:

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

对于非 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

【讨论】:

【参考方案9】:

您可以使用 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

【讨论】:

【参考方案10】:

MySQL 5.7.28

The MySQL docs推荐如下(注意使用GLOBAL):

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

【讨论】:

以上是关于Laravel 迁移 - 创建时间戳时的问题的主要内容,如果未能解决你的问题,请参考以下文章

Android/Firebase - 在 GCM 事件中解析时间戳时出错 - 时间戳为空

在没有时区的时间戳的字段上加入没有时区的 generate_series 时间戳时遇到问题

将基于十进制列的时间戳转换为实际时间戳时,使用 HH24MISS 扩展“格式字符串”的问题

Bigtable:在行键上使用时间戳时避免热点

当数据重复且我没有时间戳时避免重复插入的建议

Laravel 数据透视表时间戳