我可以将mysql转储导入到laravel迁移吗?

vla*_*zur 33 laravel

我有一个完整的数据库,需要创建迁移.我想必须有一种方法从转储中做到但不确定.有没有办法自动或至少更容易完成这项任务?

Tom*_*ler 43

您可以在Laravel中导入转储,如下所示:

DB::unprepared(file_get_contents('full/path/to/dump.sql'));
Run Code Online (Sandbox Code Playgroud)

但是,如果我要重构现有应用程序,我会花时间从头开始编写迁移,将转储导入不同的表(如果表名相同,则将转储导入到不同的数据库中),然后将内容导入新结构通过种子.

  • 如果文件太大而无法容纳内存怎么办? (2认同)

Kev*_*jan 20

Laravel无法做到这一点,但我认为这将有所帮助:Laravel迁移生成器

它基于现有表生成迁移.

  • 这不再是对L5的支持 (3认同)

sho*_*ild 13

这个问题已经得到解答,但最近在一个项目中,提供的答案不再能满足我的需求.它也不会导入整个数据库转储,而是导入一个(大)表.我觉得我应该和你分享.

问题是,我想在我的工匠期间导入一个非常大的表(zipcodes列表):迁移操作.DB :: unfpared($ dump)的解决方案让位于很长时间,我找到了一个更快的替代方案.

只需将表导出为CSV并在迁移的up()函数中使用以下代码.

    // i had to str_replace the backslash on windows dev system... but works on linux, too
    $filename = str_replace("\\", "/", storage_path('path/in/storage/to/your/file.csv'));

    $query = "LOAD DATA LOCAL INFILE '".$filename."' INTO TABLE yourtable
        FIELDS TERMINATED BY '\t'
        ENCLOSED BY ''
        LINES TERMINATED BY '\n'
        IGNORE 0 LINES
        (col1,col2,...);";

    DB::unprepared($query);
Run Code Online (Sandbox Code Playgroud)

只需根据需要更新查询.当然,你应该确保带有cols'col1','col2'等的表存在.我在导入文件之前创建了它.使用Schema :: create()...

如果您遇到以下错误消息:

PDO::exec(): LOAD DATA LOCAL INFILE forbidden
Run Code Online (Sandbox Code Playgroud)

有一种方法可以摆脱这个消息:虽然它没有真正记录,但你可以在config/database.php文件中添加一个'options'键.例如我的看起来像这样:

        'mysql' => [
        'driver'    => 'mysql',
        'host'      => env('DB_HOST', 'localhost'),
        'database'  => env('DB_DATABASE', 'forge'),
        'username'  => env('DB_USERNAME', 'forge'),
        'password'  => env('DB_PASSWORD', ''),
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
        'strict'    => false,
        'options'   => array(
            PDO::MYSQL_ATTR_LOCAL_INFILE => true,
        )
Run Code Online (Sandbox Code Playgroud)

注意:我目前正在使用laravel 5,但它也适用于laravel 4.

  • 这可能是最好的绝对方式,特别是当数据库变得庞大时 (2认同)

cee*_*yoz 10

我有一个完整的数据库,需要创建迁移.我想必须有一种方法从转储中做到但不确定.有没有办法自动或至少更容易完成这项任务?

不是自动的,但我们使用迁移在迁移中运行转储DB::unprepared().您可以使用file_get_contents.sql文件导入,因此不必担心转义整个转储"标记...

<?php

use Illuminate\Database\Migrations\Migration;

class ImportDump extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        DB::unprepared("YOUR SQL DUMP HERE");
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {

    }

}
Run Code Online (Sandbox Code Playgroud)


zmo*_*eca 9

另一种选择是直接使用 PDO:

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;

$sql_dump = File::get('/path/to/file.sql');
DB::connection()->getPdo()->exec($sql_dump);
Run Code Online (Sandbox Code Playgroud)

  • 指定您建议使用的特定 `File` 类将非常有用。 (2认同)

小智 5

Laravel 5.2中为我工作的另一个解决方案:

DB::unprepared(File::get('full/path/to/dump.sql'));

  • 如果使用phpmyadmin中的转储,它通常包含如下选项:```SET SQL_MODE =“ NO_AUTO_VALUE_ON_ZERO”; SET time_zone =“ +00:00”;```摆脱它,它将起作用 (3认同)

Pra*_*han 5

我正在写我的答案,因为这可能对使用新 laravel 8 的人有所帮助。

在 laravel 8 中,可以使用 SQL(.dump) 文件转储 SQL 并运行迁移。请参阅以下链接了解更多详情。

https://laravel.com/docs/8.x/migrations#squashing-migrations

php artisan schema:dump

// Dump the current database schema and prune all existing migrations...
php artisan schema:dump --prune
Run Code Online (Sandbox Code Playgroud)

schema:dump将在数据库 > 架构下创建新目录,SQL 转储将存储在那里。之后,当您尝试首先迁移时,它将从架构运行转储文件,然后是任何挂起的迁移。

  • 在我最初提出问题七年后。Laravel 8 正确使用 schema:dump (4认同)

Jos*_*a B 3

如果您可以转储为 CSV:某些通用数据表(国家、州、邮政编码)的替代方案,不是通过迁移而是通过播种器。尽管您可以在迁移文件中以相同的方式执行此操作。

在您的播种文件中:

    public function run()
    {
        $this->insertFromCsvFile('countries', 'path/to/countries.csv');
        $this->insertFromCsvFile('states', 'path/to/states.csv');
        $this->insertFromCsvFile('postal_codes', 'path/to/postal_codes.csv');
    }

    private function insertFromCsvFile($tableName, $filePath)
    {
        if( !file_exists($filePath) ){
            echo 'File Not Found: '.$filePath."\r\n";
            return;
        }
        $headers = $rows = [];
        $file = fopen( $filePath, 'r' );
        while( ( $line = fgetcsv( $file ) ) !== false ){

            // The first row should be header values that match column names.
            if( empty( $headers ) ){
                $headers = explode( ',', implode( ',', $line ) );
                continue;
            }

            $row = array_combine( $headers, $line );
            foreach( $row as &$val ) if( $val === 'NULL' ) $val = null;
            $rows[] = $row;

            // Adjust based on memory constraints.
            if( count($rows) === 500 ){
                DB::table( $tableName )->insert($rows);
                $rows = [];
            }
        }
        fclose( $filePath );

        if( count($rows) ) DB::table( $tableName )->insert($rows);
    }
Run Code Online (Sandbox Code Playgroud)

运行播种机:php artisan db:seed --class=GenericTableSeeder