在Rails中显示由挂起的迁移生成的SQL,而无需更新数据库 [英] Show SQL generated by pending migrations in rails without updating the database
问题描述
我希望有一种方法可以生成由rake db:migrate生成的实际sql(即,如果我粘贴到mysql控制台中,它将起作用),而无需实际更新目标数据库。
rake db:migrate:status可以很好地显示给定数据库的哪些迁移正在挂起,但是我还没有找到一种方法来生成实际的SQL。
有什么想法吗?
这可以由Monkey-修补数据库适配器。此示例适用于MySQL。
为 fake db:migrate创建rake任务:
desc打印待执行的迁移期间要执行的所有SQL
task:fake_db_migrate => :environment do
模块ActiveRecord
模块ConnectionAdapters
class AbstractMysqlAdapter< AbstractAdapter
alias_method:real_execute,:execute
def execute(sql,name = nil)
如果sql =〜/ ^ SHOW / || sql =〜/^SELECT.*FROM.*schema_migrations/ || sql =〜/^SELECT.*information_schema/m
real_execute(sql,name)
else
put sql
end
end
结束
结束
结束
Rake :: Task [ db:migrate]。调用
结束
rake任务会在连接适配器中修补 execute
方法,以便打印SQL而不是在实际运行迁移之前执行。但是,我们仍然必须执行 db:migrate
任务使用的一些内部SQL,以获取数据库架构并找出哪些迁移正在挂起。这就是 real_execute
调用的作用。
测试
现在假设,并且我们在 db / migrate / 20160211212415_create_some_table.rb
中有一个待处理的迁移:
class CreateSomeTable< ActiveRecord :: Migration
def change
create_table:some_table do | t |
t.string:string_column,null:false,默认:'ok'
t.timestamps
end
end
end
$ rake db:migrate:status
...
下来20160211212415创建一些表
现在,让我们运行假迁移任务:
$ rake fake_db_migrate
== 20160211212415 CreateSomeTable:正在迁移=== =============================
-create_table(:some_table)
CREATE TABLE`some_table `(ʻid` int(11)auto_increment主键,`string_column` varchar(255)默认'ok'不为空,`created_at`日期时间,ʻupdated_at`日期时间)ENGINE = InnoDB
-> 0.0009s
== 20160211212415 CreateSomeTable:已迁移(0.0010s)========================
开始
插入到``schema_migrations`(`version`)值('20160211212415')
COMMIT
迁移状态尚未更改,即迁移仍在进行中:
$ rake db:migrate:status
...
下来20160211212415创建一些表
在rails 4.2上进行了测试。 3与 mysql2
gem。
I'd like to have a way to produce the actual sql (ie: if I pasted into a mysql console, it would work) that will be generated by a rake db:migrate without actually updating the target database.
rake db:migrate:status does a good job of showing which migrations are pending for a given database, but I've yet to find a way to get the actual SQL produced.
Any ideas?
This can be done by monkey-patching the database adapter. This example works for MySQL.
Create a rake task for "fake db:migrate":
desc "Prints all SQL to be executed during pending migrations"
task :fake_db_migrate => :environment do
module ActiveRecord
module ConnectionAdapters
class AbstractMysqlAdapter < AbstractAdapter
alias_method :real_execute, :execute
def execute(sql, name = nil)
if sql =~ /^SHOW/ || sql =~ /^SELECT.*FROM.*schema_migrations/ || sql =~ /^SELECT.*information_schema/m
real_execute(sql, name)
else
puts sql
end
end
end
end
end
Rake::Task["db:migrate"].invoke
end
The rake task monkey-patches the execute
method in the connection adapter so that SQL is printed instead of being executed, before actually running the migrations. However, we still have to execute some of the internal SQLs that are used by the db:migrate
task to get the database schema and to find out which migrations are pending. That's what the real_execute
call does.
Test
Suppose now that and we have a pending migration in db/migrate/20160211212415_create_some_table.rb
:
class CreateSomeTable < ActiveRecord::Migration
def change
create_table :some_table do |t|
t.string :string_column, null: false, default: 'ok'
t.timestamps
end
end
end
$ rake db:migrate:status
...
down 20160211212415 Create some table
Now, let's run our fake migrations task:
$ rake fake_db_migrate
== 20160211212415 CreateSomeTable: migrating ==================================
-- create_table(:some_table)
CREATE TABLE `some_table` (`id` int(11) auto_increment PRIMARY KEY, `string_column` varchar(255) DEFAULT 'ok' NOT NULL, `created_at` datetime, `updated_at` datetime) ENGINE=InnoDB
-> 0.0009s
== 20160211212415 CreateSomeTable: migrated (0.0010s) =========================
BEGIN
INSERT INTO `schema_migrations` (`version`) VALUES ('20160211212415')
COMMIT
The migrations status has not been changed, i.e. the migration is still pending:
$ rake db:migrate:status
...
down 20160211212415 Create some table
Tested on rails 4.2.3 with the mysql2
gem.
这篇关于在Rails中显示由挂起的迁移生成的SQL,而无需更新数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!