2008-08-03 102 views
34

有几种方法可以遍历结果集。各方的权衡是什么?cx_Oracle:如何迭代结果集?

+1

有例外,但一般的经验法则是:如果有多种方法可以做到这一点,可能是因为每种方式都适用于不同的情况。否则只会有一种方法。 – 2012-05-23 02:13:52

回答

34

规范的方法是使用内置的游标迭代器。

curs.execute('select * from people') 
for row in curs: 
    print row 

您可以使用fetchall()一次获得所有行。

for row in curs.fetchall(): 
    print row 

它可以方便地使用它来创建一个包含值的Python列表返回:

curs.execute('select first_name from people') 
names = [row[0] for row in curs.fetchall()] 

这对于较小的结果集是有用的,但也有不好的副作用,如果结果集很大。

  • 您必须等待整个结果集返回到 您的客户端进程。

  • 你可能会吃掉你的客户端中的大量内存来保存 的内置列表。

  • Python可能需要一段时间来构建和解构您将立即丢弃的列表。


如果你知道有结果集中,你可以打电话fetchone()获得单行返回一行。

curs.execute('select max(x) from t') 
maxValue = curs.fetchone()[0] 

最后,您可以遍历结果集一次读取一行。一般来说,使用迭代器不会有什么特别的优势。

row = curs.fetchone() 
while row: 
    print row 
    row = curs.fetchone() 
+1

关于第二种方法,如果您使用SScursor?它会消耗很多内存吗? – Sylvain 2009-11-27 10:50:17

+0

我认为SScursor是针对MySQL的。但是任何具有fetchall()的东西都可能具有相同的内存使用情况,因为它会返回所有返回的行的列表。 – 2009-11-27 20:25:49

4

还有顺便psyco-pg似乎做...从我收集,似乎创造类似字典的行代理来查找键映射到该查询返回的内存块。在这种情况下,获取整个答案并在行上使用类似的代理工厂似乎是有用的想法。想想看,虽然感觉比Lua更像Lua。

而且,这应该是适用于所有PEP-249 DBAPI2.0接口,而不仅仅是甲骨文,还是你使用甲骨文意味着只是最快

21

我的首选方法是游标迭代器,但首先设置游标的arraysize属性。

curs.execute('select * from people') 
curs.arraysize = 256 
for row in curs: 
    print row 

在这个例子中,cx_Oracle将256行,在一个时间内获取从Oracle行,减少了需要进行网络往返次数