【问题标题】:How to write SQL in a migration in Rails如何在 Rails 的迁移中编写 SQL
【发布时间】:2013-02-13 15:23:08
【问题描述】:

我有以下需要执行的 SQL

CREATE TABLE cars_users2 AS SELECT DISTINCT * FROM cars_users;

DROP TABLE cars_users;

ALTER TABLE cars_users2 RENAME TO cars_users;

因为我不能使用 heroku 数据剪辑来删除表,所以我不能使用数据剪辑。

所以我想我需要在迁移中这样做。

我如何编写这个 sql 作为迁移?

【问题讨论】:

    标签: sql postgresql ruby-on-rails-3 migration rails-activerecord


    【解决方案1】:

    对于您的向上迁移:

    execute "CREATE TABLE cars_users2 AS SELECT DISTINCT * FROM cars_users;" 
    drop_table :car_users  
    rename_table :car_users2, :car_users  
    

    向下:

    raise ActiveRecord::IrreversibleMigration
    

    完全迁移:

    class TheMigration < ActiveRecord::Migration
        def up
            execute "CREATE TABLE cars_users2 AS SELECT DISTINCT * from cars_users;" 
            drop_table :car_users  
            rename_table :car_users2, :car_users  
        end
    
        def down
            raise ActiveRecord::IrreversibleMigration
        end
    end
    

    【讨论】:

      【解决方案2】:

      您可以尝试使用execute 方法。

      类似的东西(未经测试,某种创意)

      class UpdateCarUserTable < ActiveRecord::Migration
        def up
          execute "CREATE TABLE cars_users2 AS SELECT DISTINCT * FROM cars_users"
          execute "DROP TABLE cars_users"
          execute "ALTER TABLE cars_users2 RENAME TO cars_users"
        end
      

      由于没有等效的down 方法,因此在尝试向下迁移时应引发ActiveRecord::IrreversibleMigration

      【讨论】:

        【解决方案3】:

        我更喜欢这里的文档:

        execute <<-SQL
          CREATE TABLE cars_users2 AS SELECT DISTINCT * FROM cars_users;
          DROP TABLE cars_users;
          ALTER TABLE cars_users2 RENAME TO cars_users;
        SQL
        

        注意: 这仅适用于 PostgreSQL,如果您使用 MySQL,则应为适配器设置 CLIENT_MULTI_STATEMENTS

        【讨论】:

        • 你为什么喜欢这个?
        • 设置 CLIENT_MULTI_STATEMENTS 是一个严重的安全风险:SQL 注入。这就是它默认关闭的原因。
        【解决方案4】:

        如果您需要使用change 而不是updown,您可以使用reversible。 它适用于 Rails 4 或更高版本。

        class ExampleMigration < ActiveRecord::Migration
          def change
            create_table :distributors do |t|
              t.string :zipcode
            end
        
            reversible do |dir|
              dir.up do
                # add a CHECK constraint
                execute <<-SQL
                  ALTER TABLE distributors
                    ADD CONSTRAINT zipchk
                      CHECK (char_length(zipcode) = 5) NO INHERIT;
                SQL
              end
              dir.down do
                execute <<-SQL
                  ALTER TABLE distributors
                    DROP CONSTRAINT zipchk
                SQL
              end
            end
        
            add_column :users, :home_page_url, :string
            rename_column :users, :email, :email_address
          end
        end
        

        来源:http://edgeguides.rubyonrails.org/active_record_migrations.html#using-reversible

        https://apidock.com/rails/ActiveRecord/Migration/reversible

        【讨论】:

          猜你喜欢
          • 2020-03-14
          • 1970-01-01
          • 2011-12-12
          • 1970-01-01
          • 2012-01-20
          • 1970-01-01
          • 1970-01-01
          • 2010-10-03
          • 1970-01-01
          相关资源
          最近更新 更多