2
votes

I'm working on migrating a really old project to laravel and I thought about seeding the database with my old content to the new database.

Here is an example of how I do this for one of my tables:

<?php

class CallsTableSeeder extends Seeder {

    public function run()
    {
        $hostname = 'localhost';
        $username = 'root';
        $password = 'root';
        $link = mysql_connect($hostname, $username, $password);
        mysql_select_db('olddatabase');

        $callselect = 'SELECT * FROM calls';
        $ressource = mysql_query($callselect);

        $calls = array();

        while($item = mysql_fetch_object($ressource))
        {
            $calls['id']=$item->id;
            $calls['author_name']=$item->author_name;
            $calls['comments']=$item->comment;
            DB::table('calls')->insert($calls);
        }


    }
}

And in my DatabaseSeeder.php I have:

<?php

class DatabaseSeeder extends Seeder {

    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Eloquent::unguard();

        DB::statement('SET FOREIGN_KEY_CHECKS=1;');

        $this->call('MembersTableSeeder');
        $this->command->info('The Members table has been seeded!');
        $this->call('ContactsTableSeeder');
        $this->command->info('The Contacts table has been seeded!');
        $this->call('CallsTableSeeder');
        $this->command->info('The Calls table has been seeded!');
        $this->call('ClientsTableSeeder');
                    //and so on
    }

}

The thing is that when I do php artisan migrate:refresh --seed I get the migrations done and the seed message for the first table (it only has 8 rows in it) but nothing else. The command seems to stop after a while and the second table (Calls) will only get some of the values from my old table. It seems it has a running time that stops it from doing the loop for all the rows, but I see no message whatsoever, it just plains stops and when I check the database everything seems correct except the number of rows inserted (I'm missing a few thousands, it is a large database).

Maybe this isn't supposed to be the way to be doing this but so far it seemed like it worked for the job, except for this issue. How can I run the command for a longer period of time?

2

2 Answers

1
votes

To find what's going on, why dont you have an error thrown?? Try toi put your code inside transaction, and all that magic will happen for you...

DB::transaction(function(){

 //transaction_code_here

 });

And, by the way, after your migration is done, you can just run the specific seed you want by:

php artisan db:seed --class=CallsTableSeeder 

And you can truncate Calls table, so it cleans it and reset autoincrement!

Means changing your code to:

<?php

class CallsTableSeeder extends Seeder {

    public function run()
    {
        $hostname = 'localhost';
        $username = 'root';
        $password = 'root';
        $link = mysql_connect($hostname, $username, $password);
        mysql_select_db('olddatabase');

        $callselect = 'SELECT * FROM calls';
        $ressource = mysql_query($callselect);

        $calls = array();


     DB::table('calls')->truncate(); //ADDED BY ME 

     DB::transaction(function(){ //ADDED BY ME

        while($item = mysql_fetch_object($ressource))
        {
            $calls['id']=$item->id;
            $calls['author_name']=$item->author_name;
            $calls['comments']=$item->comment;
            DB::table('calls')->insert($calls);
        }


     }); //ADDED BY ME



    }
}

And then you can just run the artisan command i wrote above, and this will:

1- truncate ("reset") you "calls" table

2- run your inserts DB::table('calls')->insert($calls); inside a transaction, and this way it will not only not committing changes if a error happens, as well it will throw an exception with the error that happened!

Hope this helps!

Cheers!

0
votes

You must likely have had some timeouts... You can try to add more time to your PHP timeout set_time_limit(3600); (for 1 hour), but if it's not enough it'll be harder (maybe add a field to your database "is_migrated", and use a queue system)

Just out of curiosity, a simple solution like

insert into db2.table1 (field1, field2, field3)
select field1, field2, field3 from db1.table1

doesn't work? It should be really faster...