Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Upsert Laravel Package

staudenmeir/laravel-upsert

Extends Laravel's upsert capabilities with support for custom unique indexes, ignoring duplicate inserts, and bulk updates across MySQL, PostgreSQL, SQLite, and SQL Server. Adds insertIgnore/insertOrIgnore helpers for dependable insert-or-update queries without extra boilerplate.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

Feature-level decisions

  • Bulk import, sync, and ETL workflows. The package collapses "check if exists, then insert or update" into a single atomic statement, which directly reduces code complexity and round-trips for CSV uploads, catalog refreshes, CRM/ERP sync, third-party data ingestion, and nightly reconciliation jobs.
  • Idempotent write paths. Enables retry-safe and replay-safe behavior for webhook ingestion, event deduplication, duplicate-suppression tables, and "create-or-update" provisioning flows — a product reliability feature, not just a database feature.
  • Data integrity and consistency guarantees. Because inserts and updates happen in one statement rather than in application-level read-modify-write logic, the product gains a stronger concurrency story (fewer race conditions, fewer duplicate rows) that can be described to customers and auditors as a correctness property.
  • Time-to-market on legacy Laravel. If the product sits on an older Laravel version (roughly 5.5–8.9), this is a tactical accelerator that unlocks upsert/insert-ignore semantics without a framework upgrade. That is a roadmap lever: it can defer a costly Laravel upgrade without blocking a bulk-write-dependent feature.

Roadmap and sequencing decisions

  • Framework upgrade vs. feature delivery. The package can decouple these two workstreams. If the team is pre-Laravel 8, adoption may let you ship the sync/import feature now and schedule the framework upgrade independently. If the team is already on Laravel 8.10+ (native upsert()) or 6.x+ (native insertOrIgnore()), this package is a redundancy decision, not an adoption decision — and the correct product call is usually to skip it.
  • Build vs. buy. The "buy" here is trivial (MIT, Composer, no service provider or migrations). It replaces custom cross-driver upsert SQL that would otherwise be hand-written and hand-maintained across MySQL, PostgreSQL, SQLite, and SQL Server. For a team without database specialists, that is a real cost avoidance; for a team with them, it is a small convenience.
  • Multi-database product commitments. If the product must certify on more than one database engine, this package offers a single Laravel-level API. That is a genuine strategic enabler for on-prem/self-hosted or multi-cloud deployment options — but only if every in-scope driver is actually tested in CI, not just the primary one.

Decisions this should NOT be used to justify

  • It is not a strategic platform bet, not a differentiator, and not a reason to delay a framework or PHP upgrade.
  • It does not justify adding new database engines to the support matrix on its own — driver semantics differ materially (ON CONFLICT vs. ON DUPLICATE KEY UPDATE vs. MERGE), and those differences are integrity risks, not portability wins.

Portfolio/use-case summary for the roadmap doc: nightly imports, entitlement and configuration sync, deduplicated event writes, bulk CSV uploads, catalog/product updates, cache and denormalized-table refreshes, and any workflow where the same record may legitimately be written many times.

When to Consider This Package

Adopt (or seriously evaluate) when:

  • The production Laravel version lacks native upsert() / insertOrIgnore(), or the native version does not cover the specific need — notably custom conflict-target columns (uniqueBy) or per-column update lists.
  • The product genuinely needs cross-engine SQL Server support, which is the weakest area of native coverage in older Laravel lines and the clearest historical justification for this package.
  • You need both the query builder and Eloquent ergonomics (Model::upsert, insertGetId with ignore support) with consistent behavior across MySQL, PostgreSQL, SQLite, and SQL Server.
  • The write path is inherently bulk and idempotent, and the team is prepared to own the dependency: pin the Composer version, test against the exact PHP/Laravel/database runtime in production, and name an internal owner.

Look elsewhere — or use Laravel native features — when:

  • The application is on a modern Laravel that already provides adequate upsert() / insertOrIgnore(). Do not add a dormant dependency to duplicate a maintained one. This is the default case for most teams and should be the first check, not the last.
  • Production runs PHP 8.1+ or a Laravel major not explicitly validated by the package. The last release was 2022-01-14 and its only documented change was PHP 8.0 support; forward compatibility is presumed, not proven. The most common real-world failure with this package today is a Composer constraint block on Laravel 10/11, not a broken API.
  • The dependency would sit on a critical path requiring active maintenance, security responsiveness, or a formal support SLA. Single maintainer, community-only, no commercial backing, low star count and zero listed dependents — treat that as unproven adoption evidence (verify via Packagist download trends rather than GitHub metadata), not as proof of poor quality.
  • The product needs advanced merge semantics, engines outside the supported set, or behavior that must be contractually guaranteed.
  • Silent error suppression is unacceptable in your domain. MySQL's INSERT IGNORE downgrades all errors to warnings — including truncation and foreign-key violations. If you cannot add compensating validation, do not use the ignore path.

Gating questions before any commitment:

  1. Which Laravel version is in production, and does native support already cover the requirement including custom conflict targets and per-column updates?
  2. Which database engines and versions are in scope — and are all of them exercised in CI, or only the primary one?
  3. Does the generated SQL behave correctly on MySQL 8.0.20+ (the VALUES(col) reference form is deprecated) and on the team's specific SQL Server version?
  4. What is the policy for suppressed errors on ignore paths, and who validates that the rows actually landed?
  5. Is there a named internal owner and a documented exit plan (migrate to native when X)?
  6. Are there conflicts with other packages that extend the query builder or override grammar classes? That is the realistic breakage vector.

How to Pitch It (Stakeholders)

For executives — the one-paragraph version: This is a small, MIT-licensed Laravel utility that can meaningfully accelerate bulk data sync, import, and deduplication features by replacing per-record read-then-write logic with efficient single-statement upserts. It is cheap to trial, requires no schema changes, and has a low rollback cost. It is not a strategic platform bet: the last release was in 2022, its documented baseline is PHP 8.0, it has a single maintainer with no commercial backing, and modern Laravel may already ship equivalent built-in functionality. Recommendation: approve only as a time-boxed tactical dependency, with a named owner and a documented exit path — and only after engineering has confirmed the native framework methods do not already cover the need. Expected business payoff is faster delivery of bulk-sync features and fewer data-integrity bugs from hand-rolled write logic; expected cost is a small, bounded maintenance overhead reviewed annually and at each Laravel major upgrade.

For engineering — what to confirm before we commit:

  1. Classify the request first. Is this a capability gap (older Laravel, missing SQL Server support, need for richer conflict/update signatures) or a developer preference? If native upsert() / insertOrIgnore() covers it, do not add the dependency.
  2. Treat adoption as a behavioral change, not an install. Collapsing read-modify-write into one statement changes concurrency semantics, error semantics, affected-row counts, trigger and audit behavior, and replication timing. These are invisible in happy-path tests and visible in production under contention. Get sign-off from whoever owns the affected tables, not only the feature team.
  3. Test the full driver matrix in CI, not just the local engine. Validate conflict-column behavior, batch-size ceilings against each driver's bind-parameter limit (compute, don't hardcode), and MySQL 8.0.20+ and SQL Server MERGE semantics specifically.
  4. Watch the named failure modes: silent truncation/FK loss via INSERT IGNORE on MySQL; duplicate-key errors under parallel load with SQL Server MERGE; deadlocks when workers upsert overlapping key ranges (order batches by key); behavior drift after a database minor-version upgrade; and framework upgrades breaking the grammar extension point. Each needs a concrete detection signal, not just a rollback note.
  5. Sequence it: confirm the native gap → document it → pin in composer.json on a branch → add driver-matrix tests for the specific statements → convert one write path behind the existing repository/service boundary (not inline in controllers) → feature-flag the old path → validate in staging at production-like volume and concurrency → canary by job or tenant → retire legacy → record the decision plus the "replace with native when X" trigger in the architecture log.
  6. Keep runtime upgrades and package adoption as separate workstreams so a failed adoption does not block a PHP upgrade. Ensure the database enforces a real unique index on the conflict target — without it, PostgreSQL errors out and the whole mechanism silently breaks.
  7. Write the one-page internal note: when to use the package vs. native, batch-size guidance, the accepted error-suppression policy, and how to verify a bulk upsert actually landed the expected rows. That page prevents most foreseeable incidents.

For the sponsor / go-no-go: Approve a time-boxed trial on one non-critical bulk-write path, with a defined success metric (e.g., reduced write latency or eliminated duplicate-key bugs on the import job), a named engineering owner, and a decision date. Success → convert remaining paths and log the exit criteria. Failure or dormancy → revert to native methods; rollback is cheap precisely because no schema migration is required, so preserve that property by avoiding package-specific column or table conventions.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib