1

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

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

4

1 回答 1

3

这是两个独立的问题:

  1. 我可以从迁移中生成一个查询字符串(或一组查询字符串)吗?
  2. 我可以在运行迁移(或从中生成查询)时选择要使用的适配器吗?

对这两个问题的简短回答是“是的,你可以”。

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,但它无法正确完成修改现有表的工作。这是因为execute在生成修改 SQL 之前需要确定现有模式。在这种情况下,您最好使用别名并检查查询是否以、 或开头CREATE,然后再继续。ALTERDROP

于 2013-07-11T16:09:45.987 回答