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

Jac*_*uer 120 python sqlite cursor

我完全不熟悉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()
Run Code Online (Sandbox Code Playgroud)

这个不是,即使它工作得很好而没有(看似毫无意义)cursor:

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

谁能告诉我为什么需要一个cursor
这看起来似乎毫无意义.对于我的脚本中访问数据库的每个方法,我应该创建并销毁一个cursor
为什么不直接使用该connection对象?

Bas*_*ani 54

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

来自维基百科关于主题的文章:

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

和:

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

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

  • +1用于确认"传统"db游标与Python中用于db的游标之间(首先)非常混乱的区别 (7认同)
  • 实际上,人们可以简单地[即使不使用游标也可以创建表](https://xania.org/200711/python-sqlite-gotcha)。 (2认同)

Amb*_*ber 32

您需要一个游标对象来获取结果.你的例子是有效的,因为它是一个INSERT,因此你不是试图从中获取任何行,但是如果你查看sqlite3文档,你会注意到.fetchXXXX连接对象上没有任何方法,所以如果你试图做如果SELECT没有光标,您将无法获得结果数据.

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

  • 另外值得记住的是:[PEP 249](http://www.python.org/dev/peps/pep-0249/)没有在连接对象上定义`execute`,这是一个`sqlite3`扩展. (5认同)
  • 它仍然适用于SELECT语句:http://pastebin.com/5ZbhfEn7.原因是您没有在连接对象上调用任何.fetchXXXX方法,而是在连接的.execute()方法返回的对象上调用.fetchXXXX方法. (4认同)
  • 明确地使用游标是一个很好的习惯,因为你将来可能会从事一些*不*自动提交的项目。 (3认同)

use*_*ser 31

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

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


AXO*_*AXO 16

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快捷方式并且"高效" 是完全可以的.


小智 5

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