在Rails中显示由挂起的迁移生成的SQL,而无需更新数据库 [英] Show SQL generated by pending migrations in rails without updating the database

查看:51
本文介绍了在Rails中显示由挂起的迁移生成的SQL,而无需更新数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望有一种方法可以生成由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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