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

Csv Seeder Laravel Package

flynsarmy/csv-seeder

Seed your Laravel database directly from CSV files with this extension to the built-in seeder. Map columns to table fields, handle large files, and skip writing PHP seed classes by hand—ideal for importing existing data quickly and repeatably.

View on GitHub
Deep Wiki
Context7

Getting Started

Install as a dev dependency and keep CSVs in the repo:

composer require --dev flynsarmy/csv-seeder
mkdir -p database/seeders/csv

Create a seeder that extends Flynsarmy\CsvSeeder\CsvSeeder. The package is configured through public properties on the seeder, not a config file:

<?php

namespace Database\Seeders;

use Flynsarmy\CsvSeeder\CsvSeeder;

class CountriesTableSeeder extends CsvSeeder
{
    public function __construct()
    {
        $this->table = 'countries';
        $this->filename = base_path('database/seeders/csv/countries.csv');
        $this->delimiter = ',';
        $this->timestamps = true;

        // Only needed when seeding a non-default DB connection.
        // v2.0.6 fixes inserts incorrectly going to the default connection.
        // $this->connection = 'mysql_secondary';

        // Use mapping when the CSV has no header or column order differs.
        $this->offset_rows = 1; // skip CSV header row
        $this->mapping = [
            0 => 'iso2',
            1 => 'name',
            2 => 'phone_code',
        ];
    }

    public function run(): void
    {
        parent::run();
    }
}

Run it directly:

php artisan db:seed --class=CountriesTableSeeder

First practical use case: load static lookup data such as countries, currencies, categories, zip codes, or permission lists. It is faster to maintain a spreadsheet export than hundreds of hand-written DB::table()->insert() calls.

Look first at the package README for the full set of supported properties: table, filename, delimiter, timestamps, hashable, mapping, offset_rows, connection, and any version-specific upsert/chunking options. There is no service provider or publishable config to inspect.

Implementation Patterns

Use CSVs as source-of-truth for reference tables. Keep the CSV beside the seeder, review changes in pull requests, and regenerate the table in local/CI environments. This is the package’s sweet spot.

Use explicit mappings for real-world spreadsheet exports. Column order changes when someone inserts a column in Excel. Map indexes to database columns and skip the header with $offset_rows:

$this->mapping = [
    0 => 'code',
    1 => 'label',
    2 => 'sort_order',
];
$this->offset_rows = 1;

If you omit mapping, the package can use the first CSV row as the column names. Pick one convention per project: either header-driven or explicit mapping, not both.

Hash secrets on import. For dev user seeders, keep plaintext passwords in the CSV and let the package hash them:

$this->hashable = ['password'];

Make seeders idempotent. Repeated db:seed runs will hit duplicate-key errors. Wrap with a truncate or use the package’s upsert support if your version documents it:

public function run(): void
{
    DB::connection($this->connection)->statement('SET FOREIGN_KEY_CHECKS=0');
    DB::connection($this->connection)->table($this->table)->truncate();
    DB::connection($this->connection)->statement('SET FOREIGN_KEY_CHECKS=1');

    parent::run();
}

For append-only data, prefer a unique index plus upsert rather than truncate. Truncate resets IDs and can break foreign keys.

Set the connection when seeding a non-default database. On v2.0.6+, set the package’s connection property so inserts, and any wrapping queries you write, target the intended database:

$this->connection = 'reporting';

Use this for tenant databases, read/write splits, or secondary connections. In custom run() logic, consistently use DB::connection($this->connection) rather than the default DB facade.

Tune chunk size for larger files. The package inserts in chunks; if the property exists in your installed version, set it explicitly:

$this->insert_chunk_size = 1000;

Compose seeders from DatabaseSeeder. One seeder per CSV keeps failures isolated:

$this->call([
    CountriesTableSeeder::class,
    CurrenciesTableSeeder::class,
    CategoriesTableSeeder::class,
]);

Guard destructive seeders by environment. Do not let a CSV seeder truncate production tables. Add if (app()->isProduction()) { return; } or keep these seeders out of production deployment scripts.

Override run() for transformations. The package is intentionally thin: it maps columns, optionally hashes and timestamps, then inserts. If you need to trim values, convert booleans, resolve foreign keys, or split fields, override run() and use League\Csv or fgetcsv() directly, or copy the package class into your app and customize it.

Gotchas and Tips

Laravel compatibility still needs checking. The v2.0.6 release is a narrow bugfix for non-default connections, not a guarantee of modern Laravel support. Check composer why-not flynsarmy/csv-seeder before adopting it on Laravel 9/10/11. On incompatible versions, expect to fork the package or write a small custom seeder using League\Csv.

Non-default connections need v2.0.6 or later. Older versions could silently insert into the default connection even when you configured a secondary one. After upgrading, verify both the insert and any custom truncate/delete statements use the same connection.

Excel CSV exports often include a UTF-8 BOM. The first column name can become \ufeffid instead of id. Strip the BOM or export as “CSV UTF-8” carefully. Also normalize CRLF line endings and trailing empty lines.

Mapping mistakes fail late. A missing mapping entry or a column count mismatch usually surfaces as a database “unknown column” or “array to string” error during insert, not during CSV parsing. Test with a 3–5 row CSV before running the full file.

Large CSVs are still memory-heavy. Chunked inserts reduce query size but may not avoid loading the whole file. For hundreds of thousands of rows, prefer a streaming custom seeder, LOAD DATA INFILE, or a dedicated ETL job.

hashable re-hashes on every run. Re-seeding changes passwords and breaks existing logins in shared dev databases. Use it only for seed data you intend to reset.

timestamps = true sets both created_at and updated_at to the current time. You cannot preserve historical timestamps from the CSV through this flag alone; map and insert them yourself if needed.

Foreign keys and seeder order matter. Seed parent tables before children. If you truncate, disable foreign key checks around the operation and re-enable them in a finally block. Ensure this runs on the same connection as the seeded table.

Delimiter is a single character. For tab-separated files use "\t", not "\\t". For semicolon exports set ';'. Quoted fields and escaped quotes are handled by the underlying CSV reader, but malformed rows can shift columns silently.

No config file means no central defaults. Every seeder repeats table, filename, delimiter, and connection. Consider a small base class in your app to set common paths, delimiters, connections, and environment guards.

Debug by narrowing the input. Temporarily point filename at a tiny CSV, dump the mapped row shape with dd() before insert, and check storage/logs/laravel.log. If using --seed, run the specific class with --class to isolate the failing seeder.

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.
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
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle