Migração de banco de dados do Rails - como descartar uma tabela?

507

Adicionei uma tabela que achava que ia precisar, mas agora não pretendo mais usá-la. Como devo remover essa tabela?

Já executei migrações, portanto, a tabela está no meu banco de dados. Eu acho que rails generate migrationdeveria ser capaz de lidar com isso, mas ainda não descobri como.

Eu tentei:

rails generate migration drop_tablename

mas isso apenas gerou uma migração vazia.

Qual é a maneira "oficial" de descartar uma tabela no Rails?

Jason Whitehorn
fonte
1
Como rails generate migrationpossui opções de linha de comando para gerar código de migração para criar tabelas, adicionar ou alterar colunas, etc., seria bom se também houvesse uma opção de descartar uma tabela - mas não. Certamente, escrever a uppeça é simples - basta ligar drop_table- mas a downpeça, gerando a tabela novamente, nem sempre pode ser tão simples, especialmente se o esquema da tabela em questão tiver sido alterado pelas migrações após sua criação inicial. Talvez alguém deva sugerir aos desenvolvedores do Rails que adicionar essa opção seria uma boa ideia.
Teemu Leisti
3
@TeemuLeisti Que tal copiar e colar a definição de tabela atual do schema.rb? Eu fazê-lo desta forma o tempo todo ...
jasoares
1
@ João Soares: OK, acho que funciona. No entanto, seria bom se o processo pudesse ser automatizado, para que você pudesse apenas fornecer um rakecomando de criação de migração, com o nome de uma tabela como parâmetro, que produzisse as funções upe downfunções necessárias .
Teemu Leisti 02/09/2013

Respostas:

647

Você nem sempre poderá simplesmente gerar a migração para já ter o código que deseja. Você pode criar uma migração vazia e preenchê-la com o código necessário.

Você pode encontrar informações sobre como realizar tarefas diferentes em uma migração aqui:

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

Mais especificamente, você pode ver como descartar uma tabela usando a seguinte abordagem:

drop_table :table_name
Pete
fonte
3
Isso funcionou para mim também. Mas nas migrações completas (instalando a partir do zero), a tabela agora será criada primeiro e depois descartada novamente. É seguro remover as migrações de criação e remoção no caminho?
Berkes
2
Alguma visão aqui sobre se é melhor descartar tabelas ou reverter para um esquema de banco de dados anterior?
william disse
3
Se você terminou com a tabela e não planeja usá-la mais, eu diria que basta soltá-la. Melhor se livrar dele se não estiver sendo usado.
Pete
6
resposta por @BederAcostaBorges é mais auto-explicativo e precisas
onerinas
2
Como também remover todas as chaves estrangeiras? Existem colunas em outras tabelas apontando para a tabela sendo descartada.
Martin Konicek
352

Primeiro, gere uma migração vazia com o nome que desejar. É importante fazê-lo dessa maneira, pois cria a data apropriada.

rails generate migration DropProductsTable

Isso irá gerar um arquivo .rb em / db / migrate / like 20111015185025_drop_products_table.rb

Agora edite esse arquivo para ficar assim:

class DropProductsTable < ActiveRecord::Migration
  def up
    drop_table :products
  end

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

A única coisa que adicionei foi drop_table :productse raise ActiveRecord::IrreversibleMigration.

Então corra rake db:migratee isso derrubará a mesa para você.

Brandon O'Rourke
fonte
14
Uma migração inativa deve ser usada para recriar a tabela que está sendo descartada.
precisa saber é o seguinte
1
Essa migração nunca pôde ser revertida, mesmo em desenvolvimento. Seria melhor deixar a migração para baixo em branco?
Mhriess 04/04
1
Este é o comentário a melhor resposta + de fflyer
Zack Shapiro
2
@mjnissim e fflyer05 estão corretos, para evitar qualquer coisa estranha, você deve recriar a tabela no método down.
Sebastialonso
5
Soltar uma tabela exclui todos os dados; se você recriá-la no downmétodo, não a recuperará, para que não seja realmente uma reversão adequada. É melhor indicar claramente que a migração é irreversível do que dar uma falsa sensação de que pode ser recuperada.
vivi
314

Escreva sua migração manualmente. Por exemplo, corra rails g migration DropUsers.

Quanto ao código da migração, vou apenas citar o post do Maxwell Holder Checklist de Migração do Rails

RUIM - executando rake db:migratee depois rake db:rollbackfalhará

class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users
  end
end

BOM - revela intenção de que a migração não deve ser reversível

class DropUsers < ActiveRecord::Migration
  def up
    drop_table :users
  end

  def down
    fail ActiveRecord::IrreversibleMigration
  end
end

MELHOR - é realmente reversível

class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users do |t|
      t.string :email, null: false
      t.timestamps null: false
    end
  end
end
Beder Acosta Borges
fonte
Se você estiver cortando e colando no bloco schema.rb, não se esqueça de procurar também schema.rbchaves estrangeiras. Em seguida, adicione a definição de chave estrangeira ao drop_tablebloco, por exemplo:t.foreign_key "other_table"
Lencho Reyes 02/07/19
197

Enquanto as respostas fornecidas aqui funcionam corretamente, eu queria algo um pouco mais "direto", mas encontrei aqui: link Primeiro, digite o console do rails:

$rails console

Então digite:

ActiveRecord::Migration.drop_table(:table_name)

E pronto, funcionou para mim!

lllllll
fonte
O modelo ainda está lá até que seja executadorails destroy model User
gm2008
2
Só execute isso se você quiser se livrar da tabela para sempre. Os trilhos não terão conhecimento dessa queda. A migração é interrompida após a execução deste comando. Não é possível criar, deixar cair ... ETC Erro SQLite3 :: SQLException: não existe essa tabela: accruals: DROP TABLE "sometable"
zee
36

Você precisa criar um novo arquivo de migração usando o seguinte comando

rails generate migration drop_table_xyz

e escreva o código drop_table no arquivo de migração recém-gerado (db / migration / xxxxxxx_drop_table_xyz) como

drop_table :tablename

Ou, se você quiser descartar a tabela sem migração, basta abrir o console do Rails

$ rails c

e execute o seguinte comando

ActiveRecord::Base.connection.execute("drop table table_name")

ou você pode usar um comando mais simplificado

ActiveRecord::Migration.drop_table(:table_name)
Shahzad Tariq
fonte
21
  1. migração de trilhos drop_users
  2. editar a migração
    class DropUsers < ActiveRecord::Migration
      def change
        drop_table :users do |t|
          t.string :name
          t.timestamps
        end
      end
    end
  1. rake db: migrate
Aashish Saini
fonte
13

Eu acho que, para ser completamente "oficial", você precisaria criar uma nova migração e colocar drop_table em self.up. O método self.down deve conter todo o código para recriar a tabela por completo. Presumivelmente, esse código pode ser obtido do schema.rb no momento em que você cria a migração.

Parece um pouco estranho inserir código para criar uma tabela que você sabe que não precisará mais, mas isso manteria todo o código de migração completo e "oficial", certo?

Eu fiz isso apenas para uma mesa que precisava largar, mas honestamente não testei o "baixo" e não sabia por que.

Francis Potter
fonte
1
Estranho, mas parece que vou ter que fazer isso também.
DigitalWestie
7
Ou você pode simplesmente usar: raise ActiveRecord::IrreversibleMigrationno método self.down, pelo menos você se dará um erro / aviso se tentar reverter.
precisa
1
Eu testaria o down apenas porque, caso contrário, estou introduzindo código não testado em meu projeto. Como posso reutilizar o método ativo da migração original? Eu tentei CreateMyTable.upe ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, X)onde X é a migração que criou originalmente a tabela, mas nenhuma delas funciona - em ambas as abordagens, o AR primeiro verifica se a migração já foi aplicada e, se houver, ignora-a silenciosamente. `
Isaac Betesh
12

você pode simplesmente soltar uma tabela no console do rails. primeiro abra o console

$ rails c

depois cole este comando no console

ActiveRecord::Migration.drop_table(:table_name)

substitua table_name pela tabela que você deseja excluir.

você também pode soltar a tabela diretamente do terminal. basta entrar no diretório raiz do seu aplicativo e executar este comando

$ rails runner "Util::Table.clobber 'table_name'"
Farzpal Singh
fonte
10

A maneira simples e oficial seria esta:

  rails g migration drop_tablename

Agora vá para o seu db / migrate e procure seu arquivo que contém o nome_da_tabl nome do arquivo e edite-o para isso.

    def change
      drop_table :table_name
    end

Então você precisa correr

    rake db:migrate 

no seu console.

Mahesh Mesta
fonte
9

Você pode reverter uma migração da maneira que está no guia:

http://guides.rubyonrails.org/active_record_migrations.html#reverting-previous-migrations

Gere uma migração:

rails generate migration revert_create_tablename

Escreva a migração:

require_relative '20121212123456_create_tablename'

class RevertCreateTablename < ActiveRecord::Migration[5.0]
  def change
    revert CreateTablename    
  end
end

Dessa forma, você também pode reverter e usar para reverter qualquer migração

Matheus Silva
fonte
8

Alternativa para gerar exceção ou tentar recriar uma tabela agora vazia - enquanto ainda permite a reversão da migração, refazer etc. -

def change
  drop_table(:users, force: true) if ActiveRecord::Base.connection.tables.include?('users')
end
aqwan
fonte
8

Como não consegui fazê-lo funcionar com o script de migração, continuei com esta solução. Entre no console de trilhos usando o terminal:

rails c

Tipo

ActiveRecord::Migration.drop_table(:tablename)

Funciona bem para mim. Isso removerá a tabela anterior. Não se esqueça de correr

rails db:migrate
Srikanth V
fonte
7

Abra seu console de trilhos

ActiveRecord::Base.connection.execute("drop table table_name")
manish nautiyal
fonte
4

ActiveRecord::Base.connection.drop_table :table_name

nhegroj
fonte
2

Eu precisava excluir nossos scripts de migração junto com as próprias tabelas ...

class Util::Table < ActiveRecord::Migration

 def self.clobber(table_name)   
    # drop the table
    if ActiveRecord::Base.connection.table_exists? table_name
      puts "\n== " + table_name.upcase.cyan + " ! " 
           << Time.now.strftime("%H:%M:%S").yellow
      drop_table table_name 
    end

    # locate any existing migrations for a table and delete them
    base_folder = File.join(Rails.root.to_s, 'db', 'migrate')
    Dir[File.join(base_folder, '**', '*.rb')].each do |file|
      if file =~ /create_#{table_name}.rb/
        puts "== deleting migration: " + file.cyan + " ! "
             << Time.now.strftime("%H:%M:%S").yellow
        FileUtils.rm_rf(file)
        break
      end
    end
  end

  def self.clobber_all
    # delete every table in the db, along with every corresponding migration 
    ActiveRecord::Base.connection.tables.each {|t| clobber t}
  end

end

a partir da janela do terminal:

$ rails runner "Util::Table.clobber 'your_table_name'"

ou

$ rails runner "Util::Table.clobber_all"
Aaron Henderson
fonte
1

a melhor maneira que você pode fazer é

rails g migration Drop_table_Users

então faça o seguinte

rake db:migrate
Anoob K Bava
fonte
1

Corre

rake db:migrate:down VERSION=<version>

Onde <version>está o número da versão do seu arquivo de migração que você deseja reverter.

Exemplo:-

rake db:migrate:down VERSION=3846656238
Rankit Ranjan
fonte
1

se alguém estiver procurando como fazer isso no SQL.

digite rails dbconsoledo terminal

digite a senha

No console faça

USE db_name;

DROP TABLE table_name;

exit

Não se esqueça de remover o arquivo de migração e a estrutura da tabela do esquema

Shan
fonte
Você também pode abri-lo digitando apenasrails db
ARK
0

se você quiser soltar uma tabela específica, você pode fazer

$ rails db:migrate:up VERSION=[Here you can insert timestamp of table]

caso contrário, se você quiser soltar todo o seu banco de dados, poderá fazer

$rails db:drop
Nicollas
fonte
-1

Eliminar tabela / migração

run: - $ rails gera migração DropTablename

exp: - $ rails gera migração DropProducts

Pankaj Dhote
fonte
-1

Execute este comando: -

rails g migration drop_table_name

então:

rake db:migrate

ou se você estiver usando o banco de dados MySql, então:

  1. login com banco de dados
  2. show databases;
  3. show tables;
  4. drop table_name;
Nitin Rakesh
fonte
3
Essa resposta adiciona algo à resposta existente aceita? Caso contrário, não há necessidade de postar isso.
Tom Lord
1
isso cria uma migração vazia no rails 4.2, como já indicado na própria pergunta.
bert bruynooghe
Este é exatamente o que o OP originalmente tentou ... esta resposta deve ser removido
webaholik
A adição de uma resposta simples não merece voto negativo. Ainda é relevante, eu acho. Seja gentil com os usuários mais novos, por favor.
ARK
-2

Se você deseja excluir a tabela do esquema, execute a operação abaixo -

rails db:rollback
iamnair
fonte