nwidart/db-exporter
Laravel package for exporting databases to files or Laravel storage. Driver-based, with support for MySQL, PostgreSQL, SQLite, and more, plus chunked exports, configurable options, and Artisan command integration for quick backups.
This is a Laravel 4.2/5.0–5.1-era package: register it manually (no package discovery), publish its config, then run the export command against a scratch database before you ever point it at something you care about.
composer require nwidart/db-exporter will either fail resolution or install code that breaks at runtime — plan on a throwaway Laravel 5.1 project or a container if you just need the generated files.config/app.php:
'providers' => [
// ...
Nwidart\DbExporter\DbExporterServiceProvider::class,
],
and, only if you want programmatic access, the alias:
'aliases' => [
'DbExporter' => Nwidart\DbExporter\Facades\DbExporter::class,
],
php artisan vendor:publish --provider="Nwidart\DbExporter\DbExporterServiceProvider"
php artisan list db
php artisan help db:export
The two entry points are db:export (schema → migrations, and the data/seeder export) and db:sync (push the generated files to the remote server configured in config/db-exporter.php).database.connections entry at a legacy/undocumented database, run php artisan db:export, and read the generated files in database/migrations. That first dump is usually 80% right — your job is the remaining 20% (types, keys, ordering).Bootstrapping a legacy database into a greenfield Laravel app. This is the single best reason to reach for the package. Dump the old schema into migrations, commit them, then delete the export tooling from composer.json. From that point the app owns its schema history normally.
Filter aggressively, don't export everything. A 200-table legacy DB produces a wall of migrations you will never read. Use the config ignore list (and the table-filter option on the command) to skip migrations, sessions, cache, jobs, password_resets, log/audit tables and anything owned by a third-party tool. Export in batches: one run for users/accounts, one for billing, one for content. Small, reviewable batches are the whole game.
Treat migrations as generated artifacts, then hand-finish them. The workflow that actually holds up:
php artisan db:export
# review in git diff — never run blind
php artisan migrate:fresh
php artisan db:export --data # or the seed-export command
git add database/migrations database/seeds
git commit -m "chore: baseline schema from legacy DB"
Then fix the generated files in place: add ->nullable(), ->default(), ->unsigned(), indexes, and the foreign keys the exporter didn't infer. Re-export from a clean DB once more afterwards and diff — anything that changes is something you'd otherwise discover in production.
Data export for lookup/fixture tables only. The seeder export is genuinely useful for countries, currencies, roles, permissions, settings — small, stable, and painful to hand-write. Wire it up as a normal seeder and call it from DatabaseSeeder. Do not export users, orders, or anything with PII into a file that gets committed; see the gotchas.
Fresh-install and CI loops. Once the schema lives as migrations and the reference data as seeders, the standard php artisan migrate:fresh --seed works exactly as it should — that's the payoff. Run it in CI on every PR against an empty MySQL/Postgres container to prove the baseline still boots from zero.
Remote sync as a stopgap, not a deploy strategy. db:sync exists so you can push freshly generated migrations/seeders to a box you only have SSH access to. Use it for one-off staging refreshes where you don't have a deploy pipeline, and put the credentials in .env rather than the config file. The moment you have Git + a deploy tool, drop db:sync — committing the files and deploying is safer and auditable.
Programmatic use. The facade (DbExporter::…) is handy in a custom artisan command or tinker when you want a one-off export of a single connection or table without shelling out. Wrap it in your own command so the arguments are documented in your repo, not in this package's README.
each(), mysql_*-era idioms, and un-namespaced facades. On PHP 7.2+ it will throw at runtime; on PHP 8 it won't even parse cleanly. Budget time for it, or use it as a one-off and remove it.enum, json/jsonb, geometry, point, unsigned, zerofill, generated/virtual columns, and column DEFAULT expressions commonly come out as generic strings or lose their modifiers. Always diff SHOW CREATE TABLE against the generated migration for the tables you actually care about.down() is often generic or wrong. migrate:rollback on generated migrations can fail on FK constraints. Verify rollback works on a scratch DB before you trust it.create_users_table migrations. Always clear the generated range (or export to a separate directory via config) before re-running.db:sync overwrites remote files with no dry run. Run it against staging first, keep a backup of the remote database/ directory, and check git status on the remote (or a find -newer listing) afterwards. There is no conflict detection.config/db-exporter.php; if you change them after installing, php artisan config:clear — cached config is the usual reason "the ignore list doesn't work".-v, and inspect generated files before migrate. If db:export silently emits nothing, check the connection name, the ignore list, and that the tables actually exist on the connection the command resolves.kitloong/laravel-migrations-generator for schema → migrations, spatie/laravel-db-snapshots for data dumps, and Git + a real deploy pipeline for what db:sync does.How can I help you explore Laravel packages today?