MySQL在Yi2迁移时抛出错误,不';PhpMyAdmin中的t

MySQL在Yi2迁移时抛出错误,不';PhpMyAdmin中的t,mysql,yii2,Mysql,Yii2,在我的一次迁移中,我向所有表添加了一列“dateCreated”。这适用于大多数表,但在某些表上会抛出一个奇怪的错误: 'SQLSTATE[22007]:无效的日期时间格式:1292不正确的日期值:第1行“开始日期”列的“0000-00-00” 正在执行的SQL是:ALTER TABLEpaymentsADDdateCreatedDATETIME NULL DEFAULT NULL' “开始日期”列已经存在,但我不明白为什么这与新创建的列有关。 这破坏了我的迁移。当直接应用于PhpMyAdmin

在我的一次迁移中,我向所有表添加了一列“dateCreated”。这适用于大多数表,但在某些表上会抛出一个奇怪的错误:

'SQLSTATE[22007]:无效的日期时间格式:1292不正确的日期值:第1行“开始日期”列的“0000-00-00”
正在执行的SQL是:ALTER TABLE
payments
ADD
dateCreated
DATETIME NULL DEFAULT NULL'

“开始日期”列已经存在,但我不明白为什么这与新创建的列有关。 这破坏了我的迁移。当直接应用于PhpMyAdmin中的表时,同样的SQL也可以正常工作。我是在查询中添加了额外的检查,还是遗漏了其他内容

这是完整的迁移:

public function up()
    $tableNames = Yii::$app->db->schema->tableNames;

    foreach ($tableNames as $tableName) {
        Yii::$app->db->createCommand('ALTER TABLE '.$tableName.' ENGINE = InnoDB')->query();
    }
}

您的迁移中有一些错误

1)迁移应该与数据库结构和与添加时间相关的数据交互,而不是与当前时间交互

当你写这篇文章时:

Yii::$app->db->schema->tableNames

在运行迁移时,您正在引用所有现有表

所以想象一下,如果您以后添加一些新表,而某些表不需要该列。如果您的新队友将运行迁移或将在新服务器上运行迁移,则
dateCreated
将添加到所有表中。如果是其他操作,例如删除,则可能导致严重问题,例如意外的数据丢失

所以请记住——始终使用数据库结构和创建迁移时相关的数据进行操作

例如,我建议创建私有静态数组,并在
up()
down()方法中使用它

private static $_tableNames = [
    'tableName1',
    'tableName2',
];
2)当有许多查询时,将其封装在事务中会更安全。改用
safeUp()
safeDown()方法。在这种情况下,若迁移在某些查询上失败,将应用回滚,并且您不必对数据库进行任何额外的手动操作

3)在迁移过程中,不需要为此类常见任务编写原始SQL。使用
yii\db\Migration
方法

private static $_tableNames = [
    'tableName1',
    'tableName2',
];
4)
yii\db\Command
query()
用于选择,用于删除
execute()
。但不需要使用它,因为在执行原始SQL的迁移中有一个快捷方式:
$this->execute(“您的SQL在这里”)

5)我建议在列名中使用undescore(
)作为分隔符,但这并不重要

最后,您将看到如下所示:

use yii\db\Expression;
use yii\db\Migration;

class m111111_111111_add_date_created_column_to_all_existing_tables extends Migration
{
    /**
     * @var array List of table names
     */
    private static $_tableNames = [
        'tableName1',
        'tableName2',
    ],

    public function safeUp()
    {   
        foreach (self::$_tableNames as $table) {
            $this->addColumn($table, 'date_created', $this->dateTime()->defaultValue(new yii\db\Expression('NULL')));
        }
    }

    public function safeDown()
    {   
        foreach (self::$_tableNames as $table) {
            $this->dropColumn($table, 'date_created');
        }
    }
}
这更像是代码审查,但回到主要问题:在提供的代码中根本没有添加
dateCreated
列(实际上根本没有更改),与
start\u date
相关的错误来自不同的部分

此类查询的逻辑:

ALTER TABLE payments ADD dateCreated DATETIME NULL DEFAULT NULL
正确,因此,
dateCreated
列将添加到所有列出的表名中


现有行将填充
NULL
数据(对于
dateCreated
列),因此不可能出现
0000-00-00
之类的值(也是datetime,而不是date)<代码>开始日期是另一列,请在代码的其他位置检查与其相关的逻辑。

为alter table编写一个单独的迁移,然后检查。这是alter table的单独迁移。现在看来,即使我绕过Yii的DB连接,只使用mysqli,我也会得到同样的错误。Sequel Pro不会抛出错误,让我来更改表…迁移中是否有insert命令,如果是,请检查它的start_date列。我添加了迁移代码。alter table没有通用方法。在提供的示例中,我使用常用方法来添加列。您需要使用
addColumn
dropColumn
来相应地添加和删除列,它们都包含
ALTER TABLE
部分。