fix(): Ajuste na função de critica de bnanco de dados
This commit is contained in:
parent
7b2ec0be99
commit
42460f4346
1 changed files with 113 additions and 32 deletions
|
|
@ -1,5 +1,6 @@
|
|||
from fastapi import HTTPException, status
|
||||
import json
|
||||
from typing import Dict, Any, List
|
||||
|
||||
# NOTE: O esquema de entrada para a ação de exibição de um único log
|
||||
# precisaria de um esquema (Schema) que carregue o 'log_id'.
|
||||
|
|
@ -8,49 +9,129 @@ from packages.v1.administrativo.schemas.log_schema import LogClientIdSchema
|
|||
from packages.v1.administrativo.actions.log.log_show_database_action import ShowDatabaseAction
|
||||
|
||||
|
||||
# --- NOVA FUNÇÃO AUXILIAR DE COMPARAÇÃO ---
|
||||
def compare_structures(standard_structure: dict, client_structure: dict) -> dict:
|
||||
# Função auxiliar para comparação de campos
|
||||
def compare_fields(standard_fields: List[Dict], client_fields: List[Dict], table_name: str) -> List[Dict]:
|
||||
"""
|
||||
Compara os campos de uma tabela entre as estruturas padrão e cliente.
|
||||
"""
|
||||
discrepancies = []
|
||||
|
||||
# 1. Mapear campos do cliente por nome para fácil lookup
|
||||
client_fields_map = {field['FIELD_NAME']: field for field in client_fields}
|
||||
|
||||
# 2. Iterar sobre os campos padrão e verificar se existem no cliente
|
||||
for standard_field in standard_fields:
|
||||
field_name = standard_field.get('FIELD_NAME')
|
||||
|
||||
if field_name not in client_fields_map:
|
||||
# Campo que existe no padrão mas não no cliente
|
||||
discrepancies.append({
|
||||
"tabela": table_name,
|
||||
"tipo": "Campo Faltando",
|
||||
"detalhe": f"Campo '{field_name}' ausente na tabela do cliente.",
|
||||
"padrao": standard_field,
|
||||
"cliente": None
|
||||
})
|
||||
continue
|
||||
|
||||
# 3. Comparar atributos do campo (tipo, nulidade, default)
|
||||
client_field = client_fields_map[field_name]
|
||||
|
||||
# Lista de atributos cruciais para comparação
|
||||
attributes_to_check = ['DATA_TYPE', 'NULLABLE', 'DEFAULT']
|
||||
|
||||
for attr in attributes_to_check:
|
||||
standard_value = standard_field.get(attr)
|
||||
client_value = client_field.get(attr)
|
||||
|
||||
# Nota: A comparação de strings JSON é mais simples,
|
||||
# mas requer normalização (ex: null vs NULL, aspas, etc.).
|
||||
if standard_value != client_value:
|
||||
discrepancies.append({
|
||||
"tabela": table_name,
|
||||
"tipo": f"Atributo Divergente ({attr})",
|
||||
"detalhe": f"Atributo '{attr}' do campo '{field_name}' não coincide.",
|
||||
"padrao": standard_value,
|
||||
"cliente": client_value
|
||||
})
|
||||
|
||||
return discrepancies
|
||||
|
||||
|
||||
def compare_structures(standard_structure: Dict[str, Any], client_structure: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""
|
||||
Compara a estrutura do cliente com a estrutura padrão e lista as discrepâncias.
|
||||
ESTA FUNÇÃO DEVE SER IMPLEMENTADA COM A LÓGICA DE NEGÓCIO COMPLETA.
|
||||
O exemplo abaixo é uma simulação básica de comparação de tabelas.
|
||||
"""
|
||||
discrepancies = {
|
||||
audit_log = {
|
||||
"discrepancias_encontradas": False,
|
||||
"detalhes": {}
|
||||
"detalhes": {
|
||||
"tabelas_faltando": [],
|
||||
"elementos_faltando": [], # Para PKs, FKs, Views, etc.
|
||||
"divergencia_de_campos": [] # Para divergências dentro das tabelas
|
||||
}
|
||||
}
|
||||
|
||||
# Se a estrutura padrão estiver vazia, não há como comparar.
|
||||
if not standard_structure:
|
||||
discrepancies["detalhes"]["erro_comparacao"] = "Estrutura padrão de referência não encontrada ou está vazia."
|
||||
return discrepancies
|
||||
if not standard_structure or not client_structure:
|
||||
audit_log["detalhes"]["erro"] = "Estrutura padrão ou do cliente indisponível para comparação."
|
||||
audit_log["discrepancias_encontradas"] = True
|
||||
return audit_log
|
||||
|
||||
# Mapear tabelas padrão e cliente por nome
|
||||
standard_tables_map = {t['TABLE_NAME']: t for t in standard_structure.get('tables', [])}
|
||||
client_tables_map = {t['TABLE_NAME']: t for t in client_structure.get('tables', [])}
|
||||
|
||||
# --- 1. AUDITORIA DE TABELAS E SEUS CAMPOS ---
|
||||
|
||||
# 1.1 Tabelas Faltando (No padrão, mas não no cliente)
|
||||
missing_tables = standard_tables_map.keys() - client_tables_map.keys()
|
||||
if missing_tables:
|
||||
audit_log["discrepancias_encontradas"] = True
|
||||
audit_log["detalhes"]["tabelas_faltando"].extend(sorted(list(missing_tables)))
|
||||
|
||||
# 1. Comparação de Tabelas
|
||||
try:
|
||||
standard_tables = {item["TABLE_NAME"]: item for item in standard_structure.get("tables", [])}
|
||||
client_tables = {item["TABLE_NAME"]: item for item in client_structure.get("tables", [])}
|
||||
|
||||
missing_tables = standard_tables.keys() - client_tables.keys()
|
||||
|
||||
if missing_tables:
|
||||
discrepancies["discrepancias_encontradas"] = True
|
||||
discrepancies["detalhes"]["tabelas_faltando"] = list(missing_tables)
|
||||
# 1.2 Tabelas Correspondentes (Verificação de Campos)
|
||||
for table_name, standard_table in standard_tables_map.items():
|
||||
if table_name in client_tables_map:
|
||||
client_table = client_tables_map[table_name]
|
||||
|
||||
# Adicione aqui a lógica para verificar campos, PKs, FKs, etc.
|
||||
# Exemplo: Verificar se os campos da tabela 'CLIENTES' estão no cliente
|
||||
# if 'CLIENTES' in standard_tables and 'CLIENTES' in client_tables:
|
||||
# standard_fields = standard_tables['CLIENTES']['FIELDS'] # Assumindo um formato mais detalhado
|
||||
# client_fields = client_tables['CLIENTES']['FIELDS']
|
||||
# # ... lógica de comparação de campos
|
||||
# Assume que os campos são listados sob a chave 'FIELDS'
|
||||
standard_fields = standard_table.get('FIELDS', [])
|
||||
client_fields = client_table.get('FIELDS', [])
|
||||
|
||||
except Exception as e:
|
||||
# Em caso de erro na estrutura JSON (malformada)
|
||||
discrepancies["discrepancias_encontradas"] = True
|
||||
discrepancies["detalhes"]["erro_processamento"] = f"Erro ao processar estruturas para comparação: {e}"
|
||||
field_discrepancies = compare_fields(standard_fields, client_fields, table_name)
|
||||
|
||||
if field_discrepancies:
|
||||
audit_log["discrepancias_encontradas"] = True
|
||||
audit_log["detalhes"]["divergencia_de_campos"].extend(field_discrepancies)
|
||||
|
||||
# --- 2. AUDITORIA DE OUTROS ELEMENTOS (PKs, FKs, etc.) ---
|
||||
|
||||
elements_to_check = ['primary_keys', 'foreign_keys', 'indexes', 'views', 'procedures', 'triggers']
|
||||
|
||||
for element_key in elements_to_check:
|
||||
standard_elements = standard_structure.get(element_key, [])
|
||||
client_elements = client_structure.get(element_key, [])
|
||||
|
||||
# Simplifica a comparação para ver se o cliente tem TODOS os elementos do padrão.
|
||||
# Isto é uma simplificação. O ideal seria mapear por chave composta (ex: TABLE_NAME + INDEX_NAME)
|
||||
|
||||
# Convertemos em strings JSON para facilitar a comparação em uma lista/set
|
||||
standard_set = {json.dumps(item, sort_keys=True) for item in standard_elements}
|
||||
client_set = {json.dumps(item, sort_keys=True) for item in client_elements}
|
||||
|
||||
# Encontra elementos que estão no padrão mas não no cliente
|
||||
missing_elements = standard_set - client_set
|
||||
|
||||
if missing_elements:
|
||||
audit_log["discrepancias_encontradas"] = True
|
||||
|
||||
for missing_str in missing_elements:
|
||||
audit_log["detalhes"]["elementos_faltando"].append({
|
||||
"tipo": element_key,
|
||||
"detalhe": "Elemento ausente",
|
||||
"json_padrao": json.loads(missing_str) # Retorna o JSON de volta
|
||||
})
|
||||
|
||||
return discrepancies
|
||||
# --- FIM DA NOVA FUNÇÃO AUXILIAR DE COMPARAÇÃO ---
|
||||
return audit_log
|
||||
|
||||
class ShowDatabaseService:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue