Задача: в файле экселя набиты запросы к БД. Запросы идут к нескольким (>100) серверам одновременно. Время ответа от серверов разное.
Что пытаюсь: открыть 1 раз файл экселя, запустить потоки для чтения и выполнения запросов по каждому серверу (1 поток = 1 сервер, при выполнении не ждет соседа)
Вопросы:
- как использовать единственный экземпляр источника запросов ?
- использует ли эксель какой-то курсор внутри себя для доступа к данным ячеек ? Можно ли использовать несколько потоков для доступа в разные места одного файла экселя ?
- или технология в принципе неудачная ?
# coding: cp1251 from win32com.client import Dispatch import cx_Oracle import pythoncom import fdb import datetime import sys import threading import pprint import time data_n="'01.01.2014'" data_y="'01.01.2013'" res_spaces_queue=[] ora_mutex=threading.Lock() def xls(id,target_host,Sheet,x,y,sql): try: pythoncom.CoInitialize() # подключаемся к целевому серверу с данными и получаем сами данные ora_con = cx_Oracle.connect("orauser/orapass@"+target_host+"/XE",threaded=True) ora_cur = ora_con.cursor() ora_cur.execute(r"alter session set NLS_DATE_FORMAT = 'DD.MM.YYYY'") ora_cur.execute(sql) for result in ora_cur: ora_mutex.acquire() # записываем результат в запасник res_spaces_queue.append([id,result[0],str(start_time),str(datetime.datetime.now()-start_time)]) ora_mutex.release() ora_cur.close() ora_con.close() except Exception as e1: print(str(id)+" fun error:","Line "+format(sys.exc_info()[-1].tb_lineno),e1.__str__()) finally: pythoncom.CoUninitialize() #================================================================== def main(argv=None): # получаем из посторонней БД данные по параметрам подключения к серверам данных. так получается :) fb_conn = fdb.connect(dsn='firebird:d:\\NET_ANALISYS.FDB',user='fbuser',password='fbpass') fb_cur = fb_conn.cursor() SELECT=r"SELECT p.gissz_num,p.lanaddress FROM points p" fb_cur.execute(SELECT) # открываем сам эксель-файл xlApp = Dispatch("Excel.Application") xlApp.Visible=True xlWb = xlApp.Workbooks.Open(r"d:\documents\sql.xlsx") try: # пробегаем по списку серверов из БД for row in fb_cur.fetchall(): # перебираем листы в excel for Sheet in xlWb.WorkSheets: # перебираем столбцы в листе excel for y in range(8,12): # перебираем строки в листе excel for x in range(4,12): # мелкий анализ и исправление данных в целевой ячейке sql=Sheet.Cells(y,x).Formula.upper().strip() sql=sql.replace(":DATA_N",data_n) sql=sql.replace(":DATA_Y",data_y) if sql.find('SELECT ')==0: # перебираем столбцы в листе excel t = threading.Thread(target=xls,name='id'+str(row[0]),args=(row[0],row[1],Sheet.Name,x,y,sql)) t.start() while threading.activeCount()>1: if threading.activeCount()<2: print(datetime.datetime.now(),threading.enumerate(),"\n------------",) time.sleep(3) except Exception as e3: print("main try:","Line "+format(sys.exc_info()[-1].tb_lineno),e3.__str__()) xlApp.Quit() #========================================== if __name__ == "__main__": main()