मैं रूबी माइग्रेशन पर रूबी में डेटाबेस कॉलम का नाम कैसे बदल सकता हूं?


1451

मैंने hased_passwordइसके बजाय गलत तरीके से एक कॉलम का नाम दिया hashed_password

इस कॉलम का नाम बदलने के लिए माइग्रेशन का उपयोग करके मैं डेटाबेस स्कीमा को कैसे अपडेट करूं?

जवाबों:


2308
rename_column :table, :old_column, :new_column

आप शायद ऐसा करने के लिए एक अलग माइग्रेशन बनाना चाहते हैं। (आपका FixColumnNameजैसा भी नाम हो।):

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

फिर अपनी इच्छा के अनुसार प्रवास को संपादित करें:

# 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

रेल 3.1 उपयोग के लिए:

हालांकि, upऔर downविधियाँ अभी भी लागू होती हैं, रेल 3.1 को एक changeविधि प्राप्त होती है जो "अपने डेटाबेस को माइग्रेट करने का तरीका जानता है और जब एक अलग डाउन विधि लिखने की आवश्यकता के बिना माइग्रेशन को वापस रोल किया जाता है तो इसे रिवर्स करें"।

अधिक जानकारी के लिए " सक्रिय रिकॉर्ड माइग्रेशन " देखें।

rails g migration FixColumnName

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

यदि आपका नाम बदलने के लिए स्तंभों का एक पूरा गुच्छा है, या ऐसा कुछ है जिसे बार-बार तालिका नाम को दोहराने की आवश्यकता होगी:

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

आप change_tableचीजों को थोड़ा खाने के लिए इस्तेमाल कर सकते हैं:

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

फिर db:migrateहमेशा की तरह या फिर आप अपने व्यवसाय के बारे में जाने।


रेल के लिए 4:

Migrationएक स्तंभ का नाम बदलने के लिए बनाते समय , रेल 4 changeइसके बजाय एक विधि उत्पन्न करता है upऔर downजैसा कि ऊपर दिए गए अनुभाग में बताया गया है। उत्पन्न changeविधि है:

$ > rails g migration ChangeColumnName

जो इसके समान एक माइग्रेशन फ़ाइल बनाएगा:

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

24
self.down हमेशा self.up के विपरीत होना चाहिए , इसलिए "यदि आपको आवश्यकता है या कुछ और करना है या कुछ नहीं करना है" तो वास्तव में अनुशंसित नहीं है। बस करें: rename_column: table_name, new_column: old_column
ल्यूक ग्रिफ़िथ

3
हालांकि यह सामान्य अभ्यास है कि आपने जो कुछ भी किया है उसे वापस करने के लिए self.upमैं यह नहीं कहूंगा कि self.down" हमेशा विपरीत होना चाहिए "। आपके प्रवास के संदर्भ पर निर्भर करता है। बस "विपरीत" डालने से "सही" डाउन माइग्रेशन नहीं हो सकता है।
nowk

23
रेल 3.1 में आप जगह ले सकता है def self.upऔर def self.downसाथ def changeहै और यह पता चल जाएगा कि कैसे रोलबैक करने के लिए।
तुरादग सिप

2
Turadg - * यह ज्यादातर समय रोलबैक करने के लिए पता चल जाएगा। मुझे पता है कि changeविधि पूर्ण प्रमाण नहीं है, इसलिए जटिल माइग्रेशन के लिए उपयोग upऔर downविधियों का उपयोग करें ।
जेलीफिशबॉय

6
क्या नामकरण इंडेक्स हटाता है?
गाया गया

68

मेरी राय में, इस मामले में, इसका उपयोग करना बेहतर है rake db:rollback, फिर अपने प्रवास को संपादित करें और फिर से चलाएं rake db:migrate

हालाँकि, यदि आपके पास उस स्तंभ में डेटा है जिसे आप खोना नहीं चाहते हैं, तो उपयोग करें rename_column


34
यहां तक ​​कि "एक टीम" पर, यदि आपके पास आपके ऐप के कई इंस्टेंस चल रहे हैं, तो अलग-अलग वातावरण में या कई कंप्यूटर आदि पर, संपादित माइग्रेशन को प्रबंधित करना एक प्रमुख दर्द है। मैं केवल एक माइग्रेशन संपादित करता हूं अगर मैंने इसे अभी बनाया है और यह महसूस किया कि यह गलत था, और इसे अभी तक कहीं और शाब्दिक रूप से नहीं चलाया गया है।
यतनथोरजोश

1
मुझे उसके बाद सर्वर को पुनरारंभ करना पड़ा।
मुहम्मद ह्वेदी

7
इस तकनीक का उपयोग केवल उस स्थिति में किया जाना चाहिए जहां आपके परिवर्तन अभी तक आपकी उत्पादन शाखा में विलय नहीं किए गए हैं, और अन्य डेटा दृढ़ता पर निर्भर नहीं हैं। ज्यादातर हर उत्पादन परिस्थिति में, यह पसंदीदा तरीका नहीं है।
कोलिन ग्रेव्स

4
इस तरह की बातें कभी मत करो।
new2cpp

4
मैं अपनी टीम से कहना चाहता हूं: 'माइग्रेशन फ्री हैं' एक माइग्रेशन को संपादित करने की लागत जो कि जंगली में जारी की गई है, उच्च है: मैंने एक बार कुछ घंटे काम करने में बिताए, इससे पहले कि मैं टीम के किसी अन्य सदस्य को महसूस करता, मेरा कोड काम क्यों नहीं कर रहा था वापस चला गया था और मैंने पहले से चलाए जा रहे प्रवास को संपादित किया था। इसलिए किसी मौजूदा माइग्रेशन को संपादित न करें, स्कीमा को बदलने के लिए एक नए का उपयोग करें, क्योंकि ... 'माइग्रेशन फ्री हैं!' (यह कड़ाई से सच नहीं है, लेकिन यह बात बनाता है)
टेरीस

31

यदि स्तंभ पहले से ही डेटा के साथ आबाद है और उत्पादन में रहता है, तो मैं एक कदम से कदम दृष्टिकोण की सिफारिश करूंगा, ताकि पलायन की प्रतीक्षा करते समय उत्पादन में डाउनटाइम से बचा जा सके।

पहले मैं नए नाम के साथ कॉलम जोड़ने और पुराने कॉलम नाम से मानों के साथ पॉप्युलेट करने के लिए db माइग्रेशन बनाऊंगा।

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

तब मैं सिर्फ उस बदलाव को कमिट करूंगा और बदलाव को प्रोडक्शन में धकेलूंगा।

git commit -m 'adding columns with correct name'

फिर एक बार जब कमिटमेंट को प्रोडक्शन में धकेल दिया गया, तो मैं दौड़ पड़ा।

Production $ bundle exec rake db:migrate

फिर मैं उन सभी विचारों / नियंत्रकों को अपडेट करूंगा, जिन्होंने पुराने कॉलम नाम को नए कॉलम नाम से संदर्भित किया था। मेरे परीक्षण सूट के माध्यम से चलाएं, और बस उन परिवर्तनों को प्रतिबद्ध करें। (यह सुनिश्चित करने के बाद कि यह स्थानीय रूप से काम कर रहा था और पहले सभी परीक्षण पास कर रहा था!)

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

फिर मैं उत्पादन के लिए प्रतिबद्ध हूं।

इस बिंदु पर आप माइग्रेशन से जुड़े किसी भी प्रकार के डाउनटाइम की चिंता किए बिना मूल कॉलम को हटा सकते हैं।

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

फिर उत्पादन के लिए इस नवीनतम माइग्रेशन को धक्का दें और bundle exec rake db:migrateपृष्ठभूमि में चलाएं ।

मुझे लगता है कि यह एक प्रक्रिया में थोड़ा अधिक शामिल है, लेकिन मैं ऐसा नहीं करूंगा कि मेरे उत्पादन प्रवास के साथ समस्याएं हैं।


2
मुझे इसके पीछे की सोच पसंद है, और मैं आपके प्रतिनिधि को +1 करूंगा लेकिन डेटा अपडेट को निष्पादित करने में बहुत लंबा समय लगेगा क्योंकि यह रेल से गुजर रहा है और एक समय में एक पंक्ति कर रहा है। सही नाम वाले कॉलम को अपडेट करने के लिए माइग्रेशन कच्चे sql स्टेटमेंट के साथ बहुत तेज़ी से निष्पादित होगा। उदाहरण के लिए, पहले db माइग्रेशन स्क्रिप्ट में, डुप्लिकेट कॉलम नामों को जोड़ने के बाद, execute "Update table_name set correct_name_column_one = old_name_column_one"
Gui Weinmann

1
@ mr.ruh.roh ^ पूरी तरह से सहमत हैं, कि पहली जगह में लिखा जाना चाहिए था। मैंने एकल कुशल एसक्यूएल स्टेटमेंट को प्रतिबिंबित करने के लिए संपादन किया है। पवित्रता की जाँच के लिए धन्यवाद।
पॉल पेटेंगेंग

2
नई तालिका में जाने और नई तालिका का उपयोग करने के लिए कोड को अपडेट करने के बीच प्रविष्टियों के साथ क्या होता है? क्या आपके पास संभावित अनम्यूट डेटा शेष नहीं रह सकता है?
स्टीफन डोरुंगा

1
जबकि यह एक 'सुरक्षित' उत्तर है, मुझे लगता है कि यह अधूरा है। यहाँ कई लोग कहते हैं कि यह क्यों नहीं करते? डेटा की दृढ़ता। और यह मान्य है। संभवत: कम से कम दर्दनाक तरीके से लक्ष्य को पूरा करने के लिए नए क्षेत्रों को बनाना है, उन्हें पुराने कॉलम से डेटा के साथ पॉप्युलेट करना, नियंत्रकों को समायोजित करना है। यदि आप पुराने कॉलम हटाना चाहते हैं, तो आपको निश्चित रूप से विचारों को संपादित करना होगा। उन्हें रखने की लागत अतिरिक्त डीबी स्पेस और नियंत्रक में कुछ डुप्लिकेट प्रयास है। इस प्रकार ट्रेडऑफ स्पष्ट हैं।
जेरोम

26

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

के अंतर्गत Available Transformations

rename_column(table_name, column_name, new_column_name):

एक स्तंभ का नाम बदलता है, लेकिन प्रकार और सामग्री रखता है।


1
इसके लिए दस्तावेजrename_column भी देखें ।
फ्रैंकलिन यू

18

माइग्रेशन फ़ाइल बनाने के लिए नीचे कमांड चलाएँ:

rails g migration ChangeHasedPasswordToHashedPassword

फिर db/migrateफ़ोल्डर में उत्पन्न फ़ाइल में , rename_columnनीचे लिखें :

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

14

एपीआई से:

rename_column(table_name, column_name, new_column_name)

यह एक स्तंभ का नाम बदल देता है लेकिन प्रकार और सामग्री समान रहता है।


12

पटरियों पर रूबी के कुछ संस्करण प्रवास के लिए अप / डाउन विधि का समर्थन करते हैं और यदि आपके प्रवास में अप / डाउन विधि है, तो:

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

यदि आपके पास changeप्रवासन में विधि है, तो:

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

अधिक जानकारी के लिए आप आगे बढ़ सकते हैं: रूबी ऑन रेल्स - माइग्रेशन या एक्टिव रिकॉर्ड माइग्रेशन


11

यदि आपका कोड अन्य के साथ साझा नहीं किया गया है, तो सबसे अच्छा विकल्प यह है कि rake db:rollback प्रवास में और फिर अपना कॉलम नाम संपादित करें rake db:migrate। बस

और आप स्तंभ का नाम बदलने के लिए एक और माइग्रेशन लिख सकते हैं

 def change
    rename_column :table_name, :old_name, :new_name
  end

बस।


rake db:rollbackबहुत अच्छा सुझाव है। लेकिन जैसा कि आपने कहा, केवल तभी जब माइग्रेशन को आगे नहीं बढ़ाया गया हो।
danielricecodes

9

एक वैकल्पिक विकल्प के रूप में, यदि आप प्रवासियों के विचार से शादी नहीं करते हैं, तो ActiveRecord के लिए एक सम्मोहक रत्न है जो आपके लिए नाम परिवर्तन को स्वचालित रूप से संभाल लेगा, Datamapper शैली। आपको बस अपने मॉडल में कॉलम का नाम बदलना है (और सुनिश्चित करें कि आपने Model.auto_upgrade को अपने मॉडल के निचले भाग पर स्थित किया है) और viola! डेटाबेस मक्खी पर अद्यतन किया जाता है।

https://github.com/DAddYE/mini_record

नोट: संघर्ष को रोकने के लिए आपको db / स्कीमा.rb को nuke करना होगा

अभी भी बीटा चरणों में और स्पष्ट रूप से सभी के लिए नहीं है, लेकिन फिर भी एक सम्मोहक विकल्प है (मैं वर्तमान में दो गैर-तुच्छ उत्पादन एप्लिकेशन में इसका उपयोग कर रहा हूं जिसमें कोई समस्या नहीं है)


8

यदि आपको कॉलम नामों को स्विच करने की आवश्यकता है, तो आपको डुप्लिकेट कॉलम नाम त्रुटि से बचने के लिए प्लेसहोल्डर बनाने की आवश्यकता होगी । यहाँ एक उदाहरण है:

class SwitchColumns < ActiveRecord::Migration
  def change
    rename_column :column_name, :x, :holder
    rename_column :column_name, :y, :x
    rename_column :column_name, :holder, :y
  end
end

7

यदि आपके लिए वर्तमान डेटा महत्वपूर्ण नहीं है, तो आप अपने मूल माइग्रेशन को नीचे ले जा सकते हैं:

rake db:migrate:down VERSION='YOUR MIGRATION FILE VERSION HERE'

उद्धरण के बिना, फिर मूल माइग्रेशन में परिवर्तन करें और अप माइग्रेशन को फिर से चलाएं:

rake db:migrate

6

बस एक नया माइग्रेशन बनाएं, और एक ब्लॉक में, rename_columnनीचे के रूप में उपयोग करें।

rename_column :your_table_name, :hased_password, :hashed_password


5

मैन्युअल रूप से हम नीचे दी गई विधि का उपयोग कर सकते हैं:

हम माइग्रेशन को मैन्युअल रूप से संपादित कर सकते हैं जैसे:

  • खुला हुआ app/db/migrate/xxxxxxxxx_migration_file.rb

  • को अपडेट hased_passwordकरेंhashed_password

  • नीचे दिए गए आदेश चलाएँ

    $> rake db:migrate:down VERSION=xxxxxxxxx

तब यह आपके प्रवासन को हटा देगा:

$> rake db:migrate:up VERSION=xxxxxxxxx

यह अद्यतन परिवर्तन के साथ आपके प्रवासन को जोड़ेगा।


यह सुरक्षित नहीं होगा क्योंकि आप डेटा को ढीला कर सकते हैं - यदि कॉलम पहले से ही लाइव है। लेकिन नए कॉलम और / या टेबल के लिए कर सकते हैं।
तेजस पटेल 12

5

माइग्रेशन फ़ाइल जनरेट करें:

rails g migration FixName

# डीबी / माइग्रेट / xxxxxxxxxx.rb बनाता है

अपनी इच्छानुसार प्रवास को संपादित करें।

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

5

Daud rails g migration ChangesNameInUsers (या जो भी आप इसे नाम देना चाहेंगे)

माइग्रेशन फ़ाइल खोलें, जो अभी जेनरेट हुई है, और इस लाइन को विधि में जोड़ें (बीच में def changeऔर end):

rename_column :table_name, :the_name_you_want_to_change, :the_new_name

फ़ाइल को सहेजें, और rake db:migrateकंसोल में चलाएं

schema.dbडेटाबेस में नाम वास्तव में बदल गया है या नहीं यह देखने के लिए अपना चेक आउट करें !

उम्मीद है की यह मदद करेगा :)


5

चलो KISS । यह सब तीन सरल कदम है। रेल 5.2 के लिए निम्नलिखित कार्य करता है ।

1 है। एक प्रवास बनाएँ

  • rails g migration RenameNameToFullNameInStudents

  • rails g RenameOldFieldToNewFieldInTableName- इस तरह यह बाद में कोड बेस के रखवाले के लिए पूरी तरह से स्पष्ट है। (तालिका नाम के लिए एक बहुवचन का उपयोग करें)।

2. प्रवास संपादित करें

# I prefer to explicitly write theऊपर andनीचेmethods.

# ./db/migrate/20190114045137_rename_name_to_full_name_in_students.rb

class RenameNameToFullNameInStudents < ActiveRecord::Migration[5.2]
  def up
    # rename_column :table_name, :old_column, :new_column
    rename_column :students, :name, :full_name
  end

  def down
            # Note that the columns are reversed
    rename_column :students, :full_name, :name
  end
end

3. अपना माइग्रेशन चलाएं

rake db:migrate

और आप दौड़ से दूर हैं!


4
$:  rails g migration RenameHashedPasswordColumn
invoke  active_record
      create    db/migrate/20160323054656_rename_hashed_password_column.rb

उस माइग्रेशन फ़ाइल को खोलें और नीचे की तरह उस फ़ाइल को संशोधित करें (अपना मूल दर्ज करें table_name)

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


3

पटरियों पर रूबी उत्पन्न करें :

$:> rails g migration Fixcolumnname

माइग्रेशन फ़ाइल में कोड डालें (XXXXXfixcolumnname.rb) :

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

2

रेल कंसोल पर अपनी रूबी खोलें और दर्ज करें:

ActiveRecord::Migration.rename_column :tablename, :old_column, :new_column

2

आपके पास ऐसा करने के दो तरीके हैं:

  1. इस प्रकार में यह स्वचालित रूप से इसका उल्टा कोड चलाता है, जब रोलबैक होता है।

    def change
      rename_column :table_name, :old_column_name, :new_column_name
    end
  2. इस प्रकार के लिए, यह अप विधि rake db:migrateको चलाता है और जब डाउन विधि को चलाता है rake db:rollback:

    def self.up
      rename_column :table_name, :old_column_name, :new_column_name
    end
    
    def self.down
      rename_column :table_name,:new_column_name,:old_column_name
    end

2

मैं ५.२ रेल पर हूँ, और एक उपयोगकर्ता पर एक कॉलम का नाम बदलने की कोशिश कर रहा हूं।

rename_columnबिट मेरे लिए काम किया, लेकिन विलक्षण :table_nameएक फेंक दिया त्रुटि "उपयोगकर्ता तालिका नहीं मिला"। मेरे लिए बहुवचन काम किया।

rails g RenameAgentinUser

फिर माइग्रेशन फ़ाइल को इसमें बदलें:

rename_column :users, :agent?, :agent

कहां: एजेंट? पुराना कॉलम नाम है।


0

अद्यतन - create_table का एक करीबी चचेरा भाई है, जो मौजूदा टेबल को बदलने के लिए इस्तेमाल किया जाता है। इसका उपयोग समान रूप से create_table करने के लिए किया जाता है, लेकिन ब्लॉक को प्राप्त की गई वस्तु अधिक चालें जानती है। उदाहरण के लिए:

class ChangeBadColumnNames < ActiveRecord::Migration
  def change
    change_table :your_table_name do |t|
      t.rename :old_column_name, :new_column_name
    end
  end
end

यदि हम अन्य परिवर्तन विधियों के साथ करते हैं तो यह तरीका और अधिक कुशल है जैसे: इंडेक्स निकालें / इंडेक्स / निकालें इंडेक्स / एड कॉलम जोड़ें, जैसे हम आगे देख सकते हैं:

# Rename
t.rename :old_column_name, :new_column_name
# Add column
t.string :new_column
# Remove column
t.remove :removing_column
# Index column
t.index :indexing_column
#...

0

कमांड का उपयोग करके माइग्रेशन उत्पन्न करें

rails g migration rename_hased_password

उसके बाद परिवर्तन विधि में माइग्रेशन जोड़ें निम्नलिखित पंक्ति जोड़ें

rename_column :table, :hased_password, :hashed_password

यह काम कर जाना चाहिए।


0

5 प्रवास परिवर्तन

उदाहरण के लिए:

रेल जी मॉडल छात्र student_name: स्ट्रिंग आयु: पूर्णांक

यदि आप name के रूप में student_name कॉलम बदलना चाहते हैं

नोट: - यदि आप रेल नहीं चलाते हैं तो db: माइग्रेट करें

आप निम्न चरण कर सकते हैं

रेल d मॉडल छात्र student_name: स्ट्रिंग आयु: पूर्णांक

यह उत्पन्न माइग्रेशन फ़ाइल को निकाल देगा, अब आप अपना कॉलम नाम सही कर सकते हैं

रेल जी मॉडल छात्र का नाम: स्ट्रिंग आयु: पूर्णांक

यदि आप माइग्रेट किए गए हैं (रेल डीबी: माइग्रेट करें), कॉलम नाम बदलने के विकल्प के बाद

रेल g माइग्रेशन RemoveStudentNameFromStudent student_name: string

रेल g माइग्रेशन AddNameToStudent नाम: string


क्या यह नहीं होना चाहिए: rails g migration RemoveStudentNameFromStudentS student_name:string(छात्र बहुवचन हैं)?
BKSpurgeon

इसके अलावा यह खतरनाक है: स्तंभ का नाम नहीं बदला गया है, लेकिन पूरी तरह से हटा दिया गया है और फिर रीड किया गया है। डेटा का क्या होगा? यह वह नहीं हो सकता है जो उपयोगकर्ता चाहेगा।
BKSpurgeon
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.