wfeller/laravel-batch

Insert, update or delete models in batch, while still firing model events.

7.0.3 2022-03-30 15:00 UTC

This package is auto-updated.

Last update: 2024-04-29 03:41:41 UTC


README

Save and update your eloquent models in batches

Latest Version on Packagist Total Downloads Plant Tree Buy us a tree

This package allows you to save and update models in batch, meaning you can save or update many models at the same time, and still fire your events as single saves or updates do.

Licence

This package is Treeware. If you use it in production, then we ask that you buy the world a tree to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.

You can buy trees here offset.earth/treeware

Read more about Treeware at treeware.earth

Installation

You can install the package via composer:

composer require wfeller/laravel-batch

Usage

Creating and updating models

use App\Car;
use WF\Batch\Batch;

$cars = [
    ['brand' => 'Audi', 'model' => 'A6'],
    ['brand' => 'Ford', 'model' => 'Mustang'],
    $myCar // an existing or new car instance
];

$carIds = Batch::of(Car::class, $cars)->save()->now();

// You can queue the batch
Batch::of(Car::class, $cars)->save()->dispatch();
Batch::of(Car::class, $cars)->save()->onQueue('other-queue')->dispatch();

// You can set the batch size based on your needs
Batch::of(Car::class, $cars)->batchSize(1000)->save()->now();

For the updates, there will be one DB query per updated column. For the saves, there will only be one query per set of columns.

Deleting Models

use App\Car;
use WF\Batch\Batch;

$cars = [
    1, // a car id
    $car, // a car instance
    ... // many more cars
];

$deletedIds = Batch::of(Car::class, $cars)->delete()->now();
Batch::of(Car::class, $cars)->delete()->dispatch();
Batch::of(Car::class, $cars)->delete()->onQueue('other-queue')->dispatch();

You'll have 1 query to delete your models. If you're passing model IDs, the models will be loaded from the DB to fire the deletion model events.

If you want to create batches directly from your models:

class Car extends \Illuminate\Database\Eloquent\Model
{
    use \WF\Batch\Traits\Batchable;
    
    // ...
}

// This allows you to call
Car::newBatch($cars)->save()->now();
// which is the same as
Batch::of(Car::class, $cars)->save()->now();

Benchmarks

These benchmarks are not accurate, but they give some kind of rough idea of the potential performance improvement or usefulness of this package.

The results vary a lot based on the DB driver, but basically that's what you get:

  1. Laravel's bulk insert (this one doesn't fire model events though, the others do)
  2. This package's Batch Saving (1.3 to 3 times slower than #1)
  3. Laravel foreach create (8 to 50 times slower than #1)
  • Laravel's bulk insert is the fastest, but doesn't fire model events.
User::insert([$userA, $userB, $userC]);
  • This package's Batch Saving takes up to 3 times as long as Laravel's bulk insert, but your model events get fired
Batch::of(User::class, [$userA, $userB, $userC])->save()->now();
  • 'Foreach create' is the slowest, taking at least 3 times longer than Batch Saving
$users = [$userA, $userB, $userC];
foreach ($users as $user) 
{
    User::create($user);
}

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email me instead of using the issue tracker.

Credits