एक रेल प्रकार बदलने के लिए रेल में तार


90

पहले प्रवास के दौरान, मैंने एक स्तंभ contentपर स्ट्रिंग होने की घोषणा की, Activerecord ने इसे एनोटेट रत्न के अनुसार स्ट्रिंग (255) किया।

मैं ऐप को हरोकू में धकेलने के बाद, जो पोस्टग्रैस का उपयोग करता है, अगर मैं सामग्री में एक स्ट्रिंग में दर्ज करता हूं 255 से अधिक लंबे समय तक मुझे त्रुटि मिलती है

PGError: ERROR: value too long for type character varying(255)

समस्या यह है कि मुझे उस सामग्री की आवश्यकता है जिसमें एक स्ट्रिंग है जो शायद बहुत लंबा है (मुफ्त पाठ, हजारों वर्ण हो सकते हैं)

  1. क्या चर (स्ट्रिंग इसके लिए उपयुक्त नहीं है) पीजी स्वीकार करेंगे?
  2. मैं उस कॉलम के प्रकार को बदलने के लिए माइग्रेशन कैसे बनाऊं

धन्यवाद

जवाबों:


216

textयदि आप बिना लंबाई सीमा के स्ट्रिंग चाहते हैं, तो आपको रेल के साथ उपयोग करना चाहिए । इस तरह से एक प्रवास:

def up
  change_column :your_table, :your_column, :text
end
def down
  # This might cause trouble if you have strings longer
  # than 255 characters.
  change_column :your_table, :your_column, :string
end

चीजों को सुलझाना चाहिए। आप चाहते हैं :null => falseया उस के अंत में कुछ अन्य विकल्प भी हो सकता है।

जब आप stringएक स्पष्ट सीमा के बिना एक कॉलम का उपयोग करते हैं , तो रेल एक अंतर्निहित जोड़ देगा :limit => 255। लेकिन अगर आप उपयोग करते हैं text, तो आपको डेटाबेस के समर्थन में जो भी मनमाना लंबाई का तार मिलेगा। PostgreSQL आपको varcharलंबाई के बिना एक कॉलम का उपयोग करने की अनुमति देता है, लेकिन अधिकांश डेटाबेस उसके लिए एक अलग प्रकार का उपयोग करते हैं और रेल varcharबिना लंबाई के बारे में नहीं जानते हैं । PostgreSQL में textएक textकॉलम प्राप्त करने के लिए आपको रेल में उपयोग करना होगा । वहाँ प्रकार का एक स्तंभ के बीच PostgreSQL में कोई अंतर नहीं है textऔर प्रकार में से एक varcharहै (लेकिन varchar(n) है अलग)। इसके अलावा, यदि आप PostgreSQL के शीर्ष पर तैनाती कर रहे हैं, तो :string(AKA varchar) का उपयोग करने का कोई कारण नहीं है , डेटाबेस व्यवहार करता है textऔरvarchar(n)एक ही आंतरिक रूप से अतिरिक्त लंबाई की बाधाओं को छोड़कर varchar(n); आप केवल का उपयोग करना चाहिए varchar(n)(उर्फ :stringस्तंभ आकार पर (जैसे एक सरकारी फार्म का है कि प्रपत्र 897 / बी पर उस क्षेत्र 432 का कहना है 23 वर्ण लंबा हो जाएगा के रूप में)) यदि आप एक बाहरी बाधा है।

एक तरफ के रूप में, यदि आप stringकहीं भी एक कॉलम का उपयोग कर रहे हैं, तो आपको हमेशा :limitअपने लिए एक अनुस्मारक के रूप में निर्दिष्ट करना चाहिए कि एक सीमा है और आपको यह सुनिश्चित करने के लिए मॉडल में एक सत्यापन होना चाहिए कि यह सीमा पार नहीं हुई है। यदि आप सीमा से अधिक हो जाते हैं, तो PostgreSQL शिकायत करेगा और एक अपवाद बढ़ाएगा, MySQL चुपचाप स्ट्रिंग या शिकायत (सर्वर कॉन्फ़िगरेशन के आधार पर) को काट देगा, SQLite इसे-के रूप में पारित कर देगा, और अन्य डेटाबेस कुछ और करेंगे (शायद शिकायत करें) ।

साथ ही, आपको एक ही डेटाबेस के शीर्ष पर विकास, परीक्षण और तैनाती भी करनी चाहिए (जो आमतौर पर हेरोकू में PostgreSQL होगा), आपको डेटाबेस सर्वर के समान संस्करणों का उपयोग भी करना चाहिए। डेटाबेस (जैसे कि BY BY का व्यवहार) के बीच अन्य अंतर हैं, जो ActiveRecord आपको इंसुलेट नहीं करेगा। आप पहले से ही ऐसा कर रहे होंगे, लेकिन मुझे लगा कि मैं इसका जिक्र करूंगा।


13
बहुत बढ़िया जवाब। एक नोट: रेल वर्तमान में परिवर्तन विधि के साथ change_column का समर्थन नहीं करती है ( guide.rubyonrails.org/migrations.html#using-the-change-method ); यदि स्मृति कार्य करती है, तो यदि आप ऐसा करते हैं तो आप एक अपरिवर्तनीय प्रवासन बनाएंगे। अप / डाउन विधियों के साथ इसे पुराने-स्कूल तरीके से करना बेहतर है।
१५:५५ बजे कविता

@BourbonJockey: यह समझ में आता है कि changeस्वचालित रूप से एक प्रकार का परिवर्तन रिवर्स करने में सक्षम नहीं होगा और माइग्रेशन गाइड का कहना है कि "[परिवर्तन विधि] रचनात्मक माइग्रेशन (कॉलम या टेबल जोड़कर) लिखने के लिए यह विधि पसंद की जाती है" और change_columnnn सूची में t आप इंगित करते हैं तो मुझे लगता है कि आप सही हैं। मैंने इसे उपयोग करने के लिए तय किया ( up/ downएक चेतावनी के साथ down), सिर के लिए धन्यवाद।
म्यू बहुत कम है

4
अन्य पाठकों के भविष्य के संदर्भ के लिए, इस तरीके से हरोकू में पोस्टग्रेज में स्ट्रिंग से पाठ में परिवर्तित करना डेटा खोना नहीं होगा।
मरीना मार्टिन

2
@ डेनिस: शायद "आपको एक ही डेटाबेस का उपयोग करके विकास, परीक्षण और तैनाती करना चाहिए" अधिक सटीक होगा। सामान्य समस्या यह है कि लोग (हास्यास्पद) रेल डिफ़ॉल्ट सेटअप का उपयोग करते हैं और जब वे किसी चीज़ के शीर्ष पर तैनात होते हैं तो चीजें अलग हो जाती हैं। PostgreSQL Heroku पर अभी भी डिफ़ॉल्ट और सबसे आम विकल्प है, नहीं?
म्यू बहुत कम है

3
एक तरफ ध्यान दें, रेल की धारणा कि अनिर्दिष्ट लंबाई के क्षेत्र 255 वर्ण होने चाहिए अजीब है। यह असीमित लंबाई पाने के लिए PostgreSQL में उपयोग करने के लिए आवश्यक नहीं है text; आप बस अनर्गल उपयोग कर सकते हैं varchar। रेल इस विषम सीमा को लागू कर रही है, PostgreSQL को नहीं।
क्रेग रिंगर

8

जबकि स्वीकृत उत्तर उत्कृष्ट है, मैं यहां एक उत्तर जोड़ना चाहता था जो उम्मीद करता है कि मूल पोस्टर प्रश्न 2 के साथ बेहतर व्यवहार करता है, अपने लिए गैर विशेषज्ञों के लिए।

  1. मैं उस कॉलम के प्रकार को बदलने के लिए माइग्रेशन कैसे बनाऊं

पाड़ प्रवास पैदा करना

आप अपने कंसोल में टाइप करके अपना परिवर्तन रखने के लिए माइग्रेशन उत्पन्न कर सकते हैं (बस tableअपने टेबल नाम के लिए, और columnआपके लिए कॉलम नाम बदल सकते हैं)

rails generate migration change_table_column

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

उदाहरण के लिए मैं एक प्रवास को बनाने के लिए से एक स्तंभ के प्रकार परिवर्तित करना चाहते stringकरने के लिए textएक मेज कहा जाता TodoItems में,:

class ChangeTodoItemsDescription < ActiveRecord::Migration
  def change
     # enter code here
     change_column :todo_items, :description, :text
  end
end

अपना प्रवास चला रहे हैं

एक बार जब आप कॉलम को चलाने के लिए कोड को दर्ज करेंगे,

rake db:migrate

अपने प्रवास को लागू करने के लिए। यदि आप एक त्रुटि करते हैं तो आप हमेशा परिवर्तन को वापस कर सकते हैं:

rake db:rollack

ऊपर और नीचे के तरीके

नई विधि के बजाय स्वीकृत उत्तर संदर्भ Upऔर Downविधियाँ Change। चूँकि रेल पुरानी 3.2 शैली और डाउन मेथड्स ने नए चेंज मेथड पर कुछ फायदे प्रस्तुत किए हैं। 'ऊपर और नीचे' से बचें ActiveRecord::IrreversibleMigration exceptionरेल 4 की रिहाई के बाद से आप reversibleइस त्रुटि से बचने के लिए उपयोग कर सकते हैं :

class ChangeProductsPrice < ActiveRecord::Migration
  def change
    reversible do |dir|
      change_table :products do |t|
        dir.up   { t.change :price, :string }
        dir.down { t.change :price, :integer }
      end
    end
  end
end

रेल का आनंद लें :)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.