web-dev-qa-db-fra.com

Comment écrire du SQL dans une migration en Rails

J'ai le SQL suivant que je dois faire

CREATE TABLE cars_users2 AS SELECT DISTINCT * FROM cars_users;

DROP TABLE cars_users;

ALTER TABLE cars_users2 RENAME TO cars_users;

comme je ne peux pas utiliser les clips de données heroku pour supprimer une table, je ne peux pas utiliser les clips de données.

Je suppose donc que je dois le faire dans une migration.

Comment écrire ce sql en tant que migration?

51
Nick Ginanto

Pour votre migration vers le haut:

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

et pour le duvet:

raise ActiveRecord::IrreversibleMigration

Migration complète:

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
98
Tomdarkness

Vous pouvez essayer d'utiliser la méthode execute .

Quelque chose comme ça (ce n'est pas testé, une sorte de création)

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

Comme il n'y a pas de méthode down équivalente, une ActiveRecord::IrreversibleMigration devrait être relevé lors de la migration vers le bas.

17
ConcurrentHashMap

Je préfère ici doc:

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

remarque: Cela ne fonctionne que pour PostgreSQL, si vous utilisez MySQL, vous devez définir CLIENT_MULTI_STATEMENTS = pour l'adaptateur.

5
fangxing

Si vous devez utiliser change au lieu de up et down, vous pouvez utiliser reversible. Il fonctionne sur Rails 4 ou supérieur.

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

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

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

4