【问题标题】:Why running Laravel / Doctrine raw database queries is not the same as using mysql cli?为什么运行 Laravel / Doctrine 原始数据库查询与使用 mysql cli 不同?
【发布时间】:2018-08-31 19:28:45
【问题描述】:

我在进行数据库迁移时遇到了一种情况,这与我认为我知道的关于 php 连接到数据库的知识相矛盾。我想改变一列的排序规则,所以我写了以下语句:

ALTER TABLE posts MODIFY COLUMN text_html LONGTEXT COLLATE utf8_unicode_ci

使用 mysql cli 可以正常工作。现在,为了在代码中跟踪这种变化,我创建了一个 Laravel 迁移,使用以下语句:

DB::unprepared('ALTER TABLE posts MODIFY COLUMN text_html LONGTEXT COLLATE utf8_unicode_ci');

我收到以下错误:

SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'published_at' (SQL: ALTER TABLE posts MODIFY COLUMN text_html LONGTEXT COLLATE utf8_unicode_ci)

我认为这可能与 Laravel 有关,所以我尝试做一个更“原始”的查询:

DB::connection() ->getDoctrineConnection() ->exec('ALTER TABLE posts MODIFY COLUMN text_html LONGTEXT COLLATE utf8_unicode_ci');

这给了我类似的错误:

An exception occurred while executing 'ALTER TABLE posts MODIFY COLUMN text_html LONGTEXT COLLATE utf8_unicode_ci': SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'published_at'

所以这里实际上有两个问题。第一个,显然,如果我试图修改 text_html 列,为什么会收到关于 published_at 列的错误。但是第二个,我更感兴趣的一个,是为什么它可以在 mysql cli 上运行,而不能在 php 上运行。如果在 php 中运行原始查询与使用 mysql cli 运行查询不同,这告诉我 php 所做的不仅仅是运行查询。它在做什么?

【问题讨论】:

  • 您已启用严格。检查项目中的 database.php
  • @Indra 绝对是这样,我仍然不明白为什么错误是针对不同的列的,但我想这是 mysql 的问题。因此,我的问题的答案将类似于“laravel 添加了默认情况下不包含在 mysql cli 中并且可以在 config/database.php 中找到的自定义配置”。如果您想回答类似的问题,我会将其标记为已接受的答案。
  • 我更新了答案

标签: php mysql laravel doctrine dbal


【解决方案1】:

编辑:

Laravel 有一个自定义配置,默认情况下不包含在 mysql cli 中。可以在 config/database.php 中找到

我个人这样做是为了绕过它。这对我有用,因为我想保持严格模式开启。如果您不在乎,请使用第一段解决方案。

public function up()
    {

        Schema::table('posts', function ($table) { // you can drop the $table param. Also Schema::table might be redundant so try without first
            DB::statement('ALTER TABLE posts MODIFY text_html LONGTEXT COLLATE utf8_unicode_ci');
        });
    }

如果您的 Db 已经是 utf8_unicode_ci,则不需要收集

【讨论】:

  • 我会将其标记为已接受,因为更改配置有效,但您的代码示例不会更改任何配置,因此仍以严格模式执行。
  • @Noel De Martin 同意,但有些人可能希望保持严格模式,所以这就是我添加的原因。我会更新我的答案以清楚地反映这一点
  • 是的,我想在整体上保持严格模式,所以我最终做的是使用这一行,以便仅在此迁移中禁用严格模式:DB::getPdo()->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();(我这样做了,但我没有不建议任何不明白这是什么的人复制粘贴)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
  • 2021-06-24
  • 1970-01-01
相关资源
最近更新 更多