ทำไมคุณต้องสร้างเคอร์เซอร์เมื่อทำการค้นหาฐานข้อมูล sqlite?


133

ฉันยังใหม่กับโมดูล sqlite3 ของ Python (และ 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 เป็นนามธรรมที่มีไว้สำหรับการส่งผ่านชุดข้อมูล

จากบทความ Wikipedia เรื่อง :

ในวิทยาการคอมพิวเตอร์และเทคโนโลยีเคอร์เซอร์ของฐานข้อมูลเป็นโครงสร้างควบคุมที่ช่วยให้สามารถข้ามผ่านระเบียนในฐานข้อมูลได้ เคอร์เซอร์อำนวยความสะดวกในการประมวลผลในภายหลังร่วมกับการส่งผ่านเช่นการดึงข้อมูลการเพิ่มและการลบบันทึกฐานข้อมูล ลักษณะเคอร์เซอร์ฐานข้อมูลของการข้ามผ่านทำให้เคอร์เซอร์คล้ายกับแนวคิดภาษาโปรแกรมของตัววนซ้ำ

และ:

ไม่เพียง แต่สามารถใช้เคอร์เซอร์เพื่อดึงข้อมูลจาก DBMS ไปยังแอปพลิเคชันเท่านั้น แต่ยังใช้เพื่อระบุแถวในตารางที่จะอัปเดตหรือลบ มาตรฐาน SQL: 2003 กำหนดการอัปเดตตำแหน่งและวางคำสั่งลบ SQL สำหรับวัตถุประสงค์นั้น ข้อความดังกล่าวไม่ใช้ประโยค WHERE ปกติกับเพรดิเคต เคอร์เซอร์จะระบุแถวแทน ต้องเปิดเคอร์เซอร์และวางตำแหน่งบนแถวโดยใช้คำสั่ง FETCH

หากคุณตรวจสอบเอกสารในโมดูล Python sqliteคุณจะเห็นว่าcursorจำเป็นต้องใช้โมดูล python สำหรับCREATE TABLEคำสั่งดังนั้นจึงใช้สำหรับกรณีที่connectionวัตถุเพียงอย่างเดียวควรเพียงพอ - ตามที่ OP ชี้ให้ถูกต้อง สิ่งที่เป็นนามธรรมดังกล่าวแตกต่างจากสิ่งที่ผู้คนเข้าใจว่าเคอร์เซอร์ db เป็นดังนั้นความสับสน / ความยุ่งยากในส่วนของผู้ใช้ โดยไม่คำนึงถึงประสิทธิภาพเป็นเพียงค่าใช้จ่ายในแนวคิด จะดีถ้ามีการระบุในเอกสารว่าโมดูล python cursorนั้นแตกต่างจากเคอร์เซอร์ใน SQL และฐานข้อมูลเล็กน้อย


7
+1 สำหรับการรับทราบความแตกต่างที่สับสนมาก (ในตอนแรก) ระหว่างเคอร์เซอร์ db "ดั้งเดิม" กับเคอร์เซอร์ที่ใช้สำหรับ db ใน Python
Paul Draper


38

คุณต้องมีวัตถุเคอร์เซอร์เพื่อดึงผลลัพธ์ ตัวอย่างของคุณใช้งานได้เพราะเป็นINSERTและทำให้คุณไม่ได้พยายามดึงแถวใด ๆ กลับมา แต่ถ้าคุณดูsqlite3เอกสารคุณจะสังเกตเห็นว่าไม่มี.fetchXXXXวิธีการใด ๆในวัตถุการเชื่อมต่อดังนั้นหากคุณพยายามทำSELECTโดยไม่ต้องเคอร์เซอร์ที่คุณจะมีวิธีการที่จะได้รับข้อมูลที่เกิดไม่มี

วัตถุเคอร์เซอร์ช่วยให้คุณสามารถติดตามได้ว่าชุดผลลัพธ์ใดเป็นชุดใดเนื่องจากเป็นไปได้ที่จะเรียกใช้แบบสอบถามหลายรายการก่อนที่คุณจะดึงผลลัพธ์ของรายการแรกเสร็จสิ้น


5
สิ่งที่ควรคำนึงถึง: PEP 249ไม่ได้กำหนดexecuteบนวัตถุการเชื่อมต่อนี่คือsqlite3ส่วนขยาย
Cat Plus Plus

4
มันก็ยังคงทำงานร่วมกับงบ SELECT: pastebin.com/5ZbhfEn7 สาเหตุที่คุณไม่ได้เรียกใช้เมธอด .etchXXXX ใด ๆ บนอ็อบเจ็กต์การเชื่อมต่อคุณกำลังเรียกใช้เมธอด. fetchXXXX บนอ็อบเจ็กต์ที่ส่งคืนโดยเมธอด. execute () ของการเชื่อมต่อ
Jack Bauer

1
ใช่. แต่วิธีหนึ่งที่คุณจะจบลงด้วยเคอร์เซอร์ที่ไม่จำเป็น (ดูเหมือน) เพื่อค้นหาฐานข้อมูล: p
Jack Bauer

2
การใช้เคอร์เซอร์อย่างชัดเจนเป็นนิสัยที่ดีในการทำความเข้าใจเนื่องจากอาจมีโครงการในอนาคตที่คุณกำลังดำเนินการอยู่โดยที่สิ่งต่างๆไม่ใช่การคอมมิตอัตโนมัติ
Amber

1
พอใช้. ขอบคุณสำหรับข้อมูล :)
Jack Bauer

36

ตามเอกสาร อย่างเป็นทางการconnection.execute()คือทางลัดที่ไม่เป็นมาตรฐานที่สร้างวัตถุเคอร์เซอร์กลาง:

Connection.execute
นี่คือช็อตคัทที่ไม่เป็นมาตรฐานที่สร้างวัตถุเคอร์เซอร์โดยการเรียกใช้ cursor () เมธอดเรียกใช้ cursor's execute () method พร้อมกับพารามิเตอร์ที่กำหนดและส่งกลับเคอร์เซอร์


19

12.6.8 ใช้ sqlite3 อย่างมีประสิทธิภาพ ly

12.6.8.1 ใช้วิธีลัด

การใช้ที่ไม่เป็นมาตรฐาน execute() , executemany()และexecutescript()วิธีการของการเชื่อมต่อวัตถุโค้ดของคุณสามารถเขียนได้กระชับมากขึ้น Ly เพราะคุณไม่ต้องสร้าง (มักจะฟุ่มเฟือย ) เคอร์เซอร์วัตถุอย่างชัดเจน แต่วัตถุเคอร์เซอร์จะถูกสร้างขึ้นโดยปริยายและวิธีทางลัดเหล่านี้จะส่งคืนวัตถุเคอร์เซอร์ ด้วยวิธีนี้คุณสามารถเรียกใช้คำสั่ง SELECT และวนซ้ำได้โดยตรงโดยใช้การเรียกเพียงครั้งเดียวบนวัตถุ Connection

( เอกสาร sqlite3 ; เน้นเหมือง)

ทำไมไม่ใช้แค่วัตถุเชื่อมต่อล่ะ?

เนื่องจากวิธีการเหล่านั้นของอ็อบเจ็กต์การเชื่อมต่อไม่เป็นมาตรฐานกล่าวคือไม่ได้เป็นส่วนหนึ่งของPython Database API Specification v2.0 (PEP 249)

ตราบเท่าที่คุณใช้วิธีการมาตรฐานของวัตถุเคอร์เซอร์คุณสามารถมั่นใจได้ว่าหากคุณเปลี่ยนไปใช้ฐานข้อมูลอื่นที่เป็นไปตามข้อกำหนดข้างต้นรหัสของคุณจะพกพาได้อย่างสมบูรณ์ บางทีคุณอาจจะต้องเปลี่ยนimportสายเท่านั้น

แต่ถ้าคุณใช้connection.executeมีโอกาสที่การสลับจะไม่ตรงไปตรงมา นั่นเป็นเหตุผลหลักที่คุณอาจต้องการใช้cursor.executeแทน

อย่างไรก็ตามหากคุณมั่นใจว่าจะไม่เปลี่ยนฉันว่ามันเป็นเรื่องปกติที่จะใช้connection.executeทางลัดและ "มีประสิทธิภาพ"


1

ช่วยให้เราสามารถมีสภาพแวดล้อมการทำงานที่แยกจากกันได้หลายแบบผ่านการเชื่อมต่อกับฐานข้อมูลเดียวกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.