Rails DB Migration - วิธีวางโต๊ะ?


507

ฉันเพิ่มตารางที่ฉันคิดว่าฉันต้องการ แต่ตอนนี้ไม่มีแผนจะใช้อีกต่อไป ฉันจะลบตารางนั้นได้อย่างไร

ฉันได้ทำการย้ายข้อมูลแล้วดังนั้นตารางอยู่ในฐานข้อมูลของฉัน ฉันคิดว่าrails generate migrationน่าจะสามารถรับมือกับสิ่งนี้ได้ แต่ฉันยังไม่เข้าใจวิธีการ

ฉันได้พยายาม:

rails generate migration drop_tablename

แต่นั่นเพิ่งสร้างการโยกย้ายที่ว่างเปล่า

วิธี "เป็นทางการ" ในการวางโต๊ะใน Rails คืออะไร?


1
เนื่องจากrails generate migrationมีตัวเลือกบรรทัดคำสั่งสำหรับการสร้างรหัสการย้ายข้อมูลสำหรับการสร้างตารางการเพิ่มหรือการเปลี่ยนคอลัมน์ ฯลฯ มันจะดีถ้ามันมีตัวเลือกสำหรับการวางตาราง - แต่มันไม่มี แน่นอนว่าการเขียนupส่วนนั้นเป็นเรื่องง่าย - เพียงแค่โทรdrop_table- แต่downส่วนที่สร้างตารางอีกครั้งอาจไม่ใช่เรื่องง่ายเสมอไปโดยเฉพาะอย่างยิ่งหากสคีมาของตารางที่เป็นปัญหาถูกเปลี่ยนโดยการย้ายข้อมูลหลังจากการสร้างครั้งแรก บางทีใครบางคนควรแนะนำนักพัฒนาของ Rails ว่าการเพิ่มตัวเลือกดังกล่าวอาจเป็นความคิดที่ดี
Teemu Leisti

3
@TeemuLeisti ลองคัดลอกและวางนิยามตารางปัจจุบันจาก schema.rb ได้อย่างไร ฉันทำอย่างนี้ตลอดเวลา ...
jasoares

1
@ João Soares: ตกลงฉันเดาว่าใช้ได้ อย่างไรก็ตามมันจะดีถ้ากระบวนการนั้นเป็นแบบอัตโนมัติดังนั้นคุณสามารถให้rakeคำสั่งการสร้างการย้ายข้อมูลโดยใช้ชื่อของตารางเป็นพารามิเตอร์ซึ่งจะทำให้เกิดความต้องการupและdownฟังก์ชั่น
Teemu Leisti

คำตอบ:


647

คุณจะไม่สามารถสร้างการโยกย้ายเพื่อให้มีรหัสที่คุณต้องการอยู่แล้ว คุณสามารถสร้างการโยกย้ายที่ว่างเปล่าแล้วเติมด้วยรหัสที่คุณต้องการ

คุณสามารถค้นหาข้อมูลเกี่ยวกับวิธีการทำงานที่แตกต่างในการย้ายข้อมูลได้ที่นี่:

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

โดยเฉพาะอย่างยิ่งคุณสามารถดูวิธีการวางตารางโดยใช้วิธีการต่อไปนี้:

drop_table :table_name

3
มันก็ใช้ได้กับฉันเช่นกัน แต่สำหรับการย้ายข้อมูลเต็มรูปแบบ (ติดตั้งตั้งแต่เริ่มต้น) ตอนนี้ตารางจะถูกสร้างขึ้นเป็นครั้งแรกและหลังจากนั้นจะถูกลบอีกครั้ง ปลอดภัยหรือไม่ที่จะลบการสร้างและปล่อยการย้ายลงที่ถนน?
berkes

2
มุมมองใด ๆ ที่นี่ว่าจะเป็นการดีกว่าถ้าจะวางตารางหรือเปลี่ยนกลับเป็นสกีมาฐานข้อมูลก่อนหน้า
william บอก

3
ถ้าคุณทำเสร็จแล้วกับตารางและไม่ได้วางแผนที่จะใช้อีกต่อไปฉันจะบอกว่าเพียงแค่วางมัน ดีกว่าที่จะกำจัดมันหากไม่ได้ใช้งาน
Pete

6
คำตอบ โดย @BederAcostaBorges เป็นตัวอธิบายและถูกต้องมากขึ้น
2559

2
จะลบคีย์ต่างประเทศทั้งหมดได้อย่างไร มีคอลัมน์ในตารางอื่น ๆ ที่ชี้ไปที่ตารางที่ถูกทิ้ง
Martin Konicek

352

ขั้นแรกสร้างการโยกย้ายที่ว่างเปล่าด้วยชื่อใด ๆ ที่คุณต้องการ สิ่งสำคัญคือต้องทำเช่นนี้เนื่องจากสร้างวันที่เหมาะสม

rails generate migration DropProductsTable

สิ่งนี้จะสร้างไฟล์. rb ใน / db / migrate / like 20111015185025_drop_products_table.rb

ตอนนี้แก้ไขไฟล์นั้นให้มีลักษณะดังนี้:

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

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

สิ่งเดียวที่ฉันเพิ่มคือdrop_table :productsและraise ActiveRecord::IrreversibleMigrationและ

จากนั้นเรียกใช้แล้วrake db:migrateมันจะวางตารางให้คุณ


14
ควรใช้การโยกย้ายลงเพื่อสร้างตารางที่ถูกทิ้ง
fflyer05

1
การโยกย้ายครั้งนี้ไม่สามารถย้อนกลับแม้ในการพัฒนา จะเป็นการดีกว่าหรือไม่ที่จะปล่อยให้การย้ายข้อมูลว่างเปล่า
mhriess

1
นี่คือคำตอบที่ดีกว่า + ความคิดเห็นของ fflyer
Zack Shapiro

2
@mjnissim และ fflyer05 ถูกต้องเพื่อหลีกเลี่ยงสิ่งแปลก ๆ คุณควรสร้างตารางใหม่ในวิธีการลง
Sebastialonso

4
การวางตารางจะลบข้อมูลทั้งหมดหากคุณสร้างขึ้นใหม่ในdownวิธีที่คุณจะไม่กู้คืนดังนั้นจึงไม่ใช่การย้อนกลับที่เหมาะสม เป็นการดีกว่าที่จะระบุอย่างชัดเจนว่าการโยกย้ายนั้นไม่สามารถย้อนกลับไปได้มากกว่าที่จะให้ความรู้สึกผิด ๆ ที่สามารถกู้คืนได้
vivi

314

เขียนการย้ายข้อมูลของคุณด้วยตนเอง เช่นวิ่งrails g migration DropUsersเช่นวิ่ง

สำหรับรหัสของการย้ายถิ่นฉันจะพูดรายการตรวจสอบการย้ายถิ่นของโพสต์ของ Maxwell Holder

BAD - วิ่ง rake db:migrateแล้วrake db:rollbackจะล้มเหลว

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

GOOD - แสดงถึงความตั้งใจที่การโยกย้ายไม่ควรย้อนกลับได้

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

  def down
    fail ActiveRecord::IrreversibleMigration
  end
end

ที่ดีกว่า - สามารถย้อนกลับได้จริง

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

หากคุณกำลังตัดและวางลงในบล็อกschema.rbอย่าลืมค้นหาschema.rbคีย์ต่างประเทศด้วย จากนั้นเพิ่มนิยามคีย์ foreign ไปยังdrop_tableบล็อกเช่น:t.foreign_key "other_table"
Lencho Reyes

197

ในขณะที่คำตอบที่ให้ไว้ที่นี่ทำงานอย่างถูกต้องฉันต้องการบางสิ่งบางอย่าง 'ตรงไปตรงมา' มากกว่าฉันพบได้ที่นี่: ลิงค์ แรกเข้าสู่คอนโซลทางรถไฟ:

$rails console

จากนั้นเพียงพิมพ์:

ActiveRecord::Migration.drop_table(:table_name)

และเสร็จแล้วทำงานให้ฉัน!


รูปแบบยังคงอยู่ที่นั่นจนกว่าคุณจะทำงานrails destroy model User
gm2008

2
เรียกใช้สิ่งนี้เฉพาะในกรณีที่คุณต้องการกำจัดตารางให้ดี Rails จะไม่ทราบว่าหยดนี้ การโอนย้ายใช้งานไม่ได้หลังจากเรียกใช้คำสั่งนี้ ไม่สามารถสร้าง DROP ... ฯลฯ ข้อผิดพลาด SQLite3 :: SQLException: ไม่มีตารางดังกล่าว: เงินคงค้าง: ตารางที่ DROP "someable"
zee

36

คุณต้องสร้างไฟล์การย้ายข้อมูลใหม่โดยใช้คำสั่งต่อไปนี้

rails generate migration drop_table_xyz

และเขียนรหัส drop_table ในไฟล์การโยกย้ายที่สร้างขึ้นใหม่ (db / migration / xxxxxxx_drop_table_xyz) เช่น

drop_table :tablename

หรือถ้าคุณต้องการที่จะวางตารางโดยไม่มีการโยกย้ายเพียงเปิดคอนโซลทางรถไฟ

$ rails c

และดำเนินการคำสั่งต่อไปนี้

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

หรือคุณสามารถใช้คำสั่งที่ง่ายขึ้น

ActiveRecord::Migration.drop_table(:table_name)

21
  1. การโยกย้าย g ทางรถไฟ
  2. แก้ไขการโยกย้าย
    class DropUsers < ActiveRecord::Migration
      def change
        drop_table :users do |t|
          t.string :name
          t.timestamps
        end
      end
    end
  1. rake db: โยกย้าย

13

ฉันคิดว่าการเป็น "สมบูรณ์" คุณจะต้องสร้างการย้ายข้อมูลใหม่และวาง drop_table ใน self.up เมธอด self.down ควรมีรหัสทั้งหมดเพื่อสร้างตารางแบบเต็ม สันนิษฐานว่ารหัสนั้นอาจถูกนำมาจาก schema.rb ในเวลาที่คุณสร้างการย้ายข้อมูล

ดูเหมือนว่าแปลกเล็กน้อยที่จะใส่รหัสเพื่อสร้างตารางที่คุณรู้ว่าคุณไม่ต้องการอีกต่อไป แต่นั่นจะทำให้รหัสการโยกย้ายทั้งหมดเสร็จสมบูรณ์และ "เป็นทางการ" ใช่ไหม

ฉันเพิ่งทำสิ่งนี้สำหรับตารางที่ฉันต้องการวาง แต่โดยสุจริตไม่ได้ทดสอบ "ลง" และไม่แน่ใจว่าทำไมฉันจะ


1
แปลก แต่ดูเหมือนว่าฉันจะต้องทำเช่นนี้ด้วย
digitalWestie

7
หรือคุณสามารถใช้: raise ActiveRecord::IrreversibleMigrationในวิธีการ self.down ดังนั้นคุณอย่างน้อยทำให้เกิดข้อผิดพลาด / ข้อสังเกตถ้าคุณเคยลองย้อนกลับ
Steph Rose

1
ฉันจะทดสอบข้อผิดพลาดเพียงเพราะฉันไม่แนะนำรหัสที่ยังไม่ทดลองในโครงการของฉัน ฉันจะนำวิธีการย้ายข้อมูลเริ่มต้นมาใช้ใหม่ได้อย่างไร ฉันได้ลองCreateMyTable.upและActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, X)ตำแหน่ง X คือการย้ายข้อมูลที่สร้างตาราง แต่ไม่สามารถใช้งานได้ - ในทั้งสองวิธี AR ตรวจสอบก่อนว่ามีการใช้การโยกย้ายแล้วหรือไม่และจะข้ามถ้าไม่มี `
Isaac Betesh

12

คุณสามารถวางตารางจากคอนโซลทางรถไฟ ก่อนเปิดคอนโซล

$ rails c

จากนั้นวางคำสั่งนี้ในคอนโซล

ActiveRecord::Migration.drop_table(:table_name)

แทนที่table_nameด้วยตารางที่คุณต้องการลบ

คุณสามารถวางตารางโดยตรงจากเทอร์มินัล เพียงป้อนในไดเรกทอรีรากของแอปพลิเคชันของคุณและรันคำสั่งนี้

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

10

วิธีที่ง่ายและเป็นทางการคือ:

  rails g migration drop_tablename

ตอนนี้ไปที่ db / migrate ของคุณแล้วค้นหาไฟล์ของคุณที่มี drop_tablename เป็นชื่อไฟล์และแก้ไขมัน

    def change
      drop_table :table_name
    end

จากนั้นคุณต้องเรียกใช้

    rake db:migrate 

บนคอนโซลของคุณ


9

คุณสามารถย้อนกลับการโยกย้ายแบบเดียวกับในคู่มือ:

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

สร้างการโยกย้าย:

rails generate migration revert_create_tablename

เขียนการโยกย้าย:

require_relative '20121212123456_create_tablename'

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

วิธีนี้คุณสามารถย้อนกลับและสามารถใช้เพื่อยกเลิกการย้ายข้อมูลใด ๆ


8

ทางเลือกในการเพิ่มข้อยกเว้นหรือพยายามสร้างตารางว่างในขณะนี้ - ในขณะที่ยังคงเปิดใช้งานการย้อนกลับการย้ายข้อมูลทำซ้ำ ฯลฯ -

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

8

ฉันไม่สามารถทำงานกับสคริปต์การย้ายข้อมูลได้ดังนั้นฉันจึงดำเนินการแก้ไขปัญหาต่อไป เข้าสู่คอนโซลรางโดยใช้เทอร์มินัล:

rails c

ชนิด

ActiveRecord::Migration.drop_table(:tablename)

มันทำงานได้ดีสำหรับฉัน จะเป็นการลบตารางก่อนหน้า อย่าลืมวิ่ง

rails db:migrate



2

ฉันต้องการลบสคริปต์การย้ายข้อมูลของเราพร้อมกับตาราง ...

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

จาก terminal หน้าต่างทำงาน:

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

หรือ

$ rails runner "Util::Table.clobber_all"

1

วิธีที่ดีที่สุดที่คุณสามารถทำได้คือ

rails g migration Drop_table_Users

จากนั้นทำสิ่งต่อไปนี้

rake db:migrate

1

วิ่ง

rake db:migrate:down VERSION=<version>

ที่ไหน <version>หมายเลขเวอร์ชันของไฟล์การโยกย้ายของคุณคุณต้องการเปลี่ยนกลับ

ตัวอย่าง:-

rake db:migrate:down VERSION=3846656238

1

หากใครกำลังมองหาวิธีการทำใน SQL

พิมพ์rails dbconsoleจากเทอร์มินัล

ใส่รหัสผ่าน

ในคอนโซลทำ

USE db_name;

DROP TABLE table_name;

exit

โปรดอย่าลืมลบไฟล์การโยกย้ายและโครงสร้างตารางออกจากสคีมา


คุณสามารถเปิดได้โดยพิมพ์เพียงrails db
ARK

0

ถ้าคุณต้องการวางตารางเฉพาะคุณสามารถทำได้

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

มิฉะนั้นถ้าคุณต้องการที่จะทิ้งฐานข้อมูลทั้งหมดของคุณคุณสามารถทำได้

$rails db:drop

-1

วางตาราง / การย้ายข้อมูล

run: - $ rails สร้างการโยกย้าย DropTablename

exp: - $ rails สร้างการโยกย้าย DropProducts


-1

เรียกใช้คำสั่งนี้: -

rails g migration drop_table_name

แล้ว:

rake db:migrate

หรือถ้าคุณใช้ฐานข้อมูล MySql อยู่:

  1. เข้าสู่ระบบด้วยฐานข้อมูล
  2. show databases;
  3. show tables;
  4. drop table_name;

3
คำตอบนี้เพิ่มสิ่งใด ๆ ลงในคำตอบที่ยอมรับแล้วหรือไม่? ถ้าไม่จำเป็นต้องโพสต์สิ่งนี้
ทอมลอร์ด

1
สิ่งนี้จะสร้างการโยกย้ายที่ว่างเปล่าในราง 4.2 ดังที่ระบุไว้ในคำถามแล้ว
bert bruynooghe

นี่คือสิ่งที่ OP พยายามไว้ในตอนแรก ... คำตอบนี้ควรถูกลบ
webaholik

การเพิ่มคำตอบง่าย ๆ ไม่สมควรถูกลดระดับลง มันยังคงมีความเกี่ยวข้องฉันเดา โปรดเป็นผู้ใช้ใหม่
ARK

-2

หากคุณต้องการลบตารางจากสคีดำเนินการด้านล่าง -

rails db:rollback
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.