2012-10-31 20 views
20

मेरे पास "उपयोगकर्ता" नामक मॉडल बनाया गया है और मैंने उपयोगकर्ता तालिका में कुछ कॉलम जोड़ने के लिए एक नया माइग्रेशन बनाया है। अब जब मैं रेक db चलाएँ: विस्थापित, मैं नीचे b/c यह उपयोगकर्ताओं को तालिका बनाने के लिए फिर सेरेल में कॉलम जोड़ने के लिए माइग्रेशन बनाने वाले रेल रेक डीबी चलाते समय त्रुटि का कारण बनते हैं: माइग्रेट

$ rake db:migrate 
== DeviseCreateUsers: migrating ============================================== 
-- create_table(:users) 
rake aborted! 
An error has occurred, all later migrations canceled: 

Mysql::Error: Table 'users' already exists: CREATE TABLE `users`..... 

क्यों यह तालिका फिर से बनाने के लिए कोशिश कर रहा है कोशिश कर रहा है त्रुटि मिलती है?

यहाँ आदेश मैं नया माइग्रेशन

$ rails generate migration AddDetailsToUsers home_phone:decimal cell_phone:decimal work_phone:decimal birthday:date home_address:text work_address:text position:string company:string 

नया माइग्रेशन इस तरह दिखता है बनाने के लिए इस्तेमाल है:

class AddDetailsToUsers < ActiveRecord::Migration 
    def change 
    add_column :users, :home_phone, :decimal 
    add_column :users, :cell_phone, :decimal 
    add_column :users, :work_phone, :decimal 
    add_column :users, :birthday, :date 
    add_column :users, :home_address, :text 
    add_column :users, :work_address, :text 
    add_column :users, :position, :string 
    add_column :users, :company, :string 
    end 
end 

संपादित

20120511224920_devise_create_users

class DeviseCreateUsers < ActiveRecord::Migration 
    def change 
    create_table(:users) do |t| 
     ## Database authenticatable 
     t.string :email,    :null => false, :default => "" 
     t.string :username,   :null => false, :default => "" 
     t.string :encrypted_password, :null => false, :default => "" 

     ## Recoverable 
     t.string :reset_password_token 
     t.datetime :reset_password_sent_at 

     ## Rememberable 
     t.datetime :remember_created_at 

     ## Trackable 
     t.integer :sign_in_count, :default => 0 
     t.datetime :current_sign_in_at 
     t.datetime :last_sign_in_at 
     t.string :current_sign_in_ip 
     t.string :last_sign_in_ip 

     ## Encryptable 
     # t.string :password_salt 

     ## Confirmable 
     # t.string :confirmation_token 
     # t.datetime :confirmed_at 
     # t.datetime :confirmation_sent_at 
     # t.string :unconfirmed_email # Only if using reconfirmable 

     ## Lockable 
     # t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts 
     # t.string :unlock_token # Only if unlock strategy is :email or :both 
     # t.datetime :locked_at 

     ## Token authenticatable 
     # t.string :authentication_token 


     t.timestamps 
    end 

    add_index :users, :email,    :unique => true 
    add_index :users, :reset_password_token, :unique => true 
    # add_index :users, :confirmation_token, :unique => true 
    # add_index :users, :unlock_token,   :unique => true 
    # add_index :users, :authentication_token, :unique => true 
    end 
end 

20120619023856_add_name_to_users

class AddNameToUsers < ActiveRecord::Migration 
    def change 
    add_column :users, :first_name, :string 
    add_column :users, :last_name, :string 
    end 
end 

20121031174720_add_details_to_users.rb

class AddDetailsToUsers < ActiveRecord::Migration 
    def change 
    add_column :users, :home_phone, :decimal 
    add_column :users, :cell_phone, :decimal 
    add_column :users, :work_phone, :decimal 
    add_column :users, :birthday, :date 
    add_column :users, :home_address, :text 
    add_column :users, :work_address, :text 
    add_column :users, :position, :string 
    add_column :users, :company, :string 
    end 
end 
+0

आउटपुट से ऐसा लगता है कि आपके नए माइग्रेशन पर नहीं, DeviseCreateUsers के दौरान त्रुटि होती है .. क्या आपके पास एक और (पुराना) माइग्रेशन है जो पहले ही उपयोगकर्ता तालिका बना चुका है? – fwalch

+0

हां मैं करता हूं। लेकिन मैंने सोचा कि मैं एक नया माइग्रेशन जोड़ने में सक्षम होना चाहिए जैसा कि मैंने किया था और रेक डीबी चला रहा था: माइग्रेट केवल माइग्रेशन चलाएगा जो वर्तमान में नहीं चल रहा है। – Catfish

+0

नया माइग्रेशन भी नहीं चलता है; ऐसा लगता है कि आपके पास दो अन्य हैं जो दोनों उपयोगकर्ता तालिका ('DeviseCreateUsers' और पुराने माइग्रेशन) बनाने का प्रयास करते हैं। तालिका बनाने की कोशिश करने के बजाय आपको 'add_column' का उपयोग करने के लिए शायद 'DeviseCreateUsers' को बदलना चाहिए। – fwalch

उत्तर

10

रेल अपने डेटाबेस की "schema_migrations" तालिका में माइग्रेशन का ट्रैक रखता है। जब तक "20120511224920" के लिए कोई प्रविष्टि न हो, जो कि देवता माइग्रेशन है, यह इसे फिर से चलाने का प्रयास करेगा, जो कि पहले से मौजूद है।

यदि आप मामले में हैं तो आप उसे तालिका में मैन्युअल रूप से जोड़ सकते हैं।

+1

मुझे इस बारे में पता नहीं था। मैंने एक रेक डीबी चलाया: रीसेट करें ताकि वहां केवल एक ही माइग्रेशन एक नया हो। अगर मैं schema_migrations तालिका के बारे में जानता होता तो मैं कम से कम जांच कर सकता था। – Catfish

+0

हालांकि मैं यह सुनिश्चित नहीं कर सकता कि समस्या क्या थी, मैं अनुमान लगा रहा हूं कि schema_migrations तालिका से एक रिकॉर्ड गायब था। – Catfish

6

त्रुटि कह रहा है कि यह मूल DeviseCreateUsers प्रवास फिर से चलाने की कोशिश कर रहा है और क्योंकि उन तालिका पहले से मौजूद नहीं कर सकते।

इसे ठीक करने के लिए, आप DeviseCreateUsers के लिए डाउन माइग्रेशन चला सकते हैं और फिर माइग्रेशन सामान्य के रूप में चला सकते हैं। आप ऐसा कर सकते हैं साथ:

rake db:migrate:down VERSION=20121031XXXXXXXX 
rake db:migrate 

कहाँ 20121031XXXXXXXX प्रवास नाम की तारीख मोहर है। दूसरे शब्दों में, आपके पास 20120410214815_devise_create_users.rb नामक माइग्रेशन होगा और आप फ़ाइल नाम से दिनांक टिकट कॉपी करेंगे और उसे कमांड में पेस्ट करेंगे। Here's the Rails Guide on Migrations for reference

संपादित करें: यह टिप्पणियों में उल्लेख किया गया है, लेकिन केवल चेतावनी का एक शब्द है। तालिका के लिए डाउन माइग्रेशन चलाने से तालिका में कोई प्रविष्टियां खो जाएंगी। मुझे लगता है कि आप विकास मोड में चल रहे हैं, इसलिए यह कोई समस्या नहीं होनी चाहिए। यदि आप उत्पादन में हैं, तो आपको तालिका डेटा का बैकअप लेने के लिए अतिरिक्त कदम उठाने होंगे और बाद में इसे पुनः लोड करना होगा, अन्यथा आपको एक बुरा दिन (या सप्ताह शायद) होगा।

+0

यदि मैं नीचे माइग्रेशन चलाता हूं, तो यह मेरी तालिका को हटाने जा रहा है और वहां मौजूद सभी डेटा सही हैं? आपके द्वारा पोस्ट की गई मार्गदर्शिका के मुताबिक, मुझे एक नया माइग्रेशन जोड़ने और रेक डीबी चलाने में सक्षम होना चाहिए: माइग्रेट यह बताने में सक्षम होना चाहिए कि क्या कोई माइग्रेशन चलाया गया है और इस बार उन लोगों को नहीं चलाया जा सकता है। – Catfish

+1

आप सही हैं। मुझे लगता है कि आप विकास मोड में चल रहे थे कि उपयोगकर्ता तालिका को पुनर्निर्मित करना स्वीकार्य था। रेल को यह बताने में सक्षम होना चाहिए कि आपके द्वारा चलाए गए माइग्रेशन या नहीं। मैंने बस दूसरे जवाब पर टिप्पणियां पढ़ीं। क्या आपके पास दो माइग्रेशन हैं जो 'create_table: users' चलाते हैं? – GorrillaMcD

1

मुझे लगता है कि आप rails generate devise user कभी-कभी DeviseCreateUsers उत्पन्न करते हैं। यदि आपने पहले से ही उपयोगकर्ता मॉडल और उपयोगकर्ता तालिका बनाई है, तो आप डीबी/माइग्रेट से उत्पन्न माइग्रेशन फ़ाइल को हटा सकते हैं।

+0

लेकिन अगर मैं जेनरेट माइग्रेशन को हटा देता हूं, जब मैं उत्पादन में जाता हूं और एक नए डेटाबेस पर माइग्रेशन चलाता हूं, तो मुझे कुछ माइग्रेशन गायब होने जा रहा है। – Catfish

+0

मुझे लगता है कि आपके पास उपयोगकर्ता तालिका बनाने के लिए पहले से ही एक और माइग्रेशन था। – Yanhao

+0

मेरे पास उपयोगकर्ता तालिका बनाने के लिए एक और माइग्रेशन है। – Catfish

4

आप एक ताजा डेटाबेस बनाने की कोशिश कर सकते हैं और फिर इसे फिर से माइग्रेट:

rake db:drop:all 
rake db:create:all 
rake db:migrate 
+0

मैंने एक रेक डीबी किया था: रीसेट करें, और फिर रेक चलाएं: डीबी: माइग्रेट करें, लेकिन यह अभी भी समझा नहीं है कि मैं सिर्फ एक नया माइग्रेशन क्यों नहीं बना सकता और इसे चला सकता हूं। रेल आमतौर पर इसे ठीक से संभालती है। – Catfish

2

तो मैं क्या इस से इकट्ठे हुए हैं से: स्थापित:

  • आप पहले से ही एक उपयोगकर्ता मॉडल
  • आप
  • आप भाग गया एक डिफ़ॉल्ट रेल वसीयत उत्पन्न उत्पादन में इस का संस्करण नहीं था
  • फिर आप रेल वसीयत उपयोगकर्ता

उत्पन्न भागा मैं आशा करता हूं कि:

  • आप आप एक बहुत

