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

Laravel中coverage_area表created_at与updated_at字段无法自动更新问题咨询

Laravel Upsert 不自动填充 created_at/updated_at 的问题分析与解决

从你的代码场景来看,问题核心在于Laravel upsert 方法的底层特性,具体原因和解决办法如下:

为什么时间戳不会自动填充?

Laravel 模型的created_at/updated_at自动填充依赖模型的生命周期事件(比如creating/updating)和内置的自动注入逻辑,但upsert是一种直接对接数据库的批量操作——它会生成原生SQL的INSERT ... ON DUPLICATE KEY UPDATE语句,完全绕过了模型的事件系统和自动填充机制。

你手动初始化数据时能正常设置时间戳,是因为你显式在插入数组里传入了created_at和updated_at;但Excel导入的upsert代码中,$data_insert数组没有包含这两个字段,且upsert的更新字段列表也未涉及updated_at,所以数据库不会自动处理时间戳。

解决办法

方案1:手动在数据数组中添加时间戳(代码层面控制,推荐)

修改构建$data_insert的逻辑,显式加入时间戳字段,同时更新upsert的更新字段列表:

$data_insert[] = [
    'id' => $id,
    'village_id'=>$village_id,
    'hub_id'=>$hub_id,
    'price' => $price, // 这里注意:要用你转换后的$price,而非原始的$row['price'],避免字符串格式和decimal字段冲突
    'status' => $row['status'],
    'created_at' => now(), // 新增记录时自动设为当前时间
    'updated_at' => now()  // 新增/更新都同步当前时间
];

然后更新upsert的更新字段参数,把updated_at加入进去:

CoverageArea::upsert($data_insert,'id',['price','status','updated_at']);

效果说明:

  • 新增记录:created_at和updated_at都会被设为当前时间
  • 更新记录:updated_at会被刷新为当前时间,created_at保持原有值(因为更新字段列表未包含它)

方案2:数据库层面设置自动默认值(无需修改业务代码)

如果希望数据库自动处理时间戳,可以修改表结构,让字段自带默认值和更新触发逻辑:

  1. 创建新迁移文件:
php artisan make:migration modify_coverage_area_timestamps
  1. 在迁移的up方法中修改字段:
public function up()
{
    Schema::table('coverage_area', function (Blueprint $table) {
        $table->timestamp('created_at')->useCurrent()->change();
        $table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate()->change();
    });
}
  1. 运行迁移:
php artisan migrate

这样即使代码不传时间戳字段,数据库也会自动填充created_at(新增时)、自动更新updated_at(修改时)。

额外小提醒

你代码里有个潜在问题:构建$data_insert时用了原始的$row['price'],但前面已经把价格转换成了数字类型的$price,如果直接存带Rp或.的字符串,会和数据库decimal类型字段冲突,建议替换为转换后的$price。

内容的提问来源于stack exchange,提问作者julio baptiso

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 17:14:05