首页 > 解决方案 > Laravel 更新分块结果跳过行

问题描述

我正在尝试将我们的数据库从 ID 转换为 UUID。当我运行以下代码来更新数据库时,会跳过随机行。

AppUser::select('id')->orderBy('created_at')->chunk(1000, function ($appUsers) {
        foreach ($appUsers as $appUser) {
            $uuid = Str::orderedUuid();
            DB::table('files')->where('fileable_type', AppUserInfo::class)->where('fileable_id', $appUser->id)->update([
                'fileable_id' => $uuid
            ]);
            DB::table('app_users')->where('id', $appUser->id)->update(['id' => $uuid]);
        }
    });

上次我检查〜290被跳过总数为236196。

我尝试使用 chunkById,但同样的事情发生了。更新函数总是返回 true,所以我必须假设 Laravel 认为每一行在执行时都会更新。

标签: laraveleloquentlaravel-query-builder

解决方案


Laravel 文档中有一个关于分块的重要警告:

在块回调中更新或删除记录时,对主键或外键的任何更改都可能影响块查询。这可能会导致记录不包含在分块结果中。

您需要找到另一种方法来批量更新您的密钥。我已经使用了这个问题的答案中描述的技术:当我无法使用该方法所需的回调时,如何在 Laravel 中对自定义查询的结果进行分块chunk,尽管在这种情况下它不是用于update查询,只有select.


推荐阅读