1

移行用の create table ステートメントを取得する方法があるかどうか疑問に思っています。したがって、単に rake db:migrate を実行する代わりに、移行を呼び出す何かを記述でき、アップまたはダウンを実行する代わりにそれを実行できる場合、テーブルを作成する代わりに、代わりに create table ステートメントを取得することができます。

Createfootable.up のようなもので、SQLite や MySQL などの create table ステートメントが必要かどうかを指定できます。これは可能ですか?

4

1 に答える 1

3

これらは 2 つの別々の質問です。

  1. 移行からクエリ文字列 (またはクエリ文字列のセット) を生成できますか?
  2. 移行を実行する (または移行からクエリを生成する) ときに使用するアダプターを選択できますか?

これらの両方に対する簡単な答えは、「はい、できます」です。

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

最初に 2 番目の質問に答えるには、接続を確立するために使用する 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 を実行する代わりに、どのように 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を生成する前に、既存のスキーマを特定する必要があるためです。この場合、続行する前に、クエリがCREATEALTER、またはで始まるかどうかをエイリアシングして確認することをお勧めします。DROP

于 2013-07-11T16:09:45.987 に答える