You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel使用Maatwebsite/Excel导入CSV时检测列存在及修复时间字段问题

问题原因排查

首先可以明确,迁移文件中的$table->timestamps()不是导致该问题的原因,该方法仅作用于创建表结构阶段,仅负责生成created_at、updated_at两个时间戳字段,不会主动覆盖你手动赋值的字段内容。

实际问题出在两个可能性上:

  1. WithUpserts接口的默认规则限制
    你在导入类中使用了WithUpserts接口实现存在则更新的逻辑,Laravel Excel默认会把created_at、updated_at这类时间戳字段排除在upsert的更新字段列表之外,导致你在model方法中对created_at的赋值没有被实际写入数据库。
  2. 模型批量赋值过滤
    如果你的User模型的$fillable属性没有加入created_at字段,Laravel的批量赋值保护机制会直接过滤掉你传入的created_at值,导致字段使用默认的当前时间。

解决办法

方案1:指定Upsert更新字段(推荐)

在你的UsersImport类中新增upsertColumns方法,明确将created_at加入到允许更新的字段列表中:

class UsersImport implements ToModel, WithCustomCsvSettings, WithHeadingRow, WithUpserts
{
    // 原有方法保持不变

    public function upsertColumns()
    {
        return [
            'firstname',
            'lastname',
            'password',
            'created_at',
            // 其他你需要在用户邮箱重复时更新的字段
        ];
    }
}

方案2:调整模型批量赋值规则

确认User模型的$fillable属性已经包含created_at字段:

// User模型中
protected $fillable = [
    'firstname',
    'lastname',
    'email',
    'password',
    'created_at', // 新增该行
];

如果不需要在更新已有用户时修改created_at字段,仅需要在首次创建时赋值,也可以直接关闭导入时的时间戳自动更新,在model方法中新增临时设置:

public function model(array $row)
{
    $user = new User([
        'firstname' => $row['firstname'],
        'lastname' => $row['lastname'],
        'email' => $row['email'],
        'password' => $row['pass'],
        'created_at' => !empty($row['registered']) ? Carbon::parse($row['registered']) : Carbon::now(),
    ]);
    $user->timestamps = false;
    return $user;
}

内容的提问来源于stack exchange,提问作者Abdo Rabah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 06:12:02