inigopascall/clone-db
Laravel artisan command to clone medium/large MySQL databases between connections. Chunks data to avoid memory/packet limits and orders tables by foreign-key dependencies to reduce constraint errors—useful for syncing live data to staging/dev.
Installation
composer require inigopascall/clone-db
Publish Config
php artisan vendor:publish --provider="InigoPascall\CloneDb\CloneDbServiceProvider" --tag="config"
Edit config/clone-db.php to define:
source_connection (e.g., mysql_live)destination_connection (e.g., mysql_staging)batch_size (default: 1000)tables (optional: whitelist/blacklist tables)First Run
php artisan clone-db:run
Verify dependencies are resolved and data integrity is preserved.
Clone a production subset (e.g., users, orders) to staging:
// config/clone-db.php
'tables' => [
'include' => ['users', 'orders'],
'exclude' => ['sensitive_data'],
],
Run:
php artisan clone-db:run --tables=users,orders
Partial Clones
Use --tables flag to sync specific schemas:
php artisan clone-db:run --tables=customers,products
Exclude Tables Skip large tables (e.g., logs) via config:
'exclude' => ['logs', 'audit_trail'],
Batch Optimization
Adjust batch_size for memory constraints (default: 1000):
'batch_size' => 500, // For memory-limited servers
Pre/Post Hooks Extend via service provider:
// app/Providers/CloneDbServiceProvider.php
public function boot()
{
CloneDb::beforeClone(function () {
// Backup destination DB
});
CloneDb::afterClone(function () {
// Run migrations or seeders
});
}
Custom Dependency Ordering Override table ordering logic:
// app/Providers/CloneDbServiceProvider.php
CloneDb::setTableOrderResolver(function ($tables) {
return $this->customOrderLogic($tables);
});
Event Listeners
Listen for clone-db.starting, clone-db.completed:
// app/Listeners/CloneDbLogger.php
public function handle()
{
Log::info('Clone started at: '.now());
}
Foreign Key Loops
A → B → A) will fail.Transaction Limits
max_allowed_packet or transaction timeouts.batch_size or disable transactions:
'disable_transactions' => true,
Case-Sensitive Tables
users ≠ Users.Dry Run Test without writing:
php artisan clone-db:run --dry-run
Verbose Logging Enable debug mode:
php artisan clone-db:run --verbose
Or set in config:
'debug' => env('DB_CLONE_DEBUG', false),
Partial Failures
--skip-failed to continue after errors (destructive).Custom Table Processors Modify how data is inserted:
CloneDb::setTableProcessor(function ($table, $batch) {
// Transform data before insert
return $this->transformBatch($batch);
});
Connection Validation Add pre-clone checks:
CloneDb::beforeClone(function () {
if (!DB::connection('destination')->getPdo()) {
throw new \Exception('Destination DB unavailable');
}
});
Post-Clone Actions Automate post-sync tasks:
CloneDb::afterClone(function () {
Artisan::call('migrate', ['--force' => true]);
});
How can I help you explore Laravel packages today?