mardi 25 juillet 2017

Attaching pivots using Laravel model on a different connection

I am trying to copy some data from one database to another (both share the same schema). Both databases share the same host.

In config/database.php I have the following:

/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/

'default' => 'connection1',

/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/

'connections' => [
    'connection1' => [
        'driver'    => 'mysql',
        'host'      => 'host.link.here'
        'database'  => 'db1',
        'username'  => env('DB_USERNAME'),
        'password'  => env('DB_PASSWORD')
    ],

    'connection2' => [
        'driver'    => 'mysql',
        'host'      => 'host.link.here',
        'database'  => 'db2',
        'username'  => env('DB_USERNAME_2'),
        'password'  => env('DB_PASSWORD_2')
    ],
],

I wrote a command to duplicate an experiment from db1 to db2. The relevant part of the code is here:

$experiment = App\Experiment::where('key', 1234)->first();
$connection = 'connection2';

DB::connection($connection)->transaction(function() use ($experiment, $connection) {
        $clone_experiment = $experiment->replicate();
        $clone_experiment->setConnection($connection);
        $clone_experiment->save();

        $this->info('Created experiment on destination DB with ID ' . $clone_experiment->id);

        // Copy objectives
        foreach ($experiment->objectives as $objective) {
            $clone_objective = $objective->replicate();
            $clone_objective->setConnection($connection);
            $clone_objective->save();

            // Attach objective to experiment with pivot data
            $pivot_data = [
                'field_1' => $objective->pivot->field_1,
                'field_2' => $objective->pivot->field_2,
            ];

            $clone_experiment->objectives()->attach([$clone_objective->id => $pivot_data]);
        }
        $this->info('Duplicated objectives');
});

There seems to be an issue with attaching the pivot to the model on db2. I get this output when running the command:

Created experiment on destination DB with ID 3626
Exception: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`db1`.`experiment_objective`, CONSTRAINT `experiment_objective_experiment_id_foreign` FOREIGN KEY (`experiment_id`) REFERENCES `experiments` (`id`) ON DELETE CASCADE) (SQL: insert into `experiment_objective` (`created_at`, `experiment_id`, `objective_id`, `field_1`, `field_2`, `updated_at`) values (2017-07-25 23:54:25, 3626, 4973, 10, exploration, 2017-07-25 23:54:25))

The error indicates that the constraint for db1 is failing, but I do not know why it is looking at that since both $clone_experiment and $clone_objective are using connection2, which connects to db2. Is there any way around this?



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire