2009-08-22 14 views
64

मैं इस तरह कुछ करना चाहता हूँ:sqlalchemy flush() और डाली गई आईडी प्राप्त करें?

f = Foo(bar='x') 
session.add(f) 
session.flush() 

# do additional queries using f.id before commit() 
print f.id # should be not None 

session.commit() 

लेकिन f.id कोई नहीं है जब मैं यह प्रयास करें। में इससे कैसे चला सकता हूँ?

-Dan

+2

क्या आप एसए इंजन को 'echo = True' के साथ प्रारंभ कर सकते हैं, और देखें कि फ्लैश-टाइम पर SQL को निष्पादित किया जाता है? आप जो वर्णन करते हैं * * काम करना चाहिए और आपको आईडी देना चाहिए, लेकिन हो सकता है कि कोई अन्य समस्या हो जिसके परिणामस्वरूप f.id कोई नहीं हो। –

उत्तर

37

आपका नमूना कोड इस तरह काम करना चाहिए था। Sqlalchemy f.id के लिए एक मान प्रदान करना चाहिए, यह एक स्वत: उत्पन्न प्राथमिक कुंजी कॉलम मानते हैं। प्राथमिक कुंजी विशेषताओं को फ्लश() प्रक्रिया के भीतर तत्काल पॉप्युलेट किया जाता है क्योंकि वे उत्पन्न होते हैं और प्रतिबद्ध करने के लिए कोई कॉल आवश्यक नहीं होना चाहिए। तो यहां जवाब आपके मैपिंग के ब्योरे में निहित है, यदि उपयोग में बैकएंड के किसी भी अजीब quirks हैं (जैसे, SQLite एक समग्र प्राथमिक कुंजी के लिए पूर्णांक मान उत्पन्न नहीं करता है) और/या उत्सर्जित एसक्यूएल क्या कहता है जब आप गूंज चालू करें।

+0

आप सही हैं, खोल में एक त्वरित जांच से पता चलता है कि यह प्राथमिक कुंजी फ़ील्ड को मान के साथ पॉप्युलेट करता है। मुझे जांच करनी होगी कि यह अभ्यास में क्यों काम नहीं कर रहा था। – Eloff

+2

"आपका नमूना कोड एक मूल्य प्रदान करना चाहिए" जैसा कि आप कह रहे हैं "आपको पहले स्थान पर आईडी के लिए मूल्य देना चाहिए", "उस कोड के रूप में जिसने आपके काम किया होगा" के बजाय। यह मेरे लिए स्पष्ट हो गया कि आप तीसरे पढ़ने के बाद केवल पूर्व के बजाय उत्तरार्द्ध का मतलब था। क्या आप स्पष्टीकरण दे सकते हैं? – stochastic

-7

आप session.add(f) के बजाय session.save_or_update(f) का उपयोग कर प्रयास करना चाहिए।

+1

'save_or_update' को 0.5 या उससे भी कम समय से हटा दिया गया है। 'session.add() 'इसे करना चाहिए। –

93

मैंने अभी एक ही समस्या में भाग लिया है, और परीक्षण के बाद मुझे पता चला है कि इनमें से कोई भी जवाब पर्याप्त नहीं है।

वर्तमान में, या SQLAlchemy .6+ के रूप में, वहाँ एक बहुत ही सरल समाधान (अगर यह पहले संस्करण में उपलब्ध है मैं हालांकि मैं सोच भी यह होता है पता नहीं है,) है:

session.refresh()

f = Foo(bar=x) 
session.add(f) 
session.flush() 
# At this point, the object f has been pushed to the DB, 
# and has been automatically assigned a unique primary key id 

f.id 
# is None 

session.refresh(f) 
# refresh updates given object in the session with its state in the DB 
# (and can also only refresh certain attributes - search for documentation) 

f.id 
# is the automatically assigned primary key ID given in the database. 

इसे कैसे करना है कि:

तो, अपने कोड कुछ इस तरह दिखेगा।

+6

यह एक ऐसे उत्तर के करीब हो रहा है जो मेरे लिए काम कर सकता है लेकिन मुझे निम्न त्रुटि मिलती है: InvalidRequestError: उदाहरण '<....>' रीफ्रेश नहीं कर सका। यह फ्लश के बाद प्रकट होता है कि उदाहरण बस मौजूद नहीं है।किसी भी अंतर्दृष्टि की सराहना करते हैं। – PlaidFan

+1

आपने अभी मेरे गधे को बचाया है। मुझे नहीं लगता कि मैं कभी भी डीजेगो से आने वाले ओआरएम का उपयोग करूंगा। फ्लश() कमांड दस्तावेज आईएमएचओ के रूप में काम नहीं करता है। –

+1

अद्यतन, मुझे '' 'sessionmaker (autoflush = True)' '' का उपयोग करना था, उस कॉम्बो डब्ल्यू/रीफ्रेश() ने मुझे पंक्ति आईडी प्रदान की थी। #grrr –

4

डीपीबी द्वारा दिए गए उत्तर के विपरीत, एक ताज़ा करने की आवश्यकता नहीं है। एक बार आप फ्लश, आप आईडी फ़ील्ड का उपयोग कर सकते, SQLAlchemy स्वचालित रूप से आईडी जो ऑटो बैकएंड में उत्पन्न होता है

मैं इस समस्या का सामना करना पड़ा और कुछ जांच के बाद सही कारण लगा, मेरे मॉडल integerfield के रूप में आईडी के साथ बनाया गया था और ताज़ा करता है मेरे रूप में आईडी को छुपा क्षेत्र के साथ दर्शाया गया था (क्योंकि मैं अपने रूप में आईडी नहीं दिखाना चाहता था)। छुपा क्षेत्र डिफ़ॉल्ट रूप से एक पाठ के रूप में प्रतिनिधित्व किया जाता है। एक बार जब मैंने विजेट = hiddenInput() के साथ फॉर्म को पूर्णांकफील्ड में बदल दिया तो समस्या हल हो गई।

+1

का उपयोग करता हूं जैसा कि केवल ताज़ा किया गया है() मेरे लिए काम करता है। डेटा माइग्रेशन करने में मुझे एक एफओपी को पॉप करने के लिए लूप में पंक्ति आईडी की आवश्यकता होती है। मैंने प्रतिबद्धता, फ्लश, सत्र हैकिंग और रीफ्रेश() की हर कॉम्बो की कोशिश की, जो काम करने वाली एकमात्र चीज थी। मेरा डेटा बहुत साफ है और मुझे लगता है कि एसक्यूएलए वास्तव में अच्छा नहीं है (कम से कम 5 प्रमुख ओआरएमएस में काफी विस्तार कर रहा है)। एक ऐड() -> प्रतिबद्ध()/flush() के लिए पंक्ति आईडी प्राप्त करने का प्रयास कर 5+ घंटे पर बस लपेटें। –

1

मुझे session.add विधि पर कॉल करने से पहले आईडी में 0 असाइन करने में समस्या आई थी। आईडी को डेटाबेस द्वारा सही ढंग से असाइन किया गया था लेकिन session.flush() के बाद सत्र से सही आईडी पुनर्प्राप्त नहीं हुई थी।

संबंधित मुद्दे

 संबंधित मुद्दे