एक sqlite डेटाबेस को क्वेरी करते समय आपको एक कर्सर बनाने की आवश्यकता क्यों है?


133

मैं पायथन के sqlite3 मॉड्यूल (और सामान्य रूप से उस मामले के लिए SQL) के लिए पूरी तरह से नया हूं , और यह बस मुझे पूरी तरह से रोकता है। cursorवस्तुओं के वर्णन का प्रचुर अभाव (बल्कि, उनकी आवश्यकता) भी अजीब लगता है।

कोड का यह टुकड़ा काम करने का पसंदीदा तरीका है:

import sqlite3
conn = sqlite3.connect("db.sqlite")
c = conn.cursor()
c.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()
c.close()

यह एक ऐसा नहीं है, भले ही यह (और बिना किसी बात के) के रूप में अच्छी तरह से काम करता है cursor:

import sqlite3
conn = sqlite3.connect("db.sqlite")
conn.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()

क्या कोई मुझे बता सकता है कि मुझे इसकी आवश्यकता क्यों है cursor?
यह सिर्फ व्यर्थ ओवरहेड की तरह लगता है। मेरी स्क्रिप्ट में प्रत्येक विधि के लिए जो एक डेटाबेस तक पहुँचती है, मैं बनाने और नष्ट करने वाला हूँ cursor?
सिर्फ connectionवस्तु का उपयोग क्यों नहीं ?

जवाबों:


60

बस एक गलत अमूर्त यह मुझे लगता है। एक db कर्सर एक एब्स्ट्रैक्शन है, जो डेटा सेट ट्रावेल के लिए है।

विषय पर विकिपीडिया लेख से :

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

तथा:

कर्सर का उपयोग न केवल DBMS से डेटा को एक एप्लिकेशन में लाने के लिए किया जा सकता है, बल्कि अपडेट या हटाए जाने के लिए तालिका में एक पंक्ति को पहचानने के लिए भी किया जा सकता है। एसक्यूएल: 2003 मानक अद्यतन को परिभाषित करता है और उस उद्देश्य के लिए एसक्यूएल स्टेटमेंट को हटाता है। इस तरह के बयान विधेय के साथ एक नियमित WHERE क्लॉज का उपयोग नहीं करते हैं। इसके बजाय, एक कर्सर पंक्ति को पहचानता है। कर्सर को खोला जाना चाहिए और पहले से ही FETCH स्टेटमेंट के माध्यम से एक पंक्ति में तैनात किया जाना चाहिए।

यदि आप पायथन साइक्लाइट मॉड्यूल पर डॉक्स की जांच करते हैं , तो आप देख सकते हैं कि एक बयान के cursorलिए भी एक अजगर मॉड्यूल की आवश्यकता होती है CREATE TABLE, इसलिए इसका उपयोग उन मामलों के लिए किया जाता है जहां एक मात्र connectionवस्तु को पर्याप्त होना चाहिए - जैसा कि ओपी द्वारा सही ढंग से बताया गया है। इस तरह की अमूर्तता लोगों को एक db कर्सर को समझने से अलग है और इसलिए, उपयोगकर्ताओं की ओर से भ्रम / निराशा। दक्षता के बावजूद, यह सिर्फ एक वैचारिक उपरि है। अच्छा होगा यदि यह डॉक्स में बताया गया था कि अजगर मॉड्यूल cursorSQL और डेटाबेस में एक कर्सर से थोड़ा अलग है।


7
+1 को स्वीकार करने के लिए (पहली बार में) "पारंपरिक" डीबी कर्सर और कर्सर के बीच इस्तेमाल होने वाले श्रापों के बीच बहुत उलझा हुआ अंतर
पॉल ड्रेपर


38

आपको परिणाम प्राप्त करने के लिए कर्सर ऑब्जेक्ट की आवश्यकता है। आपका उदाहरण काम करता है क्योंकि यह एक है INSERTऔर इस तरह आप किसी भी पंक्तियों को वापस पाने की कोशिश नहीं कर रहे हैं, लेकिन यदि आप sqlite3डॉक्स को देखते हैं , तो आप देखेंगे कि .fetchXXXXकनेक्शन ऑब्जेक्ट पर कोई विधियाँ नहीं हैं, इसलिए यदि आपने करने की कोशिश की है एक SELECTकर्सर के बिना, आपके पास परिणामी डेटा प्राप्त करने का कोई तरीका नहीं होगा।

कर्सर ऑब्जेक्ट्स आपको किस परिणाम सेट का ट्रैक रखने की अनुमति देते हैं, क्योंकि पहले के परिणाम प्राप्त करने से पहले कई प्रश्नों को चलाना संभव है।


5
यह भी ध्यान में रखने योग्य है: PEP 249execute एक कनेक्शन ऑब्जेक्ट पर परिभाषित नहीं करता है , यह एक sqlite3विस्तार है।
कैट प्लस प्लस

4
यह अभी भी सेलेक्ट स्टेटमेंट्स के साथ काम करता है: pastebin.com/5ZbhfEn7 । इसका कारण यह है कि आप कनेक्शन ऑब्जेक्ट पर किसी भी .fetchXXXX विधियों को कॉल नहीं कर रहे हैं, आप कनेक्शन के -execute () विधि द्वारा लौटाए गए ऑब्जेक्ट पर .fetchXXXX विधि को कॉल कर रहे हैं।
जैक बाउर

1
हाँ। लेकिन एक तरह से आप एक (प्रतीत होता है) अनावश्यक कर्सर के साथ समाप्त होते हैं जिसके साथ डेटाबेस क्वेरी करने के लिए: p
जैक बाउर

2
स्पष्ट रूप से शाप देने वालों का उपयोग करना एक अच्छी आदत है, क्योंकि संभवत: भविष्य की परियोजनाएं होंगी जहां आप काम करते हैं जहां चीजें ऑटो-कमिट नहीं होती हैं ।
अम्बर

1
काफी उचित। जानकारी के लिए धन्यवाद :)
जैक बाउर

36

आधिकारिक डॉक्स के अनुसार connection.execute()एक गैरमानक शॉर्टकट है जो एक मध्यवर्ती कर्सर ऑब्जेक्ट बनाता है:

Connection.execute
यह एक अमानक शॉर्टकट है जो कर्सर () विधि को कॉल करके कर्सर ऑब्जेक्ट बनाता है, दिए गए मापदंडों के साथ कर्सर के एग्जीक्यूट () विधि को कॉल करता है, और कर्सर लौटाता है।


19

12.6.8। Sqlite3 का उपयोग करते हुए कुशल ly

12.6.8.1। शॉर्टकट तरीकों का उपयोग करना

कनेक्शन ऑब्जेक्ट के गैर-मानक execute() , executemany()और executescript()विधियों का उपयोग करके , आपके कोड को अधिक संक्षिप्त रूप से लिखा जा सकता है क्योंकि आपको स्पष्ट रूप से (अक्सर सुपरफ्लस ) कर्सर ऑब्जेक्ट बनाने की आवश्यकता नहीं है । इसके बजाय, कर्सर ऑब्जेक्ट को स्पष्ट रूप से बनाया जाता है और ये शॉर्टकट तरीके कर्सर ऑब्जेक्ट को वापस करते हैं। इस तरह, आप एक सीधे स्टेटमेंट को निष्पादित कर सकते हैं और कनेक्शन ऑब्जेक्ट पर केवल एक कॉल का उपयोग करके सीधे उस पर पुनरावृति कर सकते हैं।

( sqlite3 प्रलेखन ; मेरा जोर;)

केवल कनेक्शन ऑब्जेक्ट का उपयोग क्यों नहीं किया जाता है?

क्योंकि कनेक्शन ऑब्जेक्ट के वे तरीके गैर - मानक हैं , अर्थात वे Python Database API Specification v2.0 (PEP 249) का हिस्सा नहीं हैं ।

जब तक आप कर्सर ऑब्जेक्ट के मानक तरीकों का उपयोग करते हैं, तब तक आप यह सुनिश्चित कर सकते हैं कि यदि आप उपरोक्त विनिर्देश के बाद किसी अन्य डेटाबेस कार्यान्वयन पर स्विच करते हैं, तो आपका कोड पूरी तरह से पोर्टेबल होगा। शायद आपको केवल बदलने की आवश्यकता होगीimport लाइन ।

लेकिन अगर आप उपयोग करते हैं connection.executeतो एक मौका है कि स्विचिंग सीधी नहीं होगी। cursor.executeइसके बजाए आप इसका उपयोग करना चाहते हैं ।

हालाँकि यदि आप निश्चित हैं कि आप स्विच करने नहीं जा रहे हैं, तो मैं कहूंगा कि connection.executeशॉर्टकट लेना और "कुशल" होना पूरी तरह से ठीक है ।


1

यह हमें डेटाबेस के लिए एक ही कनेक्शन के माध्यम से कई अलग-अलग कार्यशील वातावरण रखने की क्षमता देता है।

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