我想知道是否有办法获取迁移的create table语句。所以,不要只运行rake db:migrate,如果你可以编写一些东西来调用迁移而不是向上或向下运行,那么能够运行它,而不是创建表,你可以改为创建表语句。
像Createfootable.up这样的东西,如果我想要SQLite或MySQL等的create table语句,能够具体。这可能吗?
答案 0 :(得分: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
来确定现有模式。在这种情况下,您最好先进行别名并在继续之前检查查询是以CREATE
,ALTER
还是DROP
开头。