viktorruskai/advanced-upsert-for-laravel
Advanced upsert functionality for Laravel, extending Eloquent's bulk insert-or-update capabilities with flexible conflict handling so you can efficiently sync large datasets without repetitive queries.
insertOrIgnore/upsert loops and per-row save() calls. The decision is narrow — it competes with "write 30 lines of query-builder code" more than with a paid vendor.Illuminate\Support\Collection inputs. That is a small but real product signal: teams can pass results of ->map(), ->filter(), chunked queries, or Eloquent collection pipelines straight into an upsert without a ->toArray() conversion step. It reduces the surface area where a well-intentioned ->toArray() on a nested/chunked collection silently mangles data.ON DUPLICATE KEY, Postgres ON CONFLICT, SQLite variants), and that is a product-visible difference in behavior, not just an implementation detail.Adopt when most of the following hold:
Collection a first-class input, which is the version to standardize on if you adopt.Look elsewhere or hold when:
upsert() on the query builder / Eloquent has existed since 8.x) or an in-house wrapper you control.upsert() already covers you. Before adopting, do the honest comparison: native upsert($values, $uniqueBy, $update) handles a large share of real needs. The gap this package fills is convenience and driver-specific options, not a fundamental capability.To executives: A small, low-cost open-source utility that makes high-volume database writes (imports, syncs, nightly jobs) significantly cheaper than row-by-row saves. The 1.0.1 release is an incremental ergonomics improvement — you can now feed Laravel collections directly into it, which trims boilerplate from our data-pipeline code. It is not a platform bet; treat it as a tactical dependency decision with a clear exit (Laravel's native upsert, or a thin in-house wrapper) if the package stalls. Recommend a scoped pilot on one non-critical sync job before broader use.
To engineering: Version 1.0.1 adds Collection support alongside the existing array input, so ->map()/->filter() pipelines can call the upsert directly. The ask is a timeboxed spike: benchmark against native upsert() on our real dataset, confirm driver-specific conflict semantics match our expectations on multi-unique-key tables, and verify chunking/memory behavior on our largest job. Pin the exact version, and if the spike shows no meaningful win over native upsert(), we skip the dependency — the goal is the outcome, not the package. Flag the single-maintainer risk and decide up front who owns the fork if needed.
How can I help you explore Laravel packages today?