【问题标题】:Laravel 4 Seeding many rows, artisan stopsLaravel 4播种多行,工匠停止
【发布时间】:2014-05-04 13:58:51
【问题描述】:

我正在将一个非常旧的项目迁移到 laravel,我考虑将包含旧内容的数据库播种到新数据库中。

这是我如何为我的一张表执行此操作的示例:

<?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);
        }


    }
}

在我的 DatabaseSeeder.php 中有:

<?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
    }

}

问题是,当我执行 php artisan migrate:refresh --seed 时,我完成了迁移和第一个表的种子消息(它只有 8 行),但没有别的。该命令似乎在一段时间后停止,第二个表(调用)只会从我的旧表中获取一些值。似乎它有一个运行时间来阻止它对所有行进行循环,但我没有看到任何消息,它只是简单地停止,当我检查数据库时,除了插入的行数之外,一切似乎都是正确的(我错过了几千,这是一个大型数据库)。

也许这不应该是这样做的方式,但到目前为止,它似乎对这项工作有效,除了这个问题。如何让命令运行更长时间?

【问题讨论】:

    标签: php mysql laravel laravel-4


    【解决方案1】:

    您可能有一些超时...您可以尝试在 PHP 超时 set_time_limit(3600);(1 小时)中增加更多时间,但如果这还不够,它会更难(也许在您的数据库“is_migrated”,并使用队列系统)

    只是出于好奇,一个简单的解决方案,比如

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

    不工作?它应该真的更快...

    【讨论】:

    • 我更喜欢使用种子方法,这样我可以在需要时轻松回滚并从迁移中受益。不过,时间限制建议确实有所帮助。我在 php.ini 中对其进行了更改,现在它可以正常工作了,谢谢。
    【解决方案2】:

    要查找发生了什么,为什么不抛出错误? 尝试将您的代码放入事务中,所有魔法都会为您发生...

    DB::transaction(function(){
    
     //transaction_code_here
    
     });
    

    顺便说一句,迁移完成后,您可以通过以下方式运行您想要的特定种子:

    php artisan db:seed --class=CallsTableSeeder 
    

    您可以截断 Calls 表,以便清理它并重置自动增量!

    意味着将您的代码更改为:

    <?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
    
    
    
        }
    }
    

    然后你就可以运行我上面写的 artisan 命令了,这将:

    1- 截断(“重置”)你“调用”表

    2- 运行插入 DB::table('calls')->insert($calls); 在事务内部,这样它不仅不会在发生错误时提交更改,而且会在发生错误时抛出异常!

    希望这会有所帮助!

    干杯!

    【讨论】:

    • 我尝试为这张桌子运行种子,但问题仍然存在,我也会尝试你的其他建议。
    • migrate:refresh --seed 命令与您的代码之前的工作方式完全相同,但是当它单独运行时,它确实给了我一个错误:无法截断外键约束中引用的表,所以我猜我无法截断表格?
    猜你喜欢
    • 2014-12-19
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 2015-05-24
    • 2013-08-24
    • 1970-01-01
    相关资源
    最近更新 更多