2016-01-04 69 views
0

我查询两个数据库以获得两个关系。我对这些关系进行过一次形成地图的演练,然后再进行一些计算。但是,当我第二次尝试迭代相同的关系时,我发现实际上没有发生迭代。下面是代码:多次对表进行迭代Python SQLAlchemy

dev_connect = dev_engine.connect() 
prod_connect = prod_engine.connect() # from a different database 
Relation1 = dev_engine.execute(sqlquery1) 
Relation2 = prod_engine.execute(sqlquery) 

before_map = {} 
after_map = {} 
for row in Relation1: 
    before_map[row['instrument_id']] = row 
for row2 in Relation2: 
    after_map[row2['instrument_id']] = row2 

update_count = insert_count = delete_count = 0 

change_list = [] 
count =0 
for prod_row in Relation2: 
    count += 1 
    result = list(prod_row) 
    ... 
    change_list.append(result) 

count2 = 0 
for before_row in Relation1: 
    count2 += 1 
    result = before_row 
    ... 

print count, count2 # prints 0 

before_mapafter_map不是空的,所以Relation1Relation2肯定有他们的元组。然而,countcount2为0,所以prod_rowbefore_row'for循环'实际上并未发生。为什么我不能第二次迭代Relation1Relation2

回答

1

当您在SQL Alchemy引擎上调用execute时,您会收到一个ResultProxy,这是DBAPI游标到您的查询返回的行的外观。

返回的结果是:

一旦你遍历ResultProxy的所有结果,所以你不能仅仅通过遍历它再次使用的结果,因为documented on the SQLAlchemy page自动关闭的根本指针ResultProxy的实例,它引用了一个DBAPI游标,并提供了一个与游标光标基本兼容的界面。当所有结果行(如果有)用尽时,DBAPI游标将被ResultProxy关闭。

你能解决你的问题了几个方面:

  • 商店在list结果。只要做对行的list -comprehension返回:

    Relation1 = dev_engine.execute(sqlquery1) 
    relation1_items = [r for r in Relation1] 
    # ... 
    # now you can iterate over relation1_items as much as you want 
    
  • 你通过返回的每一行集需要在一次通过的一切。我不知道这个选项对您是否可行,因为我不知道您的计算的全部范围是否需要在您的before_mapafter_map对象之间进行交叉引用。

+0

有没有办法重新打开游标? –

+0

@JeremyFisher - 据我所知,SQL Alchemy/DBAPI不支持[可滚动游标](https://en.wikipedia.org/wiki/Cursor_%28databases%29#Scrollable_cursors),所以你的光标回来是一次使用而忘记的交易。 – birryree