【发布时间】:2014-01-23 11:56:36
【问题描述】:
我有一个完整的数据库,需要创建迁移。我想一定有办法从转储中做到这一点,但不确定。有什么方法可以自动或至少更容易地完成这项任务吗?
【问题讨论】:
标签: laravel
我有一个完整的数据库,需要创建迁移。我想一定有办法从转储中做到这一点,但不确定。有什么方法可以自动或至少更容易地完成这项任务吗?
【问题讨论】:
标签: laravel
你可以像这样在 Laravel 中导入转储:
DB::unprepared(file_get_contents('full/path/to/dump.sql'));
如果我要重构现有应用程序,我会花时间从头开始编写迁移,将转储导入不同的表(或不同的数据库,如果表名相同),然后将内容导入到通过种子的新结构。
【讨论】:
ini_set('memory_limit', '-1')
我正在写我的答案,因为这可能对使用新 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
schema:dump 将在数据库> 架构下创建新目录,并且 SQL 转储将存储在那里。
之后,当您尝试首先迁移时,它将从架构运行转储文件,然后运行任何待处理的迁移。
【讨论】:
另一种选择是直接使用 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);
【讨论】:
File 类将非常有用。
Laravel 文章提供的从现有数据库表生成迁移文件的简单解决方案。
试试:https://laravelarticle.com/laravel-migration-generator-online
【讨论】:
我有一个完整的数据库,需要创建迁移。我想一定有办法从转储中做到这一点,但不确定。有什么方法可以自动完成或至少更容易完成这项任务吗?
不是自动的,但我们使用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()
{
}
}
【讨论】:
这个问题已经回答了,但是最近在一个项目中,提供的答案不再满足我的需求。它也不会导入整个数据库转储,而是导入一个(大)表。我觉得我应该和你分享。
问题是,我想在我的 artisan:migrate 操作期间导入一个相当大的表(邮政编码列表)。 DB::unprepared($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);
只需根据需要更新查询。当然,您应该确保带有 cols 的表 'col1'、'col2' 等......存在。我在导入文件之前创建了它。使用 Schema::create()...
如果您遇到以下错误消息:
PDO::exec(): LOAD DATA LOCAL INFILE forbidden
有一种方法可以消除此消息:虽然它没有真正记录在案,但您可以在 config/database.php 文件中添加一个“选项”键。例如我的看起来像这样:
'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,
)
注意:我目前使用的是 laravel 5,但它也应该适用于 laravel 4。
【讨论】:
LOAD DATA LOCAL INFILE会失败。
在 Laravel 5.2 中为我工作的另一个解决方案:
DB::unprepared(File::get('full/path/to/dump.sql'));
【讨论】:
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; 摆脱它,它会工作
Laravel 无法做到这一点,但我认为这会有所帮助:Laravel migration generator
它根据现有表生成迁移。
【讨论】:
您可以使用 https://github.com/XCMer/larry-four-generator 直接从数据库创建 laravel 迁移和模型
安装包后执行以下代码
php artisan larry:fromdb
【讨论】:
我最近站在同样的问题面前。我不想专门为此安装一个包,所以我决定写一个小工具来帮助我和其他人;)
这里是链接: http://laravel.stonelab.ch/sql-seeder-converter/
如果您有任何改进建议或问题,您可以在这里发表评论: http://www.stonelab.ch/en/sql-to-laravel-seeder-converter/
【讨论】:
您可以使用 Raahul/Larryfour 包,Laravel 4 的模型和迁移生成器
安装后,您可以使用命令行从现有数据库创建迁移,如下所示:
php artisan raahul:fromdb --only yourdatabase
您会在 app/migrations/ 文件夹中找到迁移
【讨论】:
如果您可以转储到 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);
}
运行播种机:php artisan db:seed --class=GenericTableSeeder
【讨论】: