# -*- coding: utf-8 -*- """ init_db.py — Inicializa o banco ATUAL (roteado pelo db_router/banco). - Cria/atualiza o schema (Base.metadata.create_all) no banco selecionado. - Realiza seed idempotente dos usuários padrão com hash via utils_seguranca. - Não usa caminhos fixos; respeita o banco escolhido na UI (prod/test/treinamento). Uso: - Execute este arquivo diretamente, ou - Importe e chame run() a partir do app, após selecionar o banco. """ from __future__ import annotations from datetime import datetime from sqlalchemy import text from sqlalchemy.exc import SQLAlchemyError # 👇 Usa as fábricas dinâmicas do módulo banco (que delegam ao db_router) from banco import get_engine, init_schema, SessionLocal, db_info # Importa seus modelos para garantir que o metadata conheça todas as tabelas import models # noqa: F401 (garante o registro das classes no metadata) # Utilitário de hash (bcrypt) já existente no seu projeto from utils_seguranca import gerar_hash_senha def _print_header(): try: info = db_info() print("===== Application Startup — init_db.run() =====") print(f"📦 Router ativo? {info.get('using_router')}") label = info.get("label") or info.get("choice") or "(desconhecido)" print(f"🏷️ Banco selecionado: {label}") print(f"🔗 URL: {info.get('url')}") except Exception as e: print(f"ℹ️ db_info indisponível: {e}") def _seed_usuarios(db): """ Insere usuários padrão se não existirem. Usa gerar_hash_senha(senha_plana) -> hash (bcrypt). """ from models import Usuario # import interno para evitar custos em startup usuarios_padrao = [ ("admin", "admin123", "admin"), ("usuario", "usuario123", "usuario"), ("consulta", "consulta123", "consulta"), ] for nome, senha_plana, perfil in usuarios_padrao: try: existe = db.query(Usuario).filter(Usuario.usuario == nome).first() except Exception: # Se a tabela ainda não estiver criada (latência em provedor), reforça schema init_schema() existe = db.query(Usuario).filter(Usuario.usuario == nome).first() if not existe: try: senha_hash = gerar_hash_senha(senha_plana) except Exception as e: print(f"❌ Falha ao gerar hash para '{nome}': {e}") continue novo = Usuario( usuario=nome, senha=senha_hash, # ⚠️ Armazena HASH, nunca em texto puro perfil=perfil, ativo=True, data_criacao=datetime.utcnow(), nome=nome.capitalize(), email=None, # ajuste se quiser e-mail padrão ) db.add(novo) print(f"✅ Usuário '{nome}' criado") else: print(f"ℹ️ Usuário '{nome}' já existe") def run(): """ Executa a inicialização do banco atual: - Cria/atualiza schema - Insere usuários padrão (idempotente) """ _print_header() # 1) Cria/atualiza schema no banco ATUAL try: init_schema() except Exception as e: print(f"❌ Falha ao criar/atualizar schema: {e}") # ainda assim tenta seguir, pois alguns provedores aplicam lazy pass # 2) Seed de usuários db = SessionLocal() try: _seed_usuarios(db) db.commit() print("✅ Banco inicializado com sucesso!") except SQLAlchemyError as e: db.rollback() print(f"❌ Erro SQL ao inicializar banco: {e}") except Exception as e: db.rollback() print(f"❌ Erro ao inicializar banco: {e}") finally: try: db.close() except Exception: pass if __name__ == "__main__": run()