游标在 Python 的 DB-API 中是如何工作的?
Posted
技术标签:
【中文标题】游标在 Python 的 DB-API 中是如何工作的?【英文标题】:How do cursors work in Python's DB-API? 【发布时间】:2010-10-02 01:05:27 【问题描述】:我一直在使用 python 和 RDBMS'(mysql 和 PostgreSQL),我注意到我真的不明白如何使用游标。
通常,他的脚本通过客户端 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 可以以某种方式优化执行多次但具有不同值的命令,如何以及是否值得?
谢谢
【问题讨论】:
Re:游标的最佳实践,来自常见问题解答 (initd.org/psycopg/docs/faq.html):“我们的建议是几乎总是创建一个新游标并在不再需要数据时立即处理旧游标(致电close() 。)唯一的例外是紧密循环,其中一个通常使用相同的光标来处理一大堆 INSERT 或 UPDATE。" 【参考方案1】:是的,我知道它已经几个月大了:P
DB-API 的游标似乎与 SQL 游标非常相似。就 AFA 资源(行)管理而言,DB-API 没有指定客户端是必须检索所有行还是声明一个实际的 SQL 游标。只要 fetchXXX 接口做他们应该做的,DB-API 就很高兴。
涉及到 AFA psycopg2 游标(您可能很清楚),“未命名的 DB-API 游标”将获取整个结果集——由 libpq 缓冲在内存中的 AFAIK。 “命名 DB-API 游标”(一个可能不可移植的 psycopg2 概念)将按需请求行(fetchXXX 方法)。
正如“unbeknown”所引用的,executemany 可用于优化同一命令的多次运行。但是,它不能满足准备好的语句的需要;当具有不同参数集的语句的重复执行不是直接连续的时,executemany() 将与 execute() 一样执行。 DB-API 确实“提供”了驱动程序作者缓存已执行语句的能力,但它的实现(语句的范围/生命周期是多少?)是未定义的,因此不可能在 DB-API 实现之间设置期望。
如果您将大量数据加载到 PostgreSQL 中,我强烈建议您尝试找到一种使用 COPY 的方法。
【讨论】:
【参考方案2】:假设您使用的是 PostgreSQL,游标可能只是使用数据库的本地游标 API 实现的。您可能想查看pg8000 的源代码,这是一个纯 Python PostgreSQL DB-API 模块,以了解它如何处理游标。您可能还想查看the PostgreSQL documentation for cursors。
【讨论】:
【参考方案3】:当您查看mysqldb documentation 时,您会发现他们为游标实施了不同的策略。所以一般的答案是:视情况而定。
编辑:这是mysqldb API documentation。有一些关于每种游标类型如何表现的信息。标准游标将结果集存储在客户端中。因此,我假设如果您不检索所有结果行,则会产生开销,因为即使您不获取的行也必须传输到客户端(可能通过网络)。我的猜测是它和 postgresql 没有什么不同。
当您想要优化使用多个值重复调用的 SQL 语句时,您应该查看 cursor.executemany()。它准备了一条 SQL 语句,这样就不需要每次调用它时都对其进行解析:
cur.executemany('INSERT INTO mytable (col1, col2) VALUES (%s, %s)',
[('val1', 1), ('val2', 2)])
【讨论】:
以上是关于游标在 Python 的 DB-API 中是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章
python DBUtils 线程池 连接 Postgresql(多线程公用线程池,DB-API : psycopg2)
Python操作MySQL数据库—pymysql库(可直接使用的模板通用操作)