如何从外部Python脚本或数据库变更触发Laravel通知
核心原因很明确:Python脚本绕过Laravel直接写入数据库时,Laravel的PHP进程全程没有参与数据写入流程,框架自带的ORM事件、通知逻辑都感知不到数据变更,自然不会自动触发通知。你可以根据实际场景按推荐优先级选择以下方案:
最优方案:让Python调用Laravel内部API代替直接写库
这是维护成本最低、逻辑最统一的方案,从根源上避免跨系统触发逻辑的兼容问题:- 在Laravel项目中新增内部专用接口,配置接口签名或独立访问密钥做鉴权,避免公网非法调用
- 接口内部直接复用你现有控制器的业务逻辑:校验参数、写入Txn记录、执行
Notification::send($users, new \app\Notifications\TxnAdded($txn))发送通知 - 把Python脚本原来直接写库的逻辑,改成调用这个接口提交数据,所有数据变更、通知逻辑都收敛在Laravel项目内,后续修改通知规则不需要同步调整Python脚本
次选方案:Python写库成功后主动触发通知接口
如果因为历史包袱、性能要求等原因必须保留Python直接写库的逻辑,可以做轻量改造:- 在Laravel中新增仅用于触发通知的内部接口,鉴权逻辑同上,接口接收txn记录ID作为参数,查询到对应有效记录后执行原有的通知发送逻辑
- Python脚本在确认数据写入数据库成功后,主动请求这个通知接口,传入刚插入的记录ID
- Python端要补充请求失败重试逻辑,避免因为网络波动导致通知漏发
零Python改造方案:Laravel定时任务轮询未通知记录
如果完全不能修改现有Python脚本,可以用定时任务做兜底,不需要动Python端一行代码:- 给txn数据表新增
is_notified字段,类型为tinyint,默认值设为0,用来标记该条记录是否已发送通知 - 在Laravel的定时任务中增加轮询逻辑,按固定频率扫描所有
is_notified=0的记录,批量发送通知后把对应记录的is_notified更新为1,核心代码示例:
// 在app/Console/Kernel.php的schedule方法中添加如下逻辑 $schedule->call(function () { // 查询所有未发送通知的交易记录 $unNotifiedTxns = Txn::where('is_notified', 0)->get(); foreach ($unNotifiedTxns as $txn) { // 直接复用原有通知逻辑 Notification::send($txn->relatedUsers, new \app\Notifications\TxnAdded($txn)); // 标记为已通知,避免重复发送 $txn->update(['is_notified' => 1]); } })->everyMinute(); // 可根据业务对实时性的要求调整执行频率这个方案容错率极高,只要数据成功写入数据库就不会漏发通知,唯一缺点是通知不是完全实时,延迟最多等于轮询间隔。
- 给txn数据表新增
强实时可选方案:数据库Binlog监听触发
如果业务要求通知完全实时,又不能修改Python脚本,可以部署binlog监听服务监控对应数据表的写入事件,当检测到txn表新增符合条件的记录时,自动调用Laravel的通知触发接口或者自定义artisan命令,传入记录ID完成通知发送。这个方案没有延迟,但需要额外维护监听服务,运维成本较高,非强需求不建议使用。
❌ 避坑提醒:不要尝试通过Eloquent模型的
created/updated等模型事件触发通知,这类事件只有走Laravel ORM执行的数据库操作才会触发,外部脚本直接写库时这些事件完全不会执行,无法实现需求。
内容的提问来源于stack exchange,提问作者matt

