Installation
composer require vijaytomar/db-importer
Publish the config and migrations:
php artisan vendor:publish --provider="VijayTomar\DBImporter\DBImporterServiceProvider" --tag="config"
php artisan vendor:publish --provider="VijayTomar\DBImporter\DBImporterServiceProvider" --tag="migrations"
php artisan migrate
Basic Configuration
Edit config/db-importer.php to define:
database, redis).First Use Case: Upload & Process a CSV
<form action="{{ route('import.upload') }}" method="POST" enctype="multipart/form-data">
@csrf
<input type="file" name="file" accept=".csv,.xlsx">
<button type="submit">Upload</button>
</form>
use VijayTomar\DBImporter\Facades\DBImporter;
public function upload(Request $request) {
$import = DBImporter::import($request->file('file'))
->toModel(App\Models\User::class)
->chunk(100)
->queue();
return redirect()->route('import.progress', $import->id);
}
mapColumns() to define how CSV headers map to model attributes:
DBImporter::import($file)
->toModel(User::class)
->mapColumns([
'email' => 'user_email',
'name' => 'full_name',
]);
User has many Posts), use mapRelation():
DBImporter::import($file)
->toModel(Post::class)
->mapRelation('user_id', function ($row) {
return User::where('email', $row['author_email'])->first()->id;
});
DBImporter::import($file)
->chunk(500) // Adjust based on server limits
->queue();
php artisan queue:work --sleep=3 --tries=3
For Redis:
php artisan queue:work redis --sleep=3 --tries=3
@import('db-importer::progress')
Pass the import ID to track:
return view('import.progress', ['importId' => $import->id]);
Import model to dispatch events:
class Import extends \VijayTomar\DBImporter\Models\Import {
protected $dispatchesEvents = [
'progress' => \VijayTomar\DBImporter\Events\ImportProgress::class,
];
}
DBImporter::import($file)
->validate(function ($row) {
if (empty($row['email'])) {
throw new \Exception("Email is required.");
}
});
DBImporter::import($file)
->logErrors();
Queue Stuck Jobs:
php artisan queue:retry all
database driver).Memory Limits:
memory_limit. Start with chunk(100) and adjust.PhpSpreadsheet’s setReadDataOnly(true) to reduce memory usage:
DBImporter::import($file)->useReadDataOnly(true);
Timezone Issues:
mapColumns:
->mapColumns(['created_at' => function ($date) {
return Carbon::parse($date)->setTimezone('UTC');
}]);
Relation Mismatches:
mapRelation() fails silently, add debug logging:
->mapRelation('user_id', function ($row) {
$user = User::where('email', $row['author_email'])->first();
if (!$user) {
\Log::warning("No user found for email: {$row['author_email']}");
}
return $user->id;
});
Enable Query Logging:
Add to AppServiceProvider:
public function boot() {
if (app()->environment('local')) {
DB::enableQueryLog();
}
}
Check logs after failed imports:
\Log::info('Last query:', ['queries' => DB::getQueryLog()]);
Test with Small Files: Use a 10-row CSV to validate mappings before processing large datasets.
Custom Storage: Override the default storage path in config:
'storage' => storage_path('app/imports'),
Post-Import Actions:
Hook into the imported event:
\VijayTomar\DBImporter\Events\ImportCompleted::class => function ($event) {
\Log::info("Import completed for {$event->import->id}");
// Send notification, trigger cleanup, etc.
},
Custom UI: Extend the offcanvas component by publishing views:
php artisan vendor:publish --tag="db-importer-views"
Then modify resources/views/vendor/db-importer/progress.blade.php.
Bulk Operations:
For bulk inserts, use DB::unprepared() or DB::statement() in a custom processor:
DBImporter::import($file)
->processWith(function ($chunk) {
DB::table('users')->insert($chunk->toArray());
});
How can I help you explore Laravel packages today?