ऑटो-असाइनिंग आईडी को रेल करता है जो पहले से मौजूद है


92

मैं एक नया रिकॉर्ड बनाता हूँ जैसे:

truck = Truck.create(:name=>name, :user_id=>2)

मेरे डेटाबेस में वर्तमान में ट्रक के लिए कई हज़ार इकाइयाँ हैं, लेकिन मैंने उनमें से कई को आईडी की ज़िम्मेदारी सौंपी है, इस तरह से कुछ आईडी उपलब्ध हैं। तो क्या हो रहा है रेल आईडी = 150 के साथ आइटम बनाता है और यह ठीक काम करता है। लेकिन फिर यह एक आइटम बनाने और इसे आईडी = 151 आवंटित करने की कोशिश करता है, लेकिन यह आईडी पहले से ही मौजूद हो सकती है, इसलिए मैं यह त्रुटि देख रहा हूं:

ActiveRecord::RecordNotUnique (PG::Error: ERROR: duplicate key value violates unique constraint "companies_pkey" DETAIL: Key (id)=(151) already exists.

और अगली बार जब मैं कार्रवाई करता हूं, तो यह केवल आईडी 152 को असाइन करेगा, जो ठीक काम करेगा यदि वह मान पहले से नहीं लिया गया है। मैं यह जांचने के लिए रेल कैसे प्राप्त कर सकता हूं कि क्या यह असाइन करने से पहले ही एक आईडी मौजूद है?

धन्यवाद!

संपादित करें

ट्रक आईडी वह है जिसे डुप्लिकेट किया जा रहा है। उपयोगकर्ता पहले से मौजूद है और इस मामले में एक स्थिर है। यह वास्तव में एक विरासत का मुद्दा है जिससे मुझे निपटना है। एक विकल्प यह है कि इस बार के आसपास हर रेल आईडी को ऑटो रेल असाइन करने के लिए टेबल को फिर से बनाया जाए। मुझे लगता है कि यह सबसे अच्छा विकल्प हो सकता है क्योंकि मुझे कुछ अन्य समस्याएं हैं, लेकिन ऐसा करने के लिए प्रवास बहुत जटिल होगा क्योंकि ट्रक कई अन्य तालिकाओं में एक विदेशी कुंजी है। क्या कोई सरल तरीका होगा कि रेल के नीचे पहले से संग्रहीत डेटा के साथ ही ऑटो-असाइन की गई आईडी और सभी मौजूदा रिश्तों को बनाए रखने के लिए रेल एक नई तालिका बनाएं?


आप रेल को स्वचालित रूप से आईडी असाइन करने की अनुमति क्यों नहीं दे रहे हैं? यह दोहराव के किसी भी खतरे को समाप्त करेगा - या यह एक विरासत डेटा समस्या है जहां आपको पुरानी आईडी को बनाए रखना होगा? बस व्यवसाय के मामले को थोड़ा समझना चाहते हैं क्योंकि यह नया ऑब्जेक्ट बनाते समय व्यवसाय-जैसा-सामान्य नहीं है।
MBHNYC

@MBHNYC मुझे लगता है कि कंपनी बनाते समय D-Nice एक user_id असाइन कर रहा है, और आईडी नहीं जैसा आप सोच रहे हैं (और मैंने एक पल के लिए भी किया था)।
अनिल

Ooo अच्छा पकड़ अनिल - आप पूरी तरह से सही हैं। @ डी-नाइस, शायद इस तालिका के लिए अपना माइग्रेशन जोड़कर अपनी पोस्ट में कोई अजीब बात है?
अस्थायी रूप

नहीं, क्षमा करें यह स्पष्ट नहीं था, कंपनी आईडी वह है जिसे डुप्लिकेट किया जा रहा है। उपयोगकर्ता पहले से मौजूद है और इस मामले में एक स्थिर है। यह वास्तव में एक विरासत का मुद्दा है जिससे मुझे निपटना है। अधिक जानकारी के साथ पोस्ट को संपादित करेंगे
डी-नाइस

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

जवाबों:


87

रेल शायद अंतर्निहित PostgreSQL अनुक्रम का उपयोग कर रहा है। एक अनुक्रम का विचार यह है कि यह केवल एक बार उपयोग किया जाता है।

सबसे सरल उपाय यह है कि आप अपनी कंपनी के लिए अनुक्रम सेट करें। इस तरह से एक प्रश्न के साथ तालिका में उच्चतम मूल्य के लिए कॉलम:

SELECT setval('company_id_seq', (SELECT max(id) FROM company));

मैं आपके अनुक्रम नाम "company_id_seq", टेबल नाम "कंपनी" और कॉलम नाम "id" पर अनुमान लगा रहा हूं ... कृपया उन्हें सही लोगों के साथ बदलें। आप अनुक्रम नाम के साथ SELECT pg_get_serial_sequence('tablename', 'columname');या तालिका की परिभाषा को देख सकते हैं \d tablename

वैकल्पिक समाधान अपनी कंपनी वर्ग में सेव () पद्धति को ओवरराइड करने से पहले मैन्युअल रूप से कंपनी आईडी को सेव करने से पहले नई पंक्तियों के लिए सेट करना है।


मैं अनुमान लगा रहा हूं कि वर्तमान में उच्चतम मूल्य + 1 के साथ ऑटो-असाइनिंग की शुरुआत क्या होगी?
डी-नाइस

मुझे लगता है कि यह मेरे सवाल का सबसे अच्छा जवाब है, हालांकि, असंबंधित कारणों के लिए, मुझे अपने ओपी संपादन में वर्णित रणनीति का उपयोग करने का एक तरीका खोजना होगा
D-Nice

मुझे समझ नहीं आता कि ऐसा क्यों हुआ? मेरे साथ ऐसा हुआ है और मैं यह समझना चाहूंगा कि यह कैसे संभव है।
बर्डिक

2
@ वेबसाइटें, यदि किसी के पास PostgreSQL में एक सीरियल कॉलम है (एक सीरियल कॉलम वह है जिसमें डिफ़ॉल्ट मान एक अनुक्रम में अगला मान है), तो उस कॉलम में कठिन मानों वाली तालिका को पॉप्युलेट करता है, अनुक्रम स्वचालित रूप से अपडेट नहीं होगा। उदाहरण: create table t (id serial not null primary key); insert into t values (1); insert into t values (default); ERROR: duplicate key value violates unique constraint "t_pkey" DETAIL: Key (id)=(1) already exists.
डोंडी माइकल स्ट्रोमा

206

मैंने ऐसा किया जिससे मेरे लिए समस्या हल हो गई।

ActiveRecord::Base.connection.tables.each do |t|
  ActiveRecord::Base.connection.reset_pk_sequence!(t)
end

मुझे रीसेट_पाक_ परिणाम मिला! इस धागे से। http://www.ruby-forum.com/topic/64428


4
धन्यवाद, सबसे अच्छा समाधान। डेटाबेस ट्रांसफर के बाद मुझे भी यही समस्या थी।
ओलेग पास्को

62
या वन-लाइनर समतुल्य (रेल्स कंसोल कॉपी / पेस्ट उद्देश्यों के लिए):ActiveRecord::Base.connection.tables.each { |t| ActiveRecord::Base.connection.reset_pk_sequence!(t) }
रफ

किसी भी विचार कैसे यह सिंक से बाहर हो जाता है?
टॉल पॉल

25

@ आपी जवाब के आधार पर ।

आप एक कार्य कर सकते हैं और अपनी आवश्यकता के अनुसार चला सकते हैं:

rake database:correction_seq_id

आप इस तरह के कार्य बनाएँ:

rails g task database correction_seq_id

और उत्पन्न फ़ाइल में ( lib/tasks/database.rake) डाला:

namespace :database do
    desc "Correction of sequences id"
    task correction_seq_id: :environment do
        ActiveRecord::Base.connection.tables.each do |t|
            ActiveRecord::Base.connection.reset_pk_sequence!(t)
        end
    end
end

4

मुझे एक डेटाबेस समस्या की तरह लगता है और रेल की समस्या नहीं है। क्या यह संभव है कि आपके डेटाबेस में आपके idकॉलम पर एक अनुचित पहचान बीज है ? एक जोड़े को सीधे अपने डेटाबेस में सम्मिलित करने का प्रयास करने का परीक्षण करने के लिए और देखें कि क्या समान व्यवहार मौजूद है।


3
क्यों होता है पतन? यह सटीक व्यवहार है जो तब होता है जब आप अपना वेतन वृद्धि क्रम किसी अन्य मौजूदा मूल्यों से कम होता है और इसलिए डेटा सम्मिलित करते समय कभी-कभी टकराव होता है। पोस्टर में पहले से ही कहा गया है कि मौजूदा डेटा है जो इस मामले में आता है।
mynameiscoffey

मैं फाइन लगा सकता हूं। यदि मुझे यह त्रुटि मिलती है, तो मैं वास्तव में उसी कार्रवाई को फिर से चला सकता हूं और यह काम कर सकता है, अगर अनुक्रम में अगली आईडी अभी तक नहीं ली गई है।
डी-नाइस

ऐसा लगता है कि यह मेरी स्थिति थी - मैं समस्या में भाग गया लेकिन अगले रिकॉर्ड मैंने ठीक काम किया, इसलिए इसे सही जगह पर बीज प्राप्त करना चाहिए।
बेन व्हीलर

3

मैंने कमांड का पालन करके इस मुद्दे को हल किया।

इसे अपने रेल कंसोल में चलाएं

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