Skip to content

Conversation

@dereuromark
Copy link
Member

@dereuromark dereuromark commented Nov 28, 2025

Summary

I realized that some interface changes might be necessary, so I thought better tackle this before we tag 5.x stable.

Implements insertOrUpdate() method for upsert operations - inserting new rows and updating existing rows on duplicate key conflicts.

Resolves #950

Features

  • New insertOrUpdate() method on Table class and seed interface
  • Requires explicit conflict columns (columns that define uniqueness)
  • Requires explicit update columns (columns to update on conflict)
  • Works with both single row and bulk inserts

Database Support

Database Syntax
MySQL ON DUPLICATE KEY UPDATE col = VALUES(col)
PostgreSQL ON CONFLICT (cols) DO UPDATE SET col = EXCLUDED.col
SQLite ON CONFLICT (cols) DO UPDATE SET col = excluded.col

SQL Server support is not included in this PR.

Usage

// In migrations or seeds
$table->insertOrUpdate([
    ['code' => 'USD', 'rate' => 1.0000],
    ['code' => 'EUR', 'rate' => 0.9234],
], ['rate'], ['code'])->save();

// In seeds (shorthand)
$this->insertOrUpdate('currencies', [
    ['code' => 'USD', 'rate' => 1.0000],
    ['code' => 'EUR', 'rate' => 0.9234],
], ['rate'], ['code']);

Implements upsert functionality that inserts new rows and updates existing
rows on duplicate key conflicts.

Database support:
- MySQL: ON DUPLICATE KEY UPDATE
- PostgreSQL: ON CONFLICT (...) DO UPDATE SET
- SQLite: ON CONFLICT (...) DO UPDATE SET

Usage:
$table->insertOrUpdate($data, $updateColumns, $conflictColumns);
$this->insertOrUpdate($tableName, $data, $updateColumns, $conflictColumns);

Refs #950
@dereuromark dereuromark marked this pull request as ready for review December 9, 2025 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants