Rails DB Migration - Bagaimana Cara Menjatuhkan Meja?


507

Saya menambahkan tabel yang saya pikir akan saya butuhkan, tetapi sekarang tidak lagi berencana menggunakannya. Bagaimana saya harus menghapus tabel itu?

Saya sudah menjalankan migrasi, jadi tabelnya ada di database saya. Kurasa aku rails generate migrationseharusnya bisa menangani ini, tapi aku belum tahu caranya.

Saya sudah mencoba:

rails generate migration drop_tablename

tapi itu baru saja menghasilkan migrasi kosong.

Apa cara "resmi" untuk menjatuhkan meja di Rails?


1
Karena rails generate migrationmemiliki opsi baris perintah untuk membuat kode migrasi untuk membuat tabel, menambahkan atau mengubah kolom, dll., Akan lebih baik jika juga memiliki opsi untuk menjatuhkan tabel - tetapi tidak. Tentu, menulis upbagian itu sederhana - panggil saja drop_table- tetapi downbagian itu, menghasilkan tabel lagi, mungkin tidak selalu begitu sederhana, terutama jika skema tabel yang dimaksud telah diubah oleh migrasi setelah penciptaan awal. Mungkin seseorang harus menyarankan kepada pengembang Rails bahwa menambahkan opsi seperti itu akan menjadi ide yang bagus.
Teemu Leisti

3
@TeemuLeisti Bagaimana kalau hanya menyalin dan menempelkan definisi tabel saat ini dari schema.rb? Saya melakukannya dengan cara ini setiap saat ...
jasoares

1
@ João Soares: Oke, saya kira itu berhasil. Namun, alangkah baiknya jika prosesnya bisa otomatis, sehingga Anda bisa memberikan rakeperintah pembuatan migrasi, dengan nama tabel sebagai parameter, yang akan menghasilkan fungsi updan kebutuhan down.
Teemu Leisti

Jawaban:


647

Anda tidak akan selalu dapat hanya menghasilkan migrasi untuk sudah memiliki kode yang Anda inginkan. Anda dapat membuat migrasi kosong dan mengisinya dengan kode yang Anda butuhkan.

Anda dapat menemukan informasi tentang cara menyelesaikan berbagai tugas dalam migrasi di sini:

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

Lebih khusus, Anda dapat melihat cara menjatuhkan tabel menggunakan pendekatan berikut:

drop_table :table_name

3
Ini juga berhasil bagi saya. Tetapi pada migrasi penuh (menginstal dari awal) tabel sekarang akan dibuat pertama dan kemudian dijatuhkan lagi. Apakah aman untuk menghapus migrasi buat dan lepas di jalan?
Berkel

2
Adakah yang melihat di sini apakah lebih baik untuk menjatuhkan tabel atau kembali ke skema database sebelumnya?
william memberi tahu

3
Jika Anda sudah selesai dengan tabel dan tidak berencana untuk menggunakannya lagi, saya katakan drop saja. Lebih baik menyingkirkannya jika tidak digunakan.
Pete

6
jawaban oleh @BederAcostaBorges lebih jelas dan akurat
onerinas

2
Bagaimana cara menghapus semua kunci asing? Ada kolom di tabel lain yang menunjuk ke tabel yang dijatuhkan.
Martin Konicek

352

Pertama-tama hasilkan migrasi kosong dengan nama apa pun yang Anda inginkan. Sangat penting untuk melakukannya dengan cara ini karena itu menciptakan tanggal yang sesuai.

rails generate migration DropProductsTable

Ini akan menghasilkan file .rb di / db / migrate / seperti 20111015185025_drop_products_table.rb

Sekarang edit file itu agar terlihat seperti ini:

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

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

Satu-satunya hal yang saya tambahkan adalah drop_table :productsdan raise ActiveRecord::IrreversibleMigration.

Kemudian jalankan rake db:migratedan itu akan menjatuhkan meja untuk Anda.


14
Migrasi turun harus digunakan untuk membuat ulang tabel yang sedang dijatuhkan.
fflyer05

1
Migrasi ini tidak akan pernah bisa dibatalkan, bahkan dalam pengembangan. Apakah lebih baik membiarkan migrasi turun kosong?
mhriess

1
Ini adalah jawaban yang lebih baik + komentar fflyer
Zack Shapiro

2
@ mjnissim dan fflyer05 benar, untuk menghindari hal-hal aneh, Anda harus membuat ulang tabel dengan metode down.
Sebastialonso

5
Menjatuhkan tabel menghapus semua data, jika Anda membuatnya kembali dalam downmetode, Anda tidak akan memulihkannya sehingga itu sebenarnya tidak benar-benar memutar kembali. Lebih baik menunjukkan dengan jelas bahwa migrasi tidak dapat diubah daripada memberikan pengertian yang salah bahwa migrasi dapat dipulihkan.
vivi

314

Tulis migrasi Anda secara manual. Misal lari rails g migration DropUsers.

Sedangkan untuk kode migrasi saya hanya akan mengutip daftar periksa Rails Migration posting Maxwell Holder

BURUK - berjalan rake db:migratedan kemudian rake db:rollbackakan gagal

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

BAIK - mengungkapkan maksud bahwa migrasi tidak boleh dibalik

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

  def down
    fail ActiveRecord::IrreversibleMigration
  end
end

LEBIH BAIK - sebenarnya bisa dibalik

class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users do |t|
      t.string :email, null: false
      t.timestamps null: false
    end
  end
end

Jika Anda memotong dan menempelkan ke blok schema.rb, jangan lupa juga mencari schema.rbkunci asing. Kemudian tambahkan definisi kunci asing ke drop_tableblok, misalnya:t.foreign_key "other_table"
Lencho Reyes

197

Sementara jawaban yang diberikan di sini berfungsi dengan baik, saya menginginkan sesuatu yang lebih 'langsung', saya menemukannya di sini: tautan Pertama masuk ke konsol rel:

$rails console

Kemudian ketikkan:

ActiveRecord::Migration.drop_table(:table_name)

Dan selesai, bekerja untuk saya!


Model ini masih ada sampai Anda menjalankanrails destroy model User
gm2008

2
Hanya jalankan ini jika Anda ingin menyingkirkan meja untuk selamanya. Rails tidak akan menyadari penurunan ini. Migrasi rusak setelah menjalankan perintah ini. Tidak dapat MENCIPTAKAN, DROP ... DLL. ERROR SQLite3 :: SQLException: tidak ada tabel seperti itu: akrual: DROP TABLE "sometable"
zee

36

Anda perlu membuat file migrasi baru menggunakan perintah berikut

rails generate migration drop_table_xyz

dan tulis kode drop_table di file migrasi yang baru dibuat (db / migrasi / xxxxxxx_drop_table_xyz) seperti

drop_table :tablename

Atau jika Anda ingin menjatuhkan tabel tanpa migrasi, cukup buka rel dengan

$ rails c

dan jalankan perintah berikut

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

atau Anda dapat menggunakan perintah yang lebih sederhana

ActiveRecord::Migration.drop_table(:table_name)

21
  1. rails g drop_users migrasi
  2. edit migrasi
    class DropUsers < ActiveRecord::Migration
      def change
        drop_table :users do |t|
          t.string :name
          t.timestamps
        end
      end
    end
  1. rake db: bermigrasi

13

Saya pikir, untuk sepenuhnya "resmi", Anda harus membuat migrasi baru, dan meletakkan drop_table di self.up. Metode self.down kemudian harus berisi semua kode untuk membuat ulang tabel secara penuh. Agaknya kode itu hanya bisa diambil dari schema.rb pada saat Anda membuat migrasi.

Tampaknya sedikit aneh, memasukkan kode untuk membuat tabel yang Anda tahu tidak akan Anda perlukan lagi, tetapi itu akan membuat semua kode migrasi lengkap dan "resmi", bukan?

Saya hanya melakukan ini untuk meja saya harus turun, tapi jujur ​​tidak menguji "turun" dan tidak yakin mengapa saya melakukannya.


1
Aneh tapi sepertinya aku harus melakukan ini juga.
digitalWestie

7
Atau Anda bisa menggunakan: raise ActiveRecord::IrreversibleMigrationdalam metode self.down, sehingga Anda di LEAST memberi kesalahan / pemberitahuan kepada diri sendiri jika Anda pernah mencoba untuk mengembalikan.
Steph Rose

1
Saya akan menguji turun hanya karena kalau tidak saya memperkenalkan kode yang belum diuji ke proyek saya. Bagaimana saya bisa menggunakan kembali metode migrasi asli? Saya sudah mencoba CreateMyTable.updan di ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, X)mana X adalah migrasi yang awalnya membuat tabel, tetapi tidak berhasil - dalam kedua pendekatan, AR pertama memeriksa apakah migrasi sudah diterapkan, dan diam-diam melewatkannya jika sudah. `
Isaac Betesh

12

Anda cukup menjatuhkan meja dari konsol rel. pertama buka konsol

$ rails c

lalu tempel perintah ini di konsol

ActiveRecord::Migration.drop_table(:table_name)

ganti table_name dengan tabel yang ingin Anda hapus.

Anda juga dapat menjatuhkan tabel langsung dari terminal. cukup masukkan di direktori root aplikasi Anda dan jalankan perintah ini

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

10

Cara yang sederhana dan resmi adalah:

  rails g migration drop_tablename

Sekarang pergi ke db / bermigrasi Anda dan cari file Anda yang berisi drop_tablename sebagai nama file dan edit untuk ini.

    def change
      drop_table :table_name
    end

Maka Anda harus lari

    rake db:migrate 

di konsol Anda.


9

Anda dapat mengembalikan migrasi seperti yang ada dalam panduan:

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

Hasilkan migrasi:

rails generate migration revert_create_tablename

Tulis migrasi:

require_relative '20121212123456_create_tablename'

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

Dengan cara ini Anda juga dapat mengembalikan dan dapat digunakan untuk mengembalikan migrasi apa pun


8

Alternatif untuk meningkatkan pengecualian atau mencoba untuk membuat ulang tabel yang sekarang kosong - sambil tetap mengaktifkan rollback migrasi, ulang, dll -

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

8

Saya tidak dapat membuatnya bekerja dengan skrip migrasi jadi saya melanjutkan dengan solusi ini. Masuk ke konsol rel menggunakan terminal:

rails c

Tipe

ActiveRecord::Migration.drop_table(:tablename)

Ini bekerja dengan baik untuk saya. Ini akan menghapus tabel sebelumnya. Jangan lupa lari

rails db:migrate


4

ActiveRecord::Base.connection.drop_table :table_name


2

Saya perlu menghapus skrip migrasi kami bersama dengan tabel itu sendiri ...

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

dari terminal window run:

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

atau

$ rails runner "Util::Table.clobber_all"

1

cara terbaik yang dapat Anda lakukan adalah

rails g migration Drop_table_Users

kemudian lakukan hal berikut

rake db:migrate

1

Lari

rake db:migrate:down VERSION=<version>

Di mana <version>nomor versi file migrasi Anda ingin dikembalikan.

Contoh:-

rake db:migrate:down VERSION=3846656238

1

kalau ada yang mencari cara melakukannya di SQL.

ketik rails dbconsoledari terminal

Masukkan kata kunci

Di konsol lakukan

USE db_name;

DROP TABLE table_name;

exit

Tolong jangan lupa untuk menghapus file migrasi dan struktur tabel dari skema


Anda juga dapat membukanya dengan mengetik sajarails db
ARK

0

jika Anda ingin menjatuhkan tabel tertentu yang dapat Anda lakukan

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

jika tidak, jika Anda ingin menghapus semua basis data yang dapat Anda lakukan

$rails db:drop

-1

Drop Table / Migrasi

jalankan: - $ rails menghasilkan DropTablename migrasi

exp: - $ rails menghasilkan DropProducts migrasi


-1

Jalankan perintah ini: -

rails g migration drop_table_name

kemudian:

rake db:migrate

atau jika Anda menggunakan basis data MySql maka:

  1. login dengan database
  2. show databases;
  3. show tables;
  4. drop table_name;

3
Apakah jawaban ini menambahkan sesuatu ke jawaban yang ada dan diterima? Jika tidak, tidak perlu memposting ini.
Tom Lord

1
ini menciptakan migrasi kosong di rel 4.2, seperti yang sudah dinyatakan dalam pertanyaan itu sendiri.
bert bruynooghe

Ini PERSIS apa yang awalnya dicoba OP ... jawaban ini harus dihapus
webaholik

Menambahkan jawaban sederhana tidak pantas di-downvotasikan. Masih relevan, saya kira. Tolong berbaik hati kepada pengguna yang lebih baru.
BAHKAN

-2

Jika Anda ingin menghapus tabel dari skema melakukan operasi di bawah ini -

rails db:rollback
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.