有没有办法获取迁移的create table语句

时间:2013-07-11 15:41:26

标签: ruby-on-rails ruby

我想知道是否有办法获取迁移的create table语句。所以,不要只运行rake db:migrate,如果你可以编写一些东西来调用迁移而不是向上或向下运行,那么能够运行它,而不是创建表,你可以改为创建表语句。

像Createfootable.up这样的东西,如果我想要SQLite或MySQL等的create table语句,能够具体。这可能吗?

1 个答案:

答案 0 :(得分:3)

这是两个不同的问题:

  1. 我可以从迁移生成查询字符串(或一组查询字符串)吗?
  2. 我可以选择在运行迁移时使用哪个适配器(或从中生成查询)吗?
  3. 对这两个问题的简短回答是“是的,你可以”。

    class CreateFoosTable < ActiveRecord::Migration
      def up
        create_table :foo do |t|
          t.int :bar
          t.string :baz
        end
      end
    end
    

    要先回答第二个问题,您可以通过更改用于建立连接的ActiveRecord配置来切换适配器:

    mysql_config = {
      adapter:  "mysql",
      host:     "localhost",
      username: "myuser",
      password: "mypass",
      database: "somedatabase"
    }
    sqlite_config = {
      adapter:  "sqlite",
      database: "path/to/dbfile"      
    }
    
    require "db/migrate/20130711000000_create_foos_table.rb"
    ActiveRecord::Base.establish_connection(mysql_config)
    CreateFoosTable.up      # run against mysql
    ActiveRecord::Base.establish_connection(sqlite_config)
    CreateFoosTable.up      # run against sqlite
    

    现在回答第一个问题,如何生成sql而不是实际执行它?

    最简单的方法是覆盖execute方法以输出传入的内容:

    # replace 'SQLiteAdapter' with AbstractMysqlAdapter to do the same for MySQL
    ActiveRecord::ConnectionAdapters::SQLiteAdapter.class_eval do  
      def execute(sql, name=nil)
        puts sql
      end
    end
    

    运行CreateFoosTable.up现在应该将SQL输出到控制台。如果要将SQL字符串捕获到某个变量,请将puts sql替换为适合您需要的任何逻辑。

    请注意,虽然覆盖execute将适用于create_table,但它无法正确执行修改现有表的工作。这是因为在生成修改SQL之前需要execute来确定现有模式。在这种情况下,您最好先进行别名并在继续之前检查查询是以CREATEALTER还是DROP开头。