# Выполнение_запроса_по_списку_БД ## Настройка Python В Python версии 3.7 и выше дополнительно необходимо установить `pip install oracledb, pip install pandas, pip install requests, pip install openpyxl`. В Python версии 3.7 и выше cx_oracle не работает, нужен oracledb, при необходимости запуска на Python 3.0-3.7 заменить oracledb на cx_oracle ## Python 3.7+ Параллельный запуск запроса или скрипта ```python= import oracledb import threading from pandas import DataFrame import datetime import os import requests ########################################################################################## ### Список переменных, которые нужно изменить ### ########################################################################################## # Директория с клиентом Oracle oracledb.init_oracle_client(lib_dir=r"D:\instantclient_21_11") # Запрос или скрипт в txt файле, который нужно выполнять QUERY = open('qry/hidden_par_val.sql').read() # Режим выполнения: # 0 - выполнение запроса, 1 - выполнение скрипта execution_mode = 0 # Режим получения списка баз данных: # 0 - получение из файла, 1 - получение всех актуальных БД через HTTP-запрос к CDMS db_list_mode = 1 # Файл с списком БД для db_list_mode=0 BASELIST = open('bases/baselist.txt').readlines() # Токен для подключения к CDMS для db_list_mode=1 api_token = "cdmt@pve!" # Логин и пароль для подключения к БД Oracle or_usr = 'sys' or_pas = '' ########################################################################################## ### Далее ничего менять не нужно. Результат выполнения будет сохранён в excel файл ### ### в директорию output с именем - script_res или query_res и текущей датой ### ########################################################################################## # Функция для получения списка баз данных через HTTP-запрос к CDMS def get_oracle_bases_from_http(): db_url = "https://cdms.colvir.ru/api/getactualdb" headers = { "Content-Type": "application/json", "Accept": "application/json" } payload = { "api_token": api_token } try: print("Получаем список БД через API") response = requests.get( db_url, headers=headers, json=payload ) response.raise_for_status() data = response.json() print(f"HTTP Status Code: {response.status_code}") return [item['con_str'] for item in data] except requests.exceptions.RequestException as e: print(f"Ошибка при выполнении HTTP-запроса: {e}") return [] except ValueError as ve: print(f"Ошибка декодирования JSON: {ve}") return [] except KeyError as ke: print(f"Ошибка в структуре ответа: отсутствует ключ {ke}") return [] #Очистка экрана def cls(): os.system('cls' if os.name=='nt' else 'clear') #выполнение запроса или скрипта def exec_qry(idx, con_str): print(f"Поток {idx}: обработка {con_str}".ljust(80), end='\r') try: exc = ' ' val = ' ' # Условие для установки режима SYSDBA только для пользователя 'sys' if or_usr.lower() == 'sys': con = oracledb.connect(user=or_usr, password=or_pas, dsn=con_str, mode=oracledb.SYSDBA) else: con = oracledb.connect(user=or_usr, password=or_pas, dsn=con_str) cur = con.cursor() cur.execute(QUERY) # Выполнение запроса if execution_mode == 0: for result in cur: val = ';'.join(map(str, result)) # Выполнение скрипта else: val = 'Ok' cur.close() con.close() except oracledb.DatabaseError as e: error_obj, = e.args exc = error_obj.message finally: base_list.append(con_str) value_list.append(val) except_list.append(exc) return #Основной код cls() # Получение списка баз данных BASES = BASELIST if db_list_mode == 0 else get_oracle_bases_from_http() if len(BASES) == 0: print("Нет БД для обработки. Выходим") exit() else: print(f"Список БД получен, количество БД в списке: {len(BASES)}") print("Запускаем многопоточную обработку") base_list, value_list, except_list = [], [], [] # Запуск потоков для каждой базы данных threads = list() for BASE in BASES: idx = len(threads) x = threading.Thread(target=exec_qry, args=(idx, BASE.strip(),)) threads.append(x) x.start() print(f"Все потоки запущены. Количество запущенных потоков:{idx+1}") for index, thread in enumerate(threads): print(f"Основной поток: ожидаем ответ потока #{index} для БД {BASES[index].strip()}".ljust(80), end='\r') thread.join() print() print(f"Закончили, формируем excel файл ") # Генерация имени выходного файла и создание директории, если её нет os.makedirs('output', exist_ok=True) output_prefix = 'script_res' if execution_mode == 1 else 'query_res' date_str = datetime.datetime.now().strftime('%Y%m%d') output_filename = f"{output_prefix}-{date_str}-1.xlsx" # Проверка на существование файла counter = 1 while os.path.exists(f"output/{output_filename}"): counter += 1 output_filename = f"{output_prefix}-{date_str}-{counter}.xlsx" df = DataFrame({'База': base_list, 'Результат': value_list, 'Исключение': except_list}) df.to_excel(f'output/{output_filename}', sheet_name='sheet1', index=False) print(f"Excel файл сформирован: output/{output_filename}") ```