เปลี่ยนประเภทคอลัมน์จาก Date เป็น DateTime ระหว่างการย้าย ROR


227

ฉันต้องเปลี่ยนประเภทคอลัมน์จากวันที่เป็นวันที่และเวลาสำหรับแอปที่ฉันกำลังทำ ฉันไม่สนใจเกี่ยวกับข้อมูลในขณะที่ยังคงพัฒนาอยู่

ฉันจะทำสิ่งนี้ได้อย่างไร

คำตอบ:


508

ที่หนึ่งในเทอร์มินัลของคุณ:

rails g migration change_date_format_in_my_table

จากนั้นในไฟล์การโยกย้ายของคุณ:

สำหรับ Rails> = 3.2:

class ChangeDateFormatInMyTable < ActiveRecord::Migration
  def up
    change_column :my_table, :my_column, :datetime
  end

  def down
    change_column :my_table, :my_column, :date
  end
end

27
คุณพูดถูกฉันเพิ่งสันนิษฐานว่าผู้เริ่มต้นจะเลือกเทคโนโลยีล่าสุดที่มีอยู่ แต่แน่นอนว่าไม่แน่ใจ
apneadiving

12
คำถามถูกติดแท็ก "ruby-on-rails-3"
Sucrenoir

2
@Sucrenoir ใช่แท็กถูกเพิ่มโดย apneadiving หลังจากที่เขาตอบ
เจสัน

10
หากคุณกำลังสงสัยว่าทำไมเดียวchangeวิธีการที่ไม่ได้ใช้แทนupและdownวิธีการก็เพราะวิธีการไม่สนับสนุนความละเอียดการโยกย้าย changechange_column
เดนนิส

2
คำตอบนี้ถูกต้องเพียงบางส่วนเท่านั้นคุณไม่สามารถใช้ change_column ภายในการเปลี่ยนแปลงได้แม้บนราง 4 หรือการโยกย้ายลงจะไม่ทำงาน คุณควรใช้ขึ้น / ลงไม่ว่าจะเป็นรางรุ่นใด
Alan Peabody

78

นอกจากนี้หากคุณใช้ Rails 3 หรือใหม่กว่าคุณไม่จำเป็นต้องใช้upและdownวิธีการ คุณสามารถใช้change:

class ChangeFormatInMyTable < ActiveRecord::Migration
  def change
    change_column :my_table, :my_column, :my_new_type
  end
end

78
วิธีการเปลี่ยนใช้งานได้เฉพาะกับการย้ายข้อมูลแบบย้อนกลับได้ รหัสด้านบนจะส่งข้อยกเว้น ActiveRecord :: IrreversibleMigration ควรใช้วิธีการเฉพาะในapi.rubyonrails.org/classes/ActiveRecord/Migration/…ในวิธีการเปลี่ยน
davekaro

3
ฉันใช้งาน Rails 4 และเคยทำการโยกย้ายแบบนี้มาก่อน เปลี่ยนไม่ทำงาน! ความคิดเห็นของ @ davekaro ถูกต้อง
harryt

3
สำหรับ Rails 5 นี่คือทางออกที่ถูกต้องและใช้งานได้
WM

3
เมื่อถูกกลับรายการจะทราบได้อย่างไรว่าคอลัมน์เก่าประเภทใดที่ควรเปลี่ยนกลับเป็น
Andrew Grimm

@AndrewGrimm คุณถูกต้อง นี่คือสิ่งที่ฉันเห็นเมื่อฉันพยายามย้อนกลับการย้ายถิ่นของฉัน:This migration uses change_column, which is not automatically reversible. To make the migration reversible you can either: 1. Define #up and #down methods in place of the #change method. 2. Use the #reversible method to define reversible behavior.
Marklar

42

ใน Rails 3.2 และ Rails 4 คำตอบที่ได้รับความนิยมของ Benjamin มีรูปแบบที่แตกต่างกันเล็กน้อย

ที่หนึ่งในเทอร์มินัลของคุณ:

$ rails g migration change_date_format_in_my_table

จากนั้นในไฟล์การโยกย้ายของคุณ:

class ChangeDateFormatInMyTable < ActiveRecord::Migration
  def up
   change_column :my_table, :my_column, :datetime
  end

  def down
   change_column :my_table, :my_column, :date
  end
end

23

มีเมธอดchange_columnเพียงดำเนินการในการย้ายข้อมูลของคุณด้วย datetime เป็นประเภทใหม่

change_column(:my_table, :my_column, :my_new_type)

1
นี้จะรักษาข้อมูลต้นฉบับหรือไม่
BKSpurgeon

1
ใช่เก็บรักษาข้อมูลดั้งเดิมไว้
Mauro

1

AFAIK การย้ายข้อมูลอยู่ที่นั่นเพื่อพยายามปรับแต่งข้อมูลที่คุณสนใจ (เช่นการผลิต) เมื่อทำการเปลี่ยนแปลงสคีมา ดังนั้นหากไม่ถูกต้องและเนื่องจากเขาบอกว่าเขาไม่สนใจข้อมูลทำไมไม่เพียงแค่ปรับเปลี่ยนประเภทคอลัมน์ในการย้ายข้อมูลดั้งเดิมจากวันที่เป็นวันที่และเวลาและเรียกใช้การย้ายข้อมูลอีกครั้ง (หวังว่าคุณจะได้รับการทดสอบ :))


2
คุณอาจสนใจเกี่ยวกับการใช้การย้ายข้อมูลในสภาพแวดล้อมการพัฒนาแม้ว่าคุณจะไม่สนใจข้อมูลถ้าคุณทำงานในทีมและคุณต้องการให้สคีมาของคุณเปลี่ยนเพื่อเผยแพร่ไปยังนักพัฒนาอื่น ๆ ทั้งหมดในทีมของคุณ
Jose B

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

หากคุณใช้การย้ายข้อมูลใหม่คุณสามารถยกเลิกการโยกย้ายที่เปลี่ยนประเภทคอลัมน์ได้ หากคุณต้องการแก้ไขต้นฉบับคุณจะต้องย้อนกลับแก้ไขนั้นและเรียกใช้การย้ายข้อมูลใหม่หลังจากนั้น
jazzpi

จริงๆแล้วนี่เป็นคำตอบที่รอบคอบมากเพราะยังไม่มีข้อมูลการผลิต สำหรับผู้ที่กังวลเกี่ยวกับสมาชิกในทีมคนอื่น ๆ นั่นคือสิ่งที่rake db:migrate:resetมีไว้สำหรับ
Ryan McGeary
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.