81

प्रथम प्रवास पर में अब तार के लिए एक स्तंभ प्रकार में परिवर्तन करना, मैं एक स्तंभ content पर घोषित स्ट्रिंग होने के लिए ActiveRecord यह स्ट्रिंग (255) होने के लिए बनाया मणि व्याख्या के अनुसार।रेल

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

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

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

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

धन्यवाद

उत्तर

193

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

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

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

+13

महान जवाब। एक नोट: रेल वर्तमान में परिवर्तन विधि के साथ change_column का समर्थन नहीं करता है (http://guides.rubyonrails.org/migrations.html#using-the-change-method); यदि स्मृति सेवा करता है, तो आप ऐसा करते हुए एक अपरिवर्तनीय माइग्रेशन बनाएंगे। ऊपर/नीचे विधियों के साथ पुराने स्कूल के तरीके को बेहतर करने के लिए बेहतर है। – poetmountain

+0

@BourbonJockey: यह अर्थ है कि 'change' स्वचालित रूप से एक प्रकार परिवर्तन रिवर्स करने में सक्षम है और नहीं होगा पड़ता है [माइग्रेशन गाइड] (http://guides.rubyonrails.org/migrations.html#anatomy-of-a- माइग्रेशन) कहता है कि "[परिवर्तन विधि] इस विधि को रचनात्मक माइग्रेशन (कॉलम या टेबल जोड़ना) लिखने के लिए प्राथमिकता दी जाती है" और 'change_column' उस सूची में नहीं है जिस पर आप इंगित करते हैं, इसलिए मुझे लगता है कि आप सही हैं। मैंने इसे 'अप'/'डाउन' ('डाउन' पर एक चेतावनी के साथ) का उपयोग करने के लिए तय किया, हेड अप के लिए धन्यवाद। –

+4

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

0

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

  1. How do I create a migration to replace the type of that column

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

आप एक प्रवास आपके कंसोल में टाइप करके अपने परिवर्तन धारण करने के लिए उत्पन्न कर सकते हैं (सिर्फ तुम्हारे लिए अपने टेबल नाम के लिए table, और column की जगह स्तंभ नाम)

rails generate migrate change_table_column 

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

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

अपना माइग्रेशन

एक बार आपके द्वारा चल रहा है:

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

rake db:migrate 

अपनी माइग्रती को लागू करने के लिए पर। आप मुझसे कोई त्रुटि हो तो आप हमेशा के साथ परिवर्तन को वापस लाने कर सकते हैं:

rake db:rollack 

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

स्वीकार किए जाते हैं जवाब संदर्भ Up और Down तरीकों, नए Change विधि के बजाय। चूंकि रेल 3.2पुरानी शैली ऊपर और नीचे के तरीके ने नई परिवर्तन विधि पर कुछ फायदे प्रस्तुत किए। 'ऊपर और नीचे' ActiveRecord::IrreversibleMigration exception से बचें। Rails 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 

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