Importing Data
Importing Data
The importData() method reads JSON files and imports records into the database using Laravel's updateOrCreate() method, which provides upsert (update or create) logic.
How It Works
importData() is called from your seeder's run() method:
public function run(): void
{
$this->importData();
}For each record in the JSON file:
- Extracts the columns specified in
$uniqueByas the WHERE clause - Uses all remaining columns as the values to update/create
- Calls
Model::updateOrCreate($where, $values)
The Upsert Logic
Single Unique Column
When $uniqueBy = 'email':
protected string $uniqueBy = 'email';Each JSON record is processed like this:
User::updateOrCreate(
['email' => $record['email']], // WHERE clause
[
'name' => $record['name'],
'created_at' => $record['created_at'],
'updated_at' => $record['updated_at'],
]
);If a user with that email exists, it's updated. If not, a new user is created with all fields.
Composite Unique Keys
When $uniqueBy = ['tenant_id', 'email']:
protected array $uniqueBy = ['tenant_id', 'email'];Each JSON record is processed like this:
User::updateOrCreate(
[
'tenant_id' => $record['tenant_id'],
'email' => $record['email'],
],
[
'name' => $record['name'],
'phone' => $record['phone'],
'created_at' => $record['created_at'],
'updated_at' => $record['updated_at'],
]
);Records are uniquely identified by the combination of tenant_id and email.
Example
JSON File (users.json)
[
{
"id": 1,
"email": "[email protected]",
"name": "John Doe",
"phone": "+1-555-0100",
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-01T00:00:00Z"
},
{
"id": 2,
"email": "[email protected]",
"name": "Jane Smith",
"phone": "+1-555-0101",
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-01T00:00:00Z"
}
]Seeder Class
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
use OiLab\OiLaravelSeeds\Traits\ExportableSeeder;
class UserSeeder extends Seeder
{
use ExportableSeeder;
protected string $jsonFilename = 'users.json';
protected string $modelClass = User::class;
protected string $uniqueBy = 'email';
public function run(): void
{
$this->importData();
}
}Execution
When you run php artisan db:seed --class=UserSeeder:
- First run: Both users are created with IDs 1 and 2
- Second run:
- John's record is found by email and updated (if any fields changed)
- Jane's record is found by email and updated (if any fields changed)
- No duplicates are created
Multiple Models
A single seeder can import data for multiple models:
protected array $jsonFilename = ['users.json', 'profiles.json'];
protected array $modelClass = [User::class, Profile::class];
protected string $uniqueBy = 'id';The importData() method processes each pair in order:
- Import records from
users.jsoninto theUsermodel - Import records from
profiles.jsoninto theProfilemodel
Missing Unique Key Handling
If a record is missing a column specified in $uniqueBy, that record is skipped with a warning:
protected array $uniqueBy = ['tenant_id', 'email'];If a record in the JSON lacks either tenant_id or email, it cannot be uniquely identified and is skipped.
Relations in Imported Data
When importing, nested relation data in JSON is ignored. Only the parent model is imported:
[
{
"id": 1,
"name": "John Doe",
"email": "[email protected]",
"posts": [
{
"id": 1,
"title": "First Post"
}
]
}
]Only the user record is created/updated. The posts are not automatically imported.
If you need to import relations, create separate seeders for each model.
Via Command
Import data using the Artisan command:
php artisan seed:import --seeder=UserSeederImport all seeders (respecting dependency order):
php artisan seed:importNext Steps
- Seeder Dependencies — Understand dependency ordering
- Multiple Models — Import multiple models per seeder
- Commands — Full seed:import command reference