parse_saby/app/working_database.py

132 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from os import environ
import hvac
import hvac.exceptions
from oracledb import Error, create_pool, init_oracle_client
import error_to_log
init_oracle_client()
class WorkingDB:
def __init__(self):
print('-'*60)
print("Инициализация WorkingDB")
self._create_db_pool_from_vault()
self.pool
print('-'*60)
def _handle_vault_exception(self, e: Exception, message: str):
"""
Обработка исключений Vault с возвратом понятного сообщения.
"""
error_to_log.write_to_log(message)
ind = {' '*4}
if isinstance(e, hvac.exceptions.InvalidPath):
raise hvac.exceptions.InvalidPath(f"{ind}Database configuration not found in Vault")
elif isinstance(e, hvac.exceptions.Forbidden):
raise hvac.exceptions.Forbidden(f"{ind}Permission denied to access Vault secrets")
elif isinstance(e, hvac.exceptions.Unauthorized):
raise hvac.exceptions.Unauthorized(f"{ind}Invalid Vault token")
elif isinstance(e, hvac.exceptions.VaultError):
raise hvac.exceptions.VaultError(f"{ind}Vault secret retrieval failed: {e}")
elif isinstance(e, hvac.exceptions.InvalidRequest):
raise hvac.exceptions.InvalidRequest(f"{ind}Missing database parameter in Vault response: {e}")
elif isinstance(e, hvac.exceptions.VaultDown):
raise hvac.exceptions.VaultDown(f"{ind}Database server not available: {e}")
else:
raise Exception (f'{ind}Unexpected error reading from Vault: {e}')
def _create_db_pool_from_vault(self):
"""
Подключение к Vault и создание пула соеденения.
"""
try:
# Подключение к Vault
print(f"{' '*2}Подключение к Vault")
client = hvac.Client(
url='https://vlt.dataekb.ru:8222',
token=environ.get('VAULT_TOKEN'),
)
except Exception as e:
self._handle_vault_exception(e, f"{' '*4}Ошибка при создание покдлючения c Vault")
# Проверка авторизации в Vault
print(f"{' '*4}Проверка авторизации")
if not client.is_authenticated():
raise Exception(f"{' '*6}Не удалось автозоваться в Vault")
else: print(f"{' '*6}Успешно")
try:
# Чтение секретов из Vault
secret_read_response = client.secrets.kv.v2.read_secret_version(
path='oracledb',
mount_point='kv'
)
except Exception as e:
self._handle_vault_exception(e, f"{' '*4}Ошибка чтение скретов из Vault")
try:
# Создаем пул соединений
self.pool = create_pool(
user=secret_read_response['data']['data']['user'],
password=secret_read_response['data']['data']['password'],
dsn=secret_read_response['data']['data']['cs'],
min=2,
max=10,
increment=1
)
except Exception as e:
self._handle_vault_exception(e, f"{' '*2}Ошибка при создание пула для подключение к Oracle")
def data_transfer_in_database(self, list_data: list):
"""
Передача данных в базу
Процедура на вставку:
P_RK_GOVERNMENT_REPORTS_INSERS
(
ID IN NUMBER,
ORGAN IN VARCHAR2,
NAMES IN VARCHAR2,
DATE_FROM in date,
DATE_TO in date,
VERS IN VARCHAR2)
"""
# Данные для БД не могут быть пустыми
if not list_data:
raise ValueError(list_data, "Данные для БД не могут быть пустыми")
try:
print(f"{' '*2}Отправка данных в бд")
with self.pool.acquire() as connection:
with connection.cursor() as cursor:
for dict_argument_bd in list_data:
# Просмотр отпавлямых арогументов
for key, value in dict_argument_bd.items():
print('-'*40)
print(f"{' '*4}Отправляемые аргументы - {key}: {value} -> {type(value)}")
try:
cursor.callproc('P_RK_GOVERNMENT_REPORTS_INSERS', [
dict_argument_bd['id'],
dict_argument_bd['organ'],
dict_argument_bd['names'],
dict_argument_bd['date_from'],
dict_argument_bd['date_to'], # Может быть None
dict_argument_bd['ver'],
])
except Error as e:
# Проверка является ли запись дублирующей
if 'ORA-00001' in str(e): continue
# В остальных случаях запись ошибки и пропуск данных.
else:
error_message = f"ERROR_DB-WRITE: {e} DATA: {dict_argument_bd}"
# Запись логов
error_to_log.write_to_log(error_message)
continue
except Exception as e:
error_message = f"ERROR_DB-GLOBAL: {e}"
error_to_log.write_to_log(error_message)
raise Error(f'Неожиданная ошибка: {e}')