Laravel使用Maatwebsite/Excel导入CSV时检测列存在及修复时间字段问题
问题原因排查
首先可以明确,迁移文件中的$table->timestamps()不是导致该问题的原因,该方法仅作用于创建表结构阶段,仅负责生成created_at、updated_at两个时间戳字段,不会主动覆盖你手动赋值的字段内容。
实际问题出在两个可能性上:
WithUpserts接口的默认规则限制
你在导入类中使用了WithUpserts接口实现存在则更新的逻辑,Laravel Excel默认会把created_at、updated_at这类时间戳字段排除在upsert的更新字段列表之外,导致你在model方法中对created_at的赋值没有被实际写入数据库。- 模型批量赋值过滤
如果你的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
相关产品推荐
相关产品推荐

