पायथन / पोस्टग्रेज / psycopg2: केवल सम्मिलित की गई पंक्ति की ID प्राप्त करना


99

मैं अजगर और psycopg2 का उपयोग कर रहा हूँ इंटरफ़ेस को पोस्ट करने के लिए।

जब मैं एक पंक्ति सम्मिलित करता हूं ...

sql_string = "INSERT INTO hundred (name,name_slug,status) VALUES ("
sql_string += hundred_name + ", '" + hundred_slug + "', " + status + ");"
cursor.execute(sql_string)

... जिस पंक्ति को मैंने अभी डाला है, उसकी आईडी मुझे कैसे मिलेगी? कोशिश कर रहे हैं:

hundred = cursor.fetchall() 

उपयोग करते समय एक त्रुटि देता है RETURNING id:

sql_string = "INSERT INTO domes_hundred (name,name_slug,status) VALUES ("
sql_string += hundred_name + ", '" + hundred_slug + "', " + status + ") RETURNING id;"
hundred = cursor.execute(sql_string)

बस लौटता है None

अद्यतन: तो currval(भले ही इस कमांड का उपयोग सीधे पोस्टग्रेज कार्यों में किया जाता है):

sql_string = "SELECT currval(pg_get_serial_sequence('hundred', 'id'));"
hundred_id = cursor.execute(sql_string)

क्या कोई सलाह दे सकता है?

धन्यवाद!

जवाबों:


206
cursor.execute("INSERT INTO .... RETURNING id")
id_of_new_row = cursor.fetchone()[0]

और कृपया मैन्युअल रूप से मान वाले SQL स्ट्रिंग्स का निर्माण न करें। आप मान सकते हैं (और चाहिए) अलग से मान, यह अनावश्यक बचने के लिए और SQL इंजेक्शन असंभव:

sql_string = "INSERT INTO domes_hundred (name,name_slug,status) VALUES (%s,%s,%s) RETURNING id;"
cursor.execute(sql_string, (hundred_name, hundred_slug, status))
hundred = cursor.fetchone()[0]

अधिक जानकारी के लिए मानस डॉक्स देखें: http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries


12
बस स्पष्ट करने के लिए, idमें RETURNING idधारावाहिक / प्राथमिक कुंजी क्षेत्र के क्षेत्र नाम होना चाहिए।
20

9
कर्सर भ्रूण मुझे "लाने के लिए कोई परिणाम नहीं" देता है।
लियोनिद

@ लियोनिड क्या आपने इसका पता लगाया?
एलिसन एस

4
@ एलिसन @ लियोनिड मैं एक ही त्रुटि थी, लेकिन क्वेरी RETURNING idके अंत में जोड़कर INSERTइसे मेरे लिए तय किया।
बंजर

हो सकता है कि बस थोड़ा सा ध्यान दें, लेकिन सभी के लिए उल्लेख करने के लिए महत्वपूर्ण बिंदु: सुनिश्चित करें कि आप केवल कर्सर का उपयोग कर रहे हैं .execute () और एक कर्सर नहीं है । निष्पादित () कमांड से पहले .mogrify () , अन्यथा (जैसा कि मेरे मामले में) कर्सर है। () कोई परिणाम नहीं होगा! उस आदेश से पहले केवल " .execute " ( "कुछ भी" ) का उपयोग करके आप एक आईडी प्राप्त करेंगे।
TheHeroOfTime

14

मैं यहाँ समाप्त हुआ क्योंकि मुझे एक समान समस्या थी, लेकिन हम Postgres-XC का उपयोग कर रहे हैं, जो अभी तक RETURNING ID खंड का समर्थन नहीं करता है। उस स्थिति में आप उपयोग कर सकते हैं:

कर्सर.सेक्स्यूट ('INSERT INTO ........')
कर्सर.एक्सच्यूट ('सेलेक्ट लैसटीवील ()')
lastid = कर्सर.fetchone () ['lastval']

बस मामले में यह किसी के लिए उपयोगी था!


4
बस याद रखें - इसे दो बयानों में करना जैसे कि दौड़ की स्थिति का एक (बहुत छोटा) जोखिम होता है, यदि कोई चीज आपके बाद सीधे डेटाबेस में एक पंक्ति सम्मिलित करती है, लेकिन इससे पहले कि आपका अंतिम () कमांड अनुक्रम का वर्तमान मूल्य लौटाता है।
डेव थॉमस

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