我有一个完整的数据库,需要创建迁移.我想必须有一种方法从转储中做到但不确定.有没有办法自动或至少更容易完成这项任务?
Tom*_*ler 43
您可以在Laravel中导入转储,如下所示:
DB::unprepared(file_get_contents('full/path/to/dump.sql'));
Run Code Online (Sandbox Code Playgroud)
但是,如果我要重构现有应用程序,我会花时间从头开始编写迁移,将转储导入不同的表(如果表名相同,则将转储导入到不同的数据库中),然后将内容导入新结构通过种子.
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.
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)
另一种选择是直接使用 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)
小智 5
Laravel 5.2中为我工作的另一个解决方案:
DB::unprepared(File::get('full/path/to/dump.sql'));
我正在写我的答案,因为这可能对使用新 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 转储将存储在那里。之后,当您尝试首先迁移时,它将从架构运行转储文件,然后是任何挂起的迁移。
如果您可以转储为 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
| 归档时间: |
|
| 查看次数: |
45685 次 |
| 最近记录: |