我的团队的开发人员已经习惯了Laravel迁移的强大功能,他们在本地计算机和我们的开发服务器上工作得很好。 但客户的数据库管理员不接受Laravel迁移。他要求为每个新版本的应用程序提供原始SQL脚本。
是否有任何工具或编程技术可以将Laravel迁移的输出捕获到上/下SQL脚本?
如果我们可以在创建生产构建时在我们的CI系统(TeamCity)中集成SQL脚本生成,那将是完美的。
顺便说一句,我们将在这个项目中使用Laravel 5和PostgreSQL。
答案 0 :(得分:72)
您可以在运行--pretend
时添加php artisan migrate
标志,以便将查询输出到终端:
php artisan migrate --pretend
这看起来像这样:
Migration table created successfully.
CreateUsersTable: create table "users" ("id" integer not null primary key autoincrement, "name" varchar not null, "email" varchar not null, "password" varchar not null, "remember_token" varchar null, "created_at" datetime not null, "updated_at" datetime not null)
CreateUsersTable: create unique index users_email_unique on "users" ("email")
CreatePasswordResetsTable: create table "password_resets" ("email" varchar not null, "token" varchar not null, "created_at" datetime not null)
CreatePasswordResetsTable: create index password_resets_email_index on "password_resets" ("email")
CreatePasswordResetsTable: create index password_resets_token_index on "password_resets" ("token")
要将其保存到文件,只需重定向输出而不用ansi :
php artisan migrate --pretend --no-ansi > migrate.sql
此命令仅包括尚未迁移的迁移。
要进一步自定义如何获取查询,请考虑入侵源代码并制作自己的自定义命令或类似的东西。为了帮助您入门,可以使用以下快速代码来获取所有迁移。
$migrator = app('migrator');
$db = $migrator->resolveConnection(null);
$migrations = $migrator->getMigrationFiles('database/migrations');
$queries = [];
foreach($migrations as $migration) {
$migration_name = $migration;
$migration = $migrator->resolve($migration);
$queries[] = [
'name' => $migration_name,
'queries' => array_column($db->pretend(function() use ($migration) { $migration->up(); }), 'query'),
];
}
dd($queries);
array:2 [
0 => array:2 [
"name" => "2014_10_12_000000_create_users_table"
"queries" => array:2 [
0 => "create table "users" ("id" integer not null primary key autoincrement, "name" varchar not null, "email" varchar not null, "password" varchar not null, "remember_token" varchar null, "created_at" datetime not null, "updated_at" datetime not null)"
1 => "create unique index users_email_unique on "users" ("email")"
]
]
1 => array:2 [
"name" => "2014_10_12_100000_create_password_resets_table"
"queries" => array:3 [
0 => "create table "password_resets" ("email" varchar not null, "token" varchar not null, "created_at" datetime not null)"
1 => "create index password_resets_email_index on "password_resets" ("email")"
2 => "create index password_resets_token_index on "password_resets" ("token")"
]
]
]
此代码将包含所有迁移。要了解如何仅获取尚未迁移的内容,请查看
run()
中的vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php
方法。
答案 1 :(得分:1)
以防你遇到与我一样的问题:
php artisan migrate --pretend
没有输出任何内容,但是在没有将记录添加到迁移的情况下运行SQL。换句话说,
原因是我的设置有几个数据库,用
解决 Schema::connection('master')->create('...
有关该问题的更多信息,请点击此处: https://github.com/laravel/framework/issues/13431
可悲的是,一位Laravel开发者关闭了这个问题,引用" 关闭,因为问题似乎是一个罕见的边缘情况,可以通过解决方法来解决。",所以那里希望不大,很快就会修好。对于我可能罕见的情况,我将使用第三方SQL差异检查器。
干杯
答案 2 :(得分:1)
user2479930的代码很棒,但是我得到了:
Class 'LocalItemsSchema.php' not found
我调试了问题,并使用以下方法解决了该问题:
foreach($migrations as $migration) {
$migration_name = $migration;
$migration_name = str_replace('.php', '', $migration_name);
$migration = $migrator->resolve($migration_name);
$queries[] = [
'name' => $migration_name,
'queries' => array_column($db->pretend(function() use ($migration) { $migration->up(); }), 'query'),
];
}
答案 3 :(得分:0)
在--pretend之后我必须这样做,更改此内容:
CreateTablenameTable: create table `tablename` (`id` bigint unsigned not null auto_increment primary key, `code` varchar(255) not null, `valeur` varchar(255) not null) default character set utf8mb4 collate 'utf8mb4_unicode_ci' engine = InnoDB
CreateTablenameTable: alter table `tablename` add unique `tablename_code_unique`(`code`)
对此:
create table tablename
(
id bigint unsigned not null auto_increment primary key,
code varchar(255) not null,
valeur varchar(255) not null
) default character set utf8mb4 collate 'utf8mb4_unicode_ci' engine = InnoDB;
alter table tablename add unique tablename_code_unique(code);