Laravel 数据库迁移回滚错误,列数据过长

3
我正在使用Laravel 5.3,迁移功能非常好用,可控制数据库开发。
我的问题是:当我将列类型从字符串更改为文本时,一切都运行良好。但是,如果用户保存的数据长度超过了255(varchar),则我的迁移无法回滚。它会显示“列数据过长”。请问大家有什么解决方法?
Schema::table('tbname', function(Blueprint $table)
{
    $table->text('value')->change();
});

Schema::table('tbname', function(Blueprint $table)
{
    $table->string('value')->change();
});

Seeder(种子节点):
$records = [
    [
        'description' => 'The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. '
    ],
    [
        'description' => 'The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. The description is longer than 255. '
    ]
];

foreach ($records as $index => $record) {
    Desc::create($record);
}

需要更多细节。请在问题中添加迁移代码和来自数据库的表描述。 - linuxartisan
1
如果您使用的是MySQL版本<5.7,则最近我也遇到了这个错误。您可以在此处找到解决方案。 - Ahmed Khan
1
https://laravel-news.com/laravel-5-4-key-too-long-error - Ahmed Khan
有没有解决这个问题的方法?我在L5.4上回滚时遇到了完全相同的问题。 - Oluwatobi Samuel Omisakin
1
@OmisakinOluwatobi,我已经更新了我的答案,提供了更多的解释,以及一个可能的解决方法。 - patricus
2个回答

11

您的text字段中有超过255个字符。在回滚时,您尝试将该字段更改为varchar(255)。此时,MySQL需要做出决策:要么将数据截断以适应255个字符,要么抛出错误。

如果使用严格模式的MySQL,则MySQL会抛出错误。如果不使用严格模式,则MySQL将在不发生错误的情况下截断数据。

Laravel 5.3默认使用严格模式。

如果您想停止收到此错误消息,可以通过在config/database.php文件中设置'strict' => false来禁用严格模式。

请注意,尽管这将抑制错误,但也会有后果。先前导致此错误的数据现在将被截断而不会出现任何错误。

如果您只想为回滚禁用严格模式,可以创建一个具有禁用严格模式的第二个数据库连接,并告诉迁移使用该连接进行回滚。请记住,这将截断此字段中长度超过255个字符的所有数据。

配置:

'connections' => [
    'mysql' => [
        /* normal connection information */
        'strict' => true,
    ],
    'mysql-rollback' => [
        /* normal connection information */
        'strict' => false,
    ],
],

迁移:

public function down()
{
    Schema::connection('mysql-rollback')->table('tbname', function(Blueprint $table) {
        $table->string('value')->change();
    });
}

感谢您提供全面的答案。实际上,在生产环境中,将文本回滚到varchar并不实用。在开发过程中,我只需删除所有表格并重新运行迁移即可。 - Oluwatobi Samuel Omisakin

2
在 Laravel 中,字符串类型可以创建 varchar 数据库列。VARCHAR 列中的值是可变长度的字符串。在 MySQL 5.0.3 之前,长度可以指定为 0 到 255 的值,在 5.0.3 及更高版本中可以指定为 0 到 65,535。在 MySQL 5.0.3 及更高版本中,VARCHAR 的最大有效长度取决于最大行大小(65,535 字节,这个大小是所有列共享的)和所使用的字符集。
如果你运行的 mysql 版本低于 MySQL 5.0.3,请使用文本数据类型而不是字符串。

(65,535字节,分配给所有列)。 你让我的一天变得更加美好! - Aciddiz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接