为什么查询sqlite数据库时需要创建游标?
我对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()
这个不是,尽管它工作得同样好并且没有(看似毫无意义的)光标
:
import sqlite3
conn = sqlite3.connect("db.sqlite")
conn.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()
任何人都可以告诉我为什么我需要一个 <代码>光标?
这似乎是毫无意义的开销。对于我的脚本中访问数据库的每个方法,我应该创建和销毁一个游标
?
为什么不直接使用connection
对象呢?
I'm completely new to Python's sqlite3 module (and SQL in general for that matter), and this just completely stumps me. The abundant lack of descriptions of cursor
objects (rather, their necessity) also seems odd.
This snippet of code is the preferred way of doing things:
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()
This one isn't, even though it works just as well and without the (seemingly pointless) cursor
:
import sqlite3
conn = sqlite3.connect("db.sqlite")
conn.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()
Can anyone tell me why I need a cursor
?
It just seems like pointless overhead. For every method in my script that accesses a database, I'm supposed to create and destroy a cursor
?
Why not just use the connection
object?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在我看来,这只是一个误用的抽象概念。数据库游标是一个抽象,用于数据集遍历。
来自有关主题的维基百科文章:
和:
如果你检查Python sqlite模块的文档,你可以看到一个python模块即使对于
CREATE TABLE
语句也需要cursor
,因此它用于仅connection
对象就足够的情况 - 正如OP。这种抽象与人们对数据库游标的理解不同,因此,用户会感到困惑/沮丧。不管效率如何,这只是概念上的开销。如果在文档中指出 python 模块 Cursor 与 SQL 和数据库中的游标有点不同,那就太好了。Just a misapplied abstraction it seems to me. A db cursor is an abstraction, meant for data set traversal.
From Wikipedia article on subject:
And:
If you check the docs on Python sqlite module, you can see that a python module
cursor
is needed even for aCREATE TABLE
statement, so it's used for cases where a mereconnection
object should suffice - as correctly pointed out by the OP. Such abstraction is different from what people understand a db cursor to be and hence, the confusion/frustration on the part of users. Regardless of efficiency, it's just a conceptual overhead. Would be nice if it was pointed out in the docs that the python modulecursor
is bit different than what a cursor is in SQL and databases.根据官方 docs
connection.execute ()
是创建中间光标对象的非标准快捷方式:According to the official docs
connection.execute()
is a nonstandard shortcut that creates an intermediate cursor object:(sqlite3 文档;重点是我的。)
因为连接对象的那些方法是非标准,即它们不是 Python 数据库 API 规范 v2.0 (PEP 249) 的一部分。
只要您使用 Cursor 对象的标准方法,您就可以确信,如果您切换到遵循上述规范的另一个数据库实现,您的代码将是完全可移植的。也许您只需要更改
import
行。但如果您使用
connection.execute
,则切换可能不会那么简单。这就是您可能想要使用cursor.execute
的主要原因。但是,如果您确定不会进行切换,那么我认为采用
connection.execute
快捷方式并“高效”是完全可以的。(sqlite3 documentation; emphasis mine.)
Because those methods of the connection object are nonstandard, i.e. they are not part of Python Database API Specification v2.0 (PEP 249).
As long as you use the standard methods of the Cursor object, you can be sure that if you switch to another database implementation that follows the above specification, your code will be fully portable. Perhaps you will only need to change the
import
line.But if you use the
connection.execute
there is a chance that switching won't be that straightforward. That's the main reason you might want to usecursor.execute
instead.However if you are certain that you're not going to switch, I'd say it's completely OK to take the
connection.execute
shortcut and be "efficient".您需要一个游标对象来获取结果。您的示例之所以有效,是因为它是一个
INSERT
,因此您不会尝试从中获取任何行,但是如果您查看sqlite3
docs,您会注意到连接对象上没有任何.fetchXXXX
方法,因此如果您尝试执行SELECT
而不使用光标,您将无法获取结果数据。游标对象允许您跟踪哪个结果集是哪个,因为在获取第一个查询的结果之前可以运行多个查询。
You need a cursor object to fetch results. Your example works because it's an
INSERT
and thus you aren't trying to get any rows back from it, but if you look at thesqlite3
docs, you'll notice that there aren't any.fetchXXXX
methods on connection objects, so if you tried to do aSELECT
without a cursor, you'd have no way to get the resulting data.Cursor objects allow you to keep track of which result set is which, since it's possible to run multiple queries before you're done fetching the results of the first.
它使我们能够通过同一个数据库连接拥有多个独立的工作环境。
It gives us the ability to have multiple separate working environments through the same connection to the database.