Я пытаюсь выполнить два запроса, один из которых находится в его собственном пуле подключений с указанием c user / pass (таблицы разных владельцев), и создать файл с результатом. Идея состоит в том, чтобы повысить производительность с помощью Oracle Pool и Multithread, поскольку в конечном проекте будет выполняться много запросов и генерироваться файлы для каждого запроса.
Но. Я сталкиваюсь с проблемой при попытке использовать Oracle SessionPool и многопоточность в Python. Я создаю пул с любой комбинацией мин / макс / приращение, и я всегда сталкиваюсь с ORA-24418 одним из потоков. Если я запускаю один поток, он работает хорошо.
Вот мой код (просто снят, но воспроизводит ошибку):
from datetime import datetime
from concurrent.futures.thread import ThreadPoolExecutor
import cx_Oracle
import pandas as pd
import random
import threading
def map_query(query):
try:
with oracle_pool.acquire(user=query.get("user"), password=query.get("pass")) as conn:
df = pd.read_sql(query.get("query"), conn)
df.to_csv(path_or_buf="files/file_{}.csv".format(random.choice([1, 2, 3, 4, 5])))
msg = "Success!"
except cx_Oracle.DatabaseError as err:
msg = str(err)
finally:
print("Thread {0} status: {1}\n Opened Session: {2}".format(threading.currentThread().getName(), msg, oracle_pool.opened))
oracle_pool = cx_Oracle.SessionPool(homogeneous=False,
dsn="localhost:1526/ORAHO005",
min=8,
max=8,
increment=0,
encoding="UTF-8",
threaded=True)
queries = [{"query": "select sysdate from dual", "user": "user", "pass": "user"},
{"query": "select systimestamp from dual", "user": "user2", "pass": "user2"}]
print("Starting... {0}".format(datetime.utcnow()))
with ThreadPoolExecutor(thread_name_prefix="testing") as pool:
pool.map(map_query, queries)
print("Finishing... {0}".format(datetime.utcnow()))
И это ошибка:
Starting... 2020-04-16 02:53:04.899688
Thread testing_0 status: ORA-24418: Cannot open further sessions.
Opened Session: 0
Thread testing_1 status: Success!
Opened Session: 1
Finishing... 2020-04-16 02:53:05.739701
Ошибка объясняется само собой, я пытался изменить параметры соединения, но даже при высоком значении (например, 60) ошибка все еще существует, даже при наличии только двух потоков (установка max_workers = 2 в ThreadPoolExecutor).
Я следовал Oracle официальной документации и провел поиск для использования многопоточности в Python.
Ссылки:
Oracle Github: https://github.com/oracle/python-cx_Oracle/blob/master/samples/Threads.py
cx_ Oracle do c: https://cx-oracle.readthedocs.io/en/latest/api_manual/session_pool.html
cx_ Oracle do c: https://cx-oracle.readthedocs.io/en/latest/user_guide/connection_handling.html#connection -pooling
Моя Python версия 3.8.2 и Oracle SDK 7.3.0 в ОС Win10.
Кто-нибудь сталкивался с этой проблемой или может увидеть то, что у меня нет? Я пытаюсь это сделать, но у меня нет опыта работы с многопоточностью. Я попробовал Oracle Pool и работал хорошо без многопоточности.
Заранее спасибо!