Câu hỏi Làm thế nào tôi có thể đổi tên một cột cơ sở dữ liệu trong một di chuyển Ruby on Rails?


Tôi đã đặt tên sai cột hased_password thay vì hashed_password.

Làm cách nào để cập nhật lược đồ cơ sở dữ liệu, sử dụng di chuyển để đổi tên cột này?


1282
2018-01-02 16:18


gốc




Các câu trả lời:


rename_column :table, :old_column, :new_column

Cập nhật:

Có thể bạn sẽ muốn tạo một di chuyển riêng để thực hiện việc này. (Đổi tên FixColumnName như bạn sẽ làm)

script/generate migration FixColumnName
# creates  db/migrate/xxxxxxxxxx_fix_column_name.rb

Sau đó chỉnh sửa di chuyển để thực hiện ý muốn của bạn.

# db/migrate/xxxxxxxxxx_fix_column_name.rb
class FixColumnName < ActiveRecord::Migration
  def self.up
    rename_column :table_name, :old_column, :new_column
  end

  def self.down
    # rename back if you need or do something else or do nothing
  end
end

Bản cập nhật cho Rails 3.1

Trong khi up và down phương pháp vẫn áp dụng. Rails 3.1 nhận được change phương pháp "biết cách di chuyển cơ sở dữ liệu của bạn và đảo ngược nó khi di chuyển được khôi phục mà không cần phải viết một phương thức riêng biệt"

rails g migration FixColumnName

class FixColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

Nếu bạn tình cờ có một loạt các cột để đổi tên, hoặc một cái gì đó mà có thể đã yêu cầu lặp đi lặp lại tên bảng hơn và hơn nữa.

rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...

Bạn đã có thể sử dụng change_table để giữ cho mọi thứ trở nên dễ dàng hơn một chút.

class FixColumnNames < ActiveRecord::Migration
  def change
    change_table :table_name do |t|
      t.rename :old_column1, :new_column1
      t.rename :old_column2, :new_column2
      ...
    end
  end
end

Cảm ơn bạn, Luke && Turadg, để đưa ra chủ đề.

Sau đó chỉ db:migrate như thường lệ hoặc tuy nhiên bạn đi về doanh nghiệp của bạn.


Bản cập nhật cho Rails 4

Trong khi tạo một Migration để đổi tên một cột, Rails 4 tạo ra một change phương pháp thay vì up và down như đã đề cập trong câu trả lời ở trên. Được tạo change phương pháp như sau:

$ > rails g migration ChangeColumnName

sẽ tạo tệp di chuyển tương tự như sau:

class ChangeColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

2084
2018-01-02 16:31



self.down nên luôn luôn ngược lại với self.up, vì vậy "nếu bạn cần hoặc làm điều gì khác hoặc không làm gì" thì không thực sự được khuyến nghị. Chỉ cần làm: rename_column: table_name,: new_column,: old_column - Luke Griffiths
Trong khi thực hành bình thường là hoàn nguyên những gì bạn đã làm self.up Tôi sẽ không nói self.down "Nên luôn luôn Ngược lại ". ​​Tùy thuộc vào bối cảnh di cư của bạn. Chỉ cần đặt" đối diện "có thể không phải là di chuyển xuống" đúng ". - nowk
Trong Rails 3.1 bạn có thể thay thế def self.up và def self.down với def change và nó sẽ biết cách quay ngược lại. - Turadg
Turadg - * nó sẽ biết cách khôi phục phần lớn thời gian. Tôi tìm thấy change phương pháp không phải là bằng chứng đầy đủ, vì vậy có xu hướng sử dụng up và down phương pháp di chuyển phức tạp. - JellyFishBoy
Đổi tên có xóa chỉ mục không? - Sung Won Cho


IMO, trong trường hợp này, sử dụng tốt hơn rake db:rollback. Sau đó, chỉnh sửa di chuyển của bạn và nhập lại rake db:migrate. Tuy nhiên, nếu bạn có dữ liệu trong cột bạn không muốn mất thì hãy sử dụng rename_column.


65
2018-01-03 00:55



Ngay cả trên một "nhóm của một", nếu bạn có nhiều trường hợp chạy ứng dụng của bạn, nói trong môi trường khác nhau hoặc trên nhiều máy tính, vv, quản lý di chuyển đã chỉnh sửa là một nỗi đau lớn. Tôi chỉ chỉnh sửa di chuyển nếu tôi chỉ tạo ra nó và nhận ra nó là sai, và đã không chạy nó theo nghĩa đen bất cứ nơi nào khác được nêu ra. - Yetanotherjosh
Tôi đã phải khởi động lại máy chủ sau đó. - Muhammad Hewedy
Kỹ thuật này chỉ nên được sử dụng trong trường hợp các thay đổi của bạn chưa được hợp nhất với chi nhánh sản xuất của bạn và những thay đổi khác không phụ thuộc vào sự kiên trì dữ liệu. Trong hầu hết mọi hoàn cảnh sản xuất, đây KHÔNG phải là phương pháp ưa thích. - Collin Graves
không bao giờ làm điều này. - new2cpp
Tôi muốn nói với nhóm của tôi: 'Di chuyển miễn phí' Chi phí chỉnh sửa di cư đã được phát hành vào tự nhiên rất cao: Tôi đã dành một vài giờ làm việc tại sao mã của tôi không hoạt động trước khi tôi nhận ra một thành viên khác trong nhóm đã quay lại và chỉnh sửa di chuyển mà tôi đã chạy. Vì vậy, không chỉnh sửa quá trình di chuyển hiện tại, hãy sử dụng một chuyển đổi mới để thay đổi giản đồ, bởi vì ... ... 'Di chuyển miễn phí!' (nó không đúng, nhưng nó làm cho vấn đề) - TerryS


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

Dưới Available Transformations

rename_column(table_name, column_name, new_column_name):

Đổi tên cột nhưng giữ loại và nội dung.


26
2018-01-02 16:26



Xem thêm tài liệu cho rename_column. - Franklin Yu


Nếu cột đã được phổ biến với dữ liệu và sống trong sản xuất, tôi khuyên bạn nên từng bước tiếp cận, để tránh thời gian chết trong sản xuất trong khi đợi di chuyển.

Trước tiên, tôi muốn tạo một di chuyển db để thêm các cột với (các) tên mới và điền chúng với các giá trị từ tên cột cũ.

class AddCorrectColumnNames < ActiveRecord::Migration
  def up
    add_column :table, :correct_name_column_one, :string
    add_column :table, :correct_name_column_two, :string

    puts 'Updating correctly named columns'
    execute "UPDATE table_name SET correct_name_column_one = old_name_column_one, correct_name_column_two = old_name_column_two"
    end
  end

  def down
    remove_column :table, :correct_name_column_one
    remove_column :table, :correct_name_column_two
  end
end

Sau đó, tôi chỉ cam kết thay đổi đó và đẩy sự thay đổi vào sản xuất.

git commit -m 'adding columns with correct name'

Sau đó, một khi cam kết đã được đẩy vào sản xuất, tôi sẽ chạy.

Production $ bundle exec rake db:migrate

Sau đó, tôi muốn cập nhật tất cả các khung nhìn / bộ điều khiển tham chiếu tên cột cũ thành tên cột mới. Chạy qua bộ thử nghiệm của tôi và chỉ thực hiện những thay đổi đó. (Sau khi chắc chắn rằng nó đã làm việc tại địa phương và vượt qua tất cả các bài kiểm tra đầu tiên!)

git commit -m 'using correct column name instead of old stinky bad column name'

Sau đó, tôi sẽ đẩy cam kết đó vào sản xuất.

Tại thời điểm này, bạn có thể loại bỏ cột ban đầu mà không phải lo lắng về bất kỳ loại thời gian chết nào liên quan đến việc di chuyển.

class RemoveBadColumnNames < ActiveRecord::Migration
  def up
    remove_column :table, :old_name_column_one
    remove_column :table, :old_name_column_two
  end

  def down
    add_column :table, :old_name_column_one, :string
    add_column :table, :old_name_column_two, :string
  end
end

Sau đó, đẩy di chuyển mới nhất này vào sản xuất và chạy bundle exec rake db:migrate trong nền.

Tôi nhận ra điều này có liên quan nhiều hơn đến quá trình, nhưng tôi muốn làm điều này hơn là có vấn đề với việc di chuyển sản xuất của tôi.


24
2017-08-30 22:08



Tôi thích những suy nghĩ đằng sau này, và tôi sẽ +1 repsonse của bạn nhưng dữ liệu cập nhật sẽ mất một thời gian rất dài để thực hiện vì nó đi qua đường ray và làm một hàng tại một thời điểm. Việc di chuyển sẽ thực thi nhanh hơn nhiều với các câu lệnh sql nguyên để cập nhật các cột được đặt tên chính xác. Ví dụ: trong tập lệnh di chuyển db đầu tiên, sau khi thêm tên cột trùng lặp, execute "Update table_name set correct_name_column_one = old_name_column_one" - Gui Weinmann
@ mr.ruh.roh ^ Hoàn toàn đồng ý, nên đã viết rằng ở nơi đầu tiên. Tôi đã chỉnh sửa để phản ánh một câu lệnh sql hiệu quả duy nhất. Cảm ơn bạn đã kiểm tra sự tỉnh táo. - Paul Pettengill
Điều gì sẽ xảy ra với các mục nhập giữa chuyển sang bảng mới và cập nhật mã để sử dụng bảng mới? Bạn có thể không còn dữ liệu chưa được di chuyển không? - Stefan Dorunga
trong khi đây là câu trả lời 'an toàn', tôi cảm thấy câu trả lời không đầy đủ. Nhiều người ở đây nói không làm điều này - sao? sự kiên trì của dữ liệu. Và đó là hợp lệ. Có lẽ cách đau đớn nhất là hoàn thành mục tiêu là tạo ra các trường mới, điền chúng với dữ liệu từ các cột cũ, điều chỉnh bộ điều khiển. Nếu bạn muốn xóa các cột cũ, bạn chắc chắn sẽ phải chỉnh sửa các khung nhìn. Chi phí giữ chúng là không gian db thêm và một số nỗ lực trùng lặp trong bộ điều khiển. Các sự cân bằng là như vậy rõ ràng. - Jerome


Chạy lệnh dưới đây để tạo tệp di chuyển:

rails g migration ChangeHasedPasswordToHashedPassword

Sau đó, trong tệp được tạo trong db/migrate thư mục, viết rename_column như sau:

class ChangeOldCoulmnToNewColumn < ActiveRecord::Migration
  def change
     rename_column :table_name, :hased_password, :hashed_password
  end
end

16
2017-12-03 11:45





Từ API:

rename_column(table_name, column_name, new_column_name)

Nó đổi tên một cột nhưng giữ kiểu và nội dung vẫn giữ nguyên.


13
2018-02-18 11:15





Một số phiên bản của Ruby on Rails hỗ trợ lên / xuống phương pháp di chuyển và nếu bạn có phương pháp lên / xuống trong quá trình di chuyển của mình, thì:

def up
    rename_column :table_name, :column_old_name, :column_new_name
end

def down
    rename_column :table_name, :column_new_name, :column_old_name
end

Nếu bạn có change trong quá trình di chuyển của bạn, sau đó:

def change
    rename_column :table_name, :column_old_name, :column_new_name
end

Để biết thêm thông tin, bạn có thể di chuyển: Ruby on Rails - Di chuyển hoặc là Hoạt động ghi lại di chuyển.


12
2018-02-14 10:38