我想知道是否有办法获取迁移的创建表语句。因此,不要只运行 rake db:migrate,如果你可以编写一些东西来调用迁移,而不是向上或向下运行,能够运行它,但不是创建表,你可以只获取 create table 语句。
像 Createfootable.up 之类的东西,如果我想要 SQLite 或 MySQL 等的 create table 语句,可以具体说明。这可能吗?
我想知道是否有办法获取迁移的创建表语句。因此,不要只运行 rake db:migrate,如果你可以编写一些东西来调用迁移,而不是向上或向下运行,能够运行它,但不是创建表,你可以只获取 create table 语句。
像 Createfootable.up 之类的东西,如果我想要 SQLite 或 MySQL 等的 create table 语句,可以具体说明。这可能吗?
这是两个独立的问题:
对这两个问题的简短回答是“是的,你可以”。
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
,然后再继续。ALTER
DROP