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


133

我对Python的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对象?

Answers:


60

在我看来,这只是一个错误应用的抽象。数据库游标是一种抽象,用于遍历数据集。

维基百科有关主题的文章

在计算机科学和技术中,数据库游标是一种控制结构,可以遍历数据库中的记录。游标有助于与遍历一起进行的后续处理,例如数据库记录的检索,添加和删除。数据库游标的遍历特性使游标类似于迭代器的编程语言概念。

和:

游标不仅可以用于将数据从DBMS提取到应用程序中,还可以标识表中要更新或删除的行。为此,SQL:2003标准定义了定位更新和定位删除SQL语句。这样的语句不使用带谓词的常规WHERE子句。而是用光标标识该行。游标必须已打开,并且已经通过FETCH语句定位在一行上。

如果查看Python sqlite模块上文档,您会发现cursor即使是一条CREATE TABLE语句也需要一个python模块,因此它用于仅一个connection对象就足够的情况-正如OP正确指出的那样。这种抽象与人们理解db游标的方式不同,因此与用户的困惑/挫败感不同。无论效率如何,这只是概念上的开销。如果在文档中指出python模块cursor与SQL和数据库中的游标有点不同,那将是很好的。


7
+1用于承认“传统”数据库游标与Python中用于数据库的游标之间的(起初)非常令人困惑的区别
Paul Draper

3
实际上,即使不使用游标,也可以简单地创建表
Serge Stroobandt

38

您需要一个游标对象来获取结果。您的示例可以正常运行,因为它是一个INSERT,因此您没有尝试从中获取任何行,但是如果您查看sqlite3docs,则会注意到.fetchXXXX连接对象上没有任何方法,因此,如果您尝试这样做如果SELECT没有光标,您将无法获取结果数据。

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


5
同样要记住:PEP 249execute在连接对象上定义,这是sqlite3扩展。
Cat Plus Plus

4
它仍然适用于SELECT语句:pastebin.com/5ZbhfEn7。原因是您没有在连接对象上调用任何.fetchXXXX方法,而是在由连接的.execute()方法返回的对象上调用了.fetchXXXX方法。
Jack Bauer

1
是。但是,您最终会得到一个(看似)不必要的游标来查询数据库:p
Jack Bauer

2
明确使用游标是一个很好的习惯进入,因为有可能会是你的东西在哪里工作,未来的项目自动提交。
琥珀

1
很公平。感谢您提供的信息:)
Jack Bauer

36

根据官方文档,这 connection.execute()是一个创建中间光标对象的非标准快捷方式

Connection.execute
这是一个非标准的快捷方式,它通过调用cursor()方法创建游标对象,使用给定的参数调用游标的execute()方法,然后返回游标。


19

12.6.8。使用sqlite3的高效 LY

12.6.8.1。使用快捷方式

使用非标准的 execute()executemany()并且executescript()Connection对象的方法,您可以编写代码更简洁 LY,因为你没有创建(通常是多余的)光标明确对象。而是,隐式创建Cursor对象,并且这些快捷方式方法返回游标对象。这样,您可以执行SELECT语句并直接使用Connection对象上的单个调用直接对其进行迭代。

sqlite3文档;重点是我的。)

为什么不只使用连接对象?

因为连接对象的那些方法是非标准的,即它们不是Python数据库API规范v2.0(PEP 249)的一部分。

只要您使用Cursor对象的标准方法,就可以确保如果切换到遵循上述规范的另一个数据库实现,您的代码将完全可移植。也许您只需要更改import行。

但是,如果您使用connection.execute,切换的可能性将不会那么简单。这就是您可能要使用的主要原因cursor.execute

但是,如果您确定不打算切换,那么我想选择connection.execute快捷方式并“高效” 是完全可以的。


1

它使我们能够通过与数据库的同一连接来拥有多个单独的工作环境。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.