31

我一直在使用带有 RDBMS(MySQL 和 PostgreSQL)的 python,我注意到我真的不明白如何使用游标。

通常,他的脚本通过客户端 DB-API(如 psycopg2 或 MySQLdb)连接到数据库:

connection = psycopg2.connect(host='otherhost', etc)

然后创建一个游标:

cursor = connection.cursor()

然后可以发出查询和命令:

cursor.execute("SELECT * FROM etc")

现在查询的结果在哪里,我想知道?它在服务器上吗?还是在我的客户端上一点点在我的服务器上一点点?然后,如果我们需要访问一些结果,我们获取它们:

rows = cursor.fetchone() 

或者

rows = cursor.fetchmany()

现在让我们说,我没有检索所有行,并决定执行另一个查询,以前的结果会发生什么?是他们的开销。

另外,我是否应该为每种形式的命令创建一个游标并以某种方式不断地将其重用于相同的命令?我负责 psycopg2 可以以某种方式优化执行多次但具有不同值的命令,它是如何以及值得的?

谢谢

4

3 回答 3

7

是的,我知道它已经几个月大了:P

DB-API 的游标似乎与 SQL 游标非常相似。就 AFA 资源(行)管理而言,DB-API 没有指定客户端是必须检索所有行还是声明一个实际的 SQL 游标。只要 fetchXXX 接口做他们应该做的,DB-API 就很高兴。

关注 AFA psycopg2 游标(您可能很清楚),“未命名的 DB-API 游标”将获取整个结果集——由 libpq 缓冲在内存中的 AFAIK。“命名 DB-API 游标”(可能不可移植的 psycopg2 概念)将按需请求行(fetchXXX 方法)。

正如“未知”所引用的,executemany 可用于优化同一命令的多次运行。但是,它不能满足准备好的语句的需要;当具有不同参数集的语句的重复执行不是直接顺序时,executemany() 将与 execute() 一样执行。DB-API 确实“为”驱动程序作者提供了缓存执行语句的能力,但它的实现(语句的范围/生命周期是多少?)是未定义的,因此不可能跨 DB-API 实现设置期望。

如果您将大量数据加载到 PostgreSQL 中,我强烈建议您尝试找到一种使用 COPY 的方法。

于 2009-06-09T00:57:50.203 回答
2

假设您使用的是 PostgreSQL,游标可能只是使用数据库的本机游标 API 实现的。您可能想查看pg8000的源代码,这是一个纯 Python PostgreSQL DB-API 模块,以了解它如何处理游标。您可能还想查看PostgreSQL 文档以了解 cursors

于 2009-01-18T00:09:48.157 回答
1

当您在此处查看mysqldb 文档时,您可以看到它们为游标实现了不同的策略。所以一般的答案是:这取决于。

编辑:这是mysqldb API 文档。有一些关于每种游标类型如何表现的信息。标准游标将结果集存储在客户端中。因此,我假设如果您不检索所有结果行,则会产生开销,因为即使您不获取的行也必须传输到客户端(可能通过网络)。我的猜测是它与 postgresql 没有什么不同。

当您想要优化使用许多值重复调用的 SQL 语句时,您应该查看 cursor.executemany()。它准备了一条 SQL 语句,这样就不需要每次调用它时都对其进行解析:

cur.executemany('INSERT INTO mytable (col1, col2) VALUES (%s, %s)',
                [('val1', 1), ('val2', 2)])
于 2009-01-18T08:38:08.363 回答