नोट में कोड की जाँच स्रोत नियंत्रण

  • का उपयोग करें: यदि नहीं, तो आप के बारे में जानने के लिए कारण है कि आप ऐसा करने की आवश्यकता है।

    करने से पहले आप वसीयत

    उम्मीद है, तुम सिर्फ एक बिंदु सही की एक नई sandbox वसीयत पैदा करने से पहले बना सकते हैं उत्पन्न अपने कोड को पलट दें। यदि नहीं, तो अपनी परियोजना निर्देशिका की प्रतिलिपि बनाएँ और इसे हाथ से करें। एकमात्र अन्य विकल्प मैन्युअल रूप से उत्पन्न सभी फ़ाइलों को मैन्युअल रूप से संपादित करता है।

    को पुन: चलाएं अपनी वसीयत पीढ़ी

    • readd मणि अपने Gemfile करने के लिए 'चिंतन'
    • रेल वसीयत उत्पन्न: स्थापित
    • रेल वसीयत मॉडल

    उत्पन्न लगता है कि मॉडल करता है सुनिश्चित करें मौजूद नहीं! यदि आप उस समस्या में नहीं आते हैं जो आप वर्तमान में कर रहे हैं।

    अन्य

    करने के लिए एक मॉडल से मौजूदा उपयोगकर्ताओं माइग्रेट आप एक स्क्रिप्ट पूरी तरह से प्रमाणीकरण जानकारी आप के लिए, नए अपनी पुरानी उपयोगकर्ता मॉडल से स्थानांतरित करने के लिए अच्छा उत्पन्न कर सकते हैं। यदि आप अपने वर्तमान प्रमाणीकरण के लिए डेविस से एक अलग हैशिंग एल्गोरिदम का उपयोग कर रहे हैं, तो आप या तो अपने सभी पासवर्ड को अमान्य कर देंगे और अपने उपयोगकर्ताओं को अपने ईमेल में एक पुष्टिकरण कोड का उपयोग करके एक नया पासवर्ड बनाने की आवश्यकता होगी या आप लॉग इन करते समय उपयोगकर्ताओं को माइग्रेट कर सकते हैं में पहली विधि स्वच्छ, पूर्ण और कठोर है। दूसरी विधि बदसूरत, अपूर्ण और चुप है। अपनी पसंद के अनुसार अपनी विधि चुनें।

    संपादित करें: आप शायद अपने एल्गोरिदम का उपयोग करने के लिए डेविस को अनुकूलित करने का एक तरीका ढूंढ सकते हैं। यह शायद बेहतर होगा, लेकिन थोड़ा और काम और काफी भंगुर होगा।

    एक और बात यह है कि आपके प्रमाणीकरण मॉडल को खाता डेटा के साथ अधिभारित नहीं किया जाना चाहिए। आपके पास एक मॉडल होना चाहिए जो केवल प्रमाणीकरण को संभालता है जिसमें has_a खाता डेटा मॉडल है जो आप खातों के बारे में ट्रैक करना चाहते हैं।

  • +0

    सौभाग्य से मैं इस समय उत्पादन में नहीं हूं, इसलिए मैंने अपने डीबी डेटा को हटाने के लिए समाप्त हो गया, लेकिन मैं बस सोच रहा हूं कि create_table स्क्रिप्ट को सही ढंग से छोड़ने और नए चलाने के बजाए फिर से चलाने और चलाने के लिए क्या कारण होगा add_columns – Catfish

    +0

    के साथ माइग्रेशन ओह ठीक है तो आपको उपयोगकर्ताओं को माइग्रेट करने की आवश्यकता नहीं है, लेकिन मैं अभी भी खाता डेटा से प्रमाणीकरण डेटा अलग कर दूंगा। शुद्धता के लिए, रेल मानते हैं कि आप माइग्रेशन में सबकुछ करना चाहते हैं। उपयोगकर्ता को अपने प्रमाणीकरण मॉडल के रूप में उपयोग करने के लिए आपको 'रेल मॉडल तैयार करने' मॉडल चलाने से पहले अपने पुराने को डेटाबेस से छोड़ना होगा। –

    0

    सिर्फ पहली फ़ाइल

    create_table(:users), :force => true do |t| 
    

    इस में

    कोशिश किसी अन्य तालिका

    +0

    लेकिन यह मेरी तालिका को सही ढंग से ओवरराइट करेगा? जैसा कि आप अन्य सभी टिप्पणियों से बता सकते हैं, मैं डेटा को हटाने के बिना, डीबी में कॉलम जोड़ने की कोशिश कर रहा हूं। रेल इसे संभालने में सक्षम है। – Catfish

    2

    और अप का उपयोग नीचे तरीकों पर आ जाएगी। यह रोलबैक और विशिष्ट माइग्रेशन फ़ाइल चलाने के लिए उपयोगी होगा।

    वाक्य रचना का पालन करें ..

    class AddDetailsToUsers < ActiveRecord::Migration 
        def self.up 
         add_column :users, :home_phone, :decimal 
         add_column :users, :cell_phone, :decimal 
         add_column :users, :work_phone, :decimal 
         add_column :users, :birthday, :date 
         add_column :users, :home_address, :text 
         add_column :users, :work_address, :text 
         add_column :users, :position, :string 
         add_column :users, :company, :string 
        end 
    
        def self.down 
         remove_column :users, :home_phone 
         remove_column :users, :cell_phone 
         remove_column :users, :work_phone 
         remove_column :users, :birthday 
         remove_column :users, :home_address 
         remove_column :users, :work_address 
         remove_column :users, :position 
         remove_column :users, :company 
        end 
        end 
    
    
        In this case please try to migrate using version number. 
    

    रेक डाटाबेस की तरह: विस्थापित: नीचे संस्करण = संस्करण संख्या #version संख्या कौन-सा संस्करण आप स्थानांतरित करना चाहता है।

    +0

    जब मैंने इस रेल की तरह माइग्रेशन माइग्रेशन AddDetailsToUsers उत्पन्न किया था, तो माइग्रेशन बनाया था जब ऊपर और नीचे विधियां क्यों नहीं बनाई गईं .... ' – Catfish

    +0

    हाय। रेल 2.2.2 में ऊपर और नीचे विधि उत्पन्न की जाएगी। – vijikumar

    +1

    रेल 3.1 एक नई परिवर्तन विधि प्रदान करके माइग्रेशन को बेहतर बनाता है। रचनात्मक माइग्रेशन (कॉलम या टेबल जोड़ना) लिखने के लिए इस विधि को प्राथमिकता दी जाती है। माइग्रेशन जानता है कि कैसे अपने डेटाबेस को माइग्रेट करना है और माइग्रेशन को अलग डाउन विधि लिखने की आवश्यकता के बिना वापस घुमाया जाता है। तो ऐसा लगता है कि आपको def self.down होने के बारे में चिंता करने की ज़रूरत नहीं है क्योंकि रेल अब यह समझने के लिए काफी समझदार है कि इसे वापस कैसे रोल करें। – vijikumar

    1

    कुछ पर्यावरण चर के लिए जांचें जो आपके प्रवासन के संस्करण के लिए एक अप्रत्याशित मूल्य की आपूर्ति कर रहे हैं। मुझे स्टैक ओवरफ़्लो पर an old question मिला (और अगर यह पुराना है तो मुझे क्षमा करें) जहां db:migrate मौजूदा नए माइग्रेशन को लागू करने के बजाय तालिका को नष्ट कर रहा था।

    धीरे-धीरे ये पाया गया कि एक पर्यावरण चर "0" का एक संस्करण पैरामीटर जो कार्यात्मक रूप rake db:migrate:down

    के बराबर है साथ चलाने के लिए db:migrate पैदा कर रहा था यह है कि अपनी स्थिति संस्करण के कारण हो सकता अप्रत्याशित रूप से बदला जा रहा है संभव पिछले माइग्रेशन DeviseCreateUsers को शामिल या मिलान करें? दशमलव cell_phone: दशमलव work_phone: दशमलव जन्मदिन:

    +0

    मुझे ऐसा नहीं लगता क्योंकि सभी माइग्रेशन के पास अलग-अलग टाइमस्टैम्प होते हैं – Catfish

    0
    जो आपने कहा है कि आप एक नया माइग्रेशन बनाने के लिए

    $ रेल प्रवास AddDetailsToUsers home_phone उत्पन्न इस आदेश का इस्तेमाल किया के अनुसार

    तारीख home_address: पाठ work_address: पाठ स्थिति: स्ट्रिंग कंपनी: स्ट्रिंग

    मुझे यकीन नहीं है कि यह सिर्फ एक टाइपो है, लेकिन यह "AddDetailsToUser" होना चाहिए और "उपयोगकर्ता" नहीं होना चाहिए। बस फिर से जांचें और हम आपकी मदद कर सकेंगे। यह तैयार जेनरेट मॉडल के लिए है। जब आप उपयोगकर्ता का उल्लेख करते हैं, डीबी में यह उपयोगकर्ताओं की तलाश करता है।

    रेल पर रूबी भाषाई परंपरा का पालन करें .able_नाम बहुवचन है लेकिन model_name एकवचन है। आपके द्वारा उपयोग किए गए आदेश में आपको model_name का उपयोग करना होगा।

    आप TABLE_NAME उपयोग करने के लिए तो यह

    रेल ग्राम प्रवास add_details_to_users home_phone उपयोग करना चाहते हैं: दशमलव ...... आदि

    0

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

    class A < ActiveRecord::Migration 
        def up 
        add_column :images, :name 
        end 
    end 
    
    A.new.migrate(:up) 
    
    संबंधित मुद्दे