2016-01-04 4 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_map и after_map не пусты, поэтому Relation1 и Relation2 определенно кортежи в них. Тем не менее count и count2 равны 0, поэтому prod_row и before_row 'для петель' фактически не встречаются. Почему я не могу перебрать более Relation1 и Relation2 во второй раз?

ответ

1

При вызове execute на двигатель SQL алхимии, вы получите обратно в ResultProxy, которая является фасадом к DBAPI курсора по строкам ваши возвращает запрос.

После того, как вы итерацию по всем результатам ResultProxy, он автоматически закрывает курсор, лежащий в основе, так что вы не можете использовать результаты снова только итерацию над ним, так как documented on the SQLAlchemy page:

Возвращаемый результат является экземпляр ResultProxy, который ссылается на курсор DBAPI и обеспечивает в значительной степени совместимый интерфейс с интерфейсом курсора 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_map и after_map.

+0

Невозможно повторно открыть курсор? –

+0

@JeremyFisher - Насколько я знаю, SQL Alchemy/DBAPI не предлагает поддержку [прокручиваемых курсоров] (https://en.wikipedia.org/wiki/Cursor_%28databases%29#Scrollable_cursors), поэтому курсор вы вернуться назад - это дело «раз-и-забыть». – birryree

Смежные вопросы