Di chuyển DB Rails - Làm thế nào để thả bảng?


507

Tôi đã thêm một bảng mà tôi nghĩ rằng tôi sẽ cần, nhưng bây giờ không còn kế hoạch sử dụng nó nữa. Làm thế nào tôi nên loại bỏ bảng đó?

Tôi đã chạy di chuyển, vì vậy bảng nằm trong cơ sở dữ liệu của tôi. Tôi rails generate migrationcó thể xử lý việc này, nhưng tôi chưa tìm ra cách nào.

Tôi đã thử:

rails generate migration drop_tablename

nhưng điều đó chỉ tạo ra một cuộc di cư trống rỗng.

Cách "chính thức" để thả bảng trong Rails là gì?


1
rails generate migrationcó các tùy chọn dòng lệnh để tạo mã di chuyển để tạo bảng, thêm hoặc thay đổi cột, v.v., sẽ rất tuyệt nếu nó cũng có tùy chọn bỏ bảng - nhưng không được. Chắc chắn, viết upphần rất đơn giản - chỉ cần gọi drop_table- nhưng downphần, tạo lại bảng, có thể không phải lúc nào cũng đơn giản, đặc biệt là nếu lược đồ của bảng được đề cập đã bị thay đổi bởi quá trình di chuyển sau khi tạo ban đầu. Có lẽ ai đó nên đề xuất với các nhà phát triển của Rails rằng thêm một tùy chọn như vậy sẽ là một ý tưởng tốt.
Teemu Leisti

3
@TeemuLeisti Làm thế nào về việc chỉ sao chép và dán định nghĩa bảng hiện tại từ lược đồ.rb? Tôi làm theo cách này mọi lúc ...
jasoares

1
@ João Soares: OK, tôi đoán là nó hoạt động. Tuy nhiên, thật tuyệt nếu quy trình có thể được tự động hóa, do đó bạn chỉ cần đưa rakera lệnh tạo di chuyển, với tên của bảng là tham số, sẽ tạo ra các hàm updownhàm cần thiết .
Teemu Leisti

Câu trả lời:


647

Bạn sẽ không thể luôn luôn có thể tạo di chuyển để có mã bạn muốn. Bạn có thể tạo một di chuyển trống và sau đó điền nó với mã bạn cần.

Bạn có thể tìm thấy thông tin về cách hoàn thành các nhiệm vụ khác nhau trong quá trình di chuyển tại đây:

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

Cụ thể hơn, bạn có thể xem cách thả bảng bằng cách tiếp cận sau:

drop_table :table_name

3
Điều này làm việc cho tôi quá. Nhưng khi di chuyển đầy đủ (cài đặt từ đầu), bảng sẽ được tạo trước và sau đó được bỏ lại. Có an toàn để loại bỏ việc tạo và thả di chuyển xuống đường không?
berkes

2
Bất kỳ quan điểm nào ở đây về việc tốt hơn là bỏ bảng hoặc hoàn nguyên về lược đồ cơ sở dữ liệu trước đó?
william kể

3
Nếu bạn đã hoàn thành với bảng và không có kế hoạch sử dụng nó nữa, tôi sẽ nói hãy bỏ nó xuống. Tốt hơn để thoát khỏi nó nếu nó không được sử dụng.
Pete

6
câu trả lời của @BederAcostaBorges tự giải thích và chính xác hơn
onerinas

2
Làm thế nào để loại bỏ tất cả các khóa ngoại? Có các cột trong các bảng khác chỉ vào bảng bị bỏ.
Martin Konicek

352

Đầu tiên tạo một di chuyển trống với bất kỳ tên nào bạn muốn. Điều quan trọng là phải làm theo cách này vì nó tạo ra ngày thích hợp.

rails generate migration DropProductsTable

Điều này sẽ tạo một tệp .rb trong / db / di chuyển / thích 20111015185025_drop_products_table.rb

Bây giờ chỉnh sửa tập tin đó để trông như thế này:

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

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

Điều duy nhất tôi thêm vào là drop_table :productsraise ActiveRecord::IrreversibleMigration.

Sau đó chạy rake db:migratevà nó sẽ thả bàn cho bạn.


14
Di chuyển xuống nên được sử dụng để tạo lại bảng bị loại bỏ.
fflyer05

1
Sự di chuyển này không bao giờ có thể quay trở lại, ngay cả trong quá trình phát triển. Sẽ tốt hơn nếu chỉ để trống di chuyển xuống?
mhriess

1
Đây là câu trả lời tốt hơn + bình luận của fflyer
Zack Shapiro

2
@mjnissim và fflyer05 là chính xác, để tránh mọi điều kỳ lạ, bạn nên tạo lại bảng trong phương thức xuống.
Sebastialonso

4
Việc bỏ một bảng sẽ xóa tất cả dữ liệu, nếu bạn tạo lại nó trong downphương thức bạn sẽ không phục hồi nó để nó không thực sự trở lại đúng. Tốt hơn là chỉ rõ rằng việc di chuyển là không thể đảo ngược hơn là mang lại cảm giác sai lầm rằng nó có thể được phục hồi.
vivi

314

Viết di chuyển của bạn bằng tay. Ví dụ: chạy rails g migration DropUsers.

Đối với mã di chuyển, tôi sẽ trích dẫn Danh sách kiểm tra di chuyển Rails của Maxwell Chủ

BAD - chạy rake db:migratevà sau đó rake db:rollbacksẽ thất bại

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

TỐT - tiết lộ ý định di cư không nên đảo ngược

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

  def down
    fail ActiveRecord::IrreversibleMigration
  end
end

TỐT HƠN - thực sự có thể đảo ngược

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

Nếu bạn đang cắt và dán vào khối từ schema.rb, đừng quên tìm kiếm schema.rbkhóa ngoại. Sau đó thêm định nghĩa khóa ngoại vào drop_tablekhối, ví dụ:t.foreign_key "other_table"
Lencho Reyes

197

Trong khi các câu trả lời được cung cấp ở đây hoạt động chính xác, tôi muốn một cái gì đó "đơn giản hơn", tôi đã tìm thấy nó ở đây: link Đầu tiên nhập bảng điều khiển rails:

$rails console

Sau đó chỉ cần gõ:

ActiveRecord::Migration.drop_table(:table_name)

Và thực hiện, làm việc cho tôi!


Mô hình vẫn ở đó cho đến khi bạn chạyrails destroy model User
gm2008

2
Chỉ chạy cái này nếu bạn muốn thoát khỏi bàn cho tốt. Rails sẽ không biết về sự sụt giảm này. Di chuyển bị hỏng sau khi chạy lệnh này. Không thể TẠO, DROP ... ETC. ERROR SQLite3 :: SQLException: không có bảng như vậy: tích lũy: DROP TABLE "đôi khi"
zee

36

Bạn cần tạo một tệp di chuyển mới bằng lệnh sau

rails generate migration drop_table_xyz

và viết mã drop_table trong tệp di chuyển mới được tạo (db / di chuyển / xxxxxxx_drop_table_xyz) như

drop_table :tablename

Hoặc nếu bạn muốn thả bảng mà không di chuyển, chỉ cần mở bảng điều khiển rails bằng cách

$ rails c

và thực hiện lệnh sau

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

hoặc bạn có thể sử dụng lệnh đơn giản hơn

ActiveRecord::Migration.drop_table(:table_name)

21
  1. đường ray g di chuyển drop_users
  2. chỉnh sửa di chuyển
    class DropUsers < ActiveRecord::Migration
      def change
        drop_table :users do |t|
          t.string :name
          t.timestamps
        end
      end
    end
  1. rake db: di chuyển

13

Tôi nghĩ, để hoàn toàn "chính thức", bạn sẽ cần tạo một di chuyển mới và đặt drop_table trong self.up. Phương thức self.down sau đó sẽ chứa tất cả mã để tạo lại bảng đầy đủ. Có lẽ mã đó chỉ có thể được lấy từ lược đồ.rb tại thời điểm bạn tạo di chuyển.

Có vẻ hơi kỳ lạ, khi đặt mã để tạo bảng bạn biết bạn sẽ không cần nữa, nhưng điều đó sẽ giữ cho tất cả mã di chuyển hoàn chỉnh và "chính thức", phải không?

Tôi chỉ làm điều này cho một bảng tôi cần bỏ, nhưng thực sự tôi đã không kiểm tra "xuống" và không chắc tại sao tôi lại làm vậy.


1
Lạ nhưng có vẻ như tôi cũng sẽ phải làm điều này.
kỹ thuật sốWestie

7
Hoặc bạn chỉ có thể sử dụng: raise ActiveRecord::IrreversibleMigrationtrong phương thức self.down, vì vậy, tại LEAST hãy tự đưa ra lỗi / thông báo nếu bạn từng cố gắng quay lại.
Steph Rose

1
Tôi sẽ kiểm tra xuống chỉ vì nếu không tôi sẽ giới thiệu mã chưa được kiểm tra vào dự án của mình. Làm cách nào tôi có thể sử dụng lại phương thức di chuyển ban đầu? Tôi đã thử CreateMyTable.upActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, X)X là di chuyển ban đầu tạo bảng, nhưng không hoạt động - trong cả hai cách tiếp cận, AR trước tiên kiểm tra xem di chuyển đã được áp dụng chưa, và âm thầm bỏ qua nếu có. `
Isaac Betesh

12

bạn có thể chỉ cần thả một bảng từ bảng điều khiển đường ray. đầu tiên mở giao diện điều khiển

$ rails c

sau đó dán lệnh này trong bàn điều khiển

ActiveRecord::Migration.drop_table(:table_name)

thay thế tên_bảng bằng bảng bạn muốn xóa.

bạn cũng có thể thả bảng trực tiếp từ thiết bị đầu cuối. chỉ cần nhập vào thư mục gốc của ứng dụng của bạn và chạy lệnh này

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

10

Cách đơn giản và chính thức sẽ là:

  rails g migration drop_tablename

Bây giờ, hãy truy cập db / di chuyển của bạn và tìm tệp của bạn chứa drop_tablename làm tên tệp và chỉnh sửa nó thành tệp này.

    def change
      drop_table :table_name
    end

Sau đó, bạn cần phải chạy

    rake db:migrate 

trên bàn điều khiển của bạn.


9

Bạn có thể quay lại di chuyển theo cách trong hướng dẫn:

http://guides.rubyonrails.org/active_record_migations.html#reverting-preingly-migations

Tạo một di chuyển:

rails generate migration revert_create_tablename

Viết di chuyển:

require_relative '20121212123456_create_tablename'

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

Bằng cách này, bạn cũng có thể quay lại và có thể sử dụng để hoàn nguyên bất kỳ di chuyển nào


8

Thay thế cho việc tăng ngoại lệ hoặc cố gắng tạo lại một bảng hiện trống - trong khi vẫn cho phép khôi phục di chuyển, làm lại, v.v.

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

8

Tôi không thể làm cho nó hoạt động với tập lệnh di chuyển nên tôi đã tiếp tục với giải pháp này. Nhập bảng điều khiển đường ray bằng thiết bị đầu cuối:

rails c

Kiểu

ActiveRecord::Migration.drop_table(:tablename)

Nó hoạt động tốt cho tôi. Điều này sẽ loại bỏ bảng trước. Đừng quên chạy

rails db:migrate

7

Mở bảng điều khiển đường ray

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


2

Tôi cần phải xóa các tập lệnh di chuyển của chúng tôi cùng với các bảng ...

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

từ cửa sổ thiết bị đầu cuối chạy:

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

hoặc là

$ rails runner "Util::Table.clobber_all"

1

cách tốt nhất bạn có thể làm là

rails g migration Drop_table_Users

sau đó làm như sau

rake db:migrate

1

Chạy

rake db:migrate:down VERSION=<version>

Trong trường hợp <version>là số phiên bản của tập tin chuyển đổi của bạn, bạn muốn chỉnh sửa.

Thí dụ:-

rake db:migrate:down VERSION=3846656238

1

nếu có ai đang tìm cách làm điều đó trong SQL.

rails dbconsoletừ thiết bị đầu cuối

nhập mật khẩu

Trong giao diện điều khiển làm

USE db_name;

DROP TABLE table_name;

exit

Xin đừng quên xóa tệp di chuyển và cấu trúc bảng khỏi lược đồ


Bạn cũng có thể mở nó bằng cách gõ chỉrails db
ARK

0

nếu bạn muốn bỏ một bảng cụ thể, bạn có thể làm

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

nếu không, nếu bạn muốn bỏ tất cả cơ sở dữ liệu của bạn, bạn có thể làm

$rails db:drop

-1

Thả bảng / Di chuyển

chạy: - $ rails tạo di chuyển DropTablename

exp: - $ rails tạo di chuyển Drop Products


-1

Chạy lệnh này: -

rails g migration drop_table_name

sau đó:

rake db:migrate

hoặc nếu bạn đang sử dụng cơ sở dữ liệu MySql thì:

  1. đăng nhập với cơ sở dữ liệu
  2. show databases;
  3. show tables;
  4. drop table_name;

3
Câu trả lời này có thêm gì vào câu trả lời hiện có, được chấp nhận không? Nếu không, không cần phải đăng bài này.
Tom Lord

1
điều này tạo ra một sự di chuyển trống trong đường ray 4.2, như đã nêu trong chính câu hỏi.
bert bruynooghe

Đây là chính xác những gì OP ban đầu đã cố gắng ... câu trả lời này nên được gỡ bỏ
webaholik

Thêm một câu trả lời đơn giản không đáng bị đánh giá thấp. Nó vẫn còn liên quan, tôi đoán vậy. Hãy tử tế với người dùng mới hơn xin vui lòng.
ARK

-2

Nếu bạn muốn xóa bảng khỏi lược đồ, hãy thực hiện thao tác bên dưới -

rails db:rollback
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.