为什么查询sqlite数据库时需要创建游标?

2024-05-12 19:30:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Python's sqlite3 module(通常是SQL)还不太熟悉,这完全让我难堪。对^{} objects(更确切地说,是它们的必要性)的大量描述的缺乏也显得很奇怪。

这段代码是首选的操作方式:

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对象呢?


Tags: importexecutedbsqliteconnecttableconnusers
3条回答

根据官方的docsconnection.execute()是一个创建中间游标对象的非标准快捷方式:

Connection.execute
This is a nonstandard shortcut that creates a cursor object by calling the cursor() method, calls the cursor’s execute() method with the parameters given, and returns the cursor.

在我看来,这只是一个误用的抽象概念。db游标是一个抽象,用于数据集遍历。

来自Wikipedia article on subject

In computer science and technology, a database cursor is a control structure that enables traversal over the records in a database. Cursors facilitate subsequent processing in conjunction with the traversal, such as retrieval, addition and removal of database records. The database cursor characteristic of traversal makes cursors akin to the programming language concept of iterator.

以及:

Cursors can not only be used to fetch data from the DBMS into an application but also to identify a row in a table to be updated or deleted. The SQL:2003 standard defines positioned update and positioned delete SQL statements for that purpose. Such statements do not use a regular WHERE clause with predicates. Instead, a cursor identifies the row. The cursor must be opened and already positioned on a row by means of FETCH statement.

如果您检查docs on Python sqlite module,您可以看到甚至对于CREATE TABLE语句也需要一个python模块cursor,因此它被用于仅需要connection对象就足够的情况-正如OP正确指出的那样。这种抽象不同于人们理解的db游标,因此,用户的困惑/沮丧。不管效率如何,这只是一个概念性的开销。如果在文档中指出python模块cursor与SQL和数据库中的游标有点不同,那就太好了。

您需要一个游标对象来获取结果。您的示例之所以有效,是因为它是一个INSERT,因此您不会试图从中获取任何行,但是如果您查看^{} docs,您会注意到在连接对象上没有任何.fetchXXXX方法,因此如果您尝试在没有游标的情况下执行SELECT,您将无法获取结果数据。

游标对象允许您跟踪哪个结果集是哪个,因为在获取第一个结果集的结果之前可以运行多个查询。

相关问题 更多 >