from datetime import datetime import uuid from sqlalchemy import Column, Integer, String, DateTime, Text, create_engine, Boolean from sqlalchemy.orm import declarative_base, sessionmaker from sqlalchemy.exc import SQLAlchemyError Base = declarative_base() class CertificadoDigitalTable(Base): __tablename__ = 'certificado_digital' id = Column(Integer, primary_key=True, autoincrement=True) id_tecnospeed = Column(String(50), nullable=False) certificado = Column(Text, nullable=False) createdAt = Column(DateTime, default=datetime.now) updatedAt = Column(DateTime, default=datetime.now, onupdate=datetime.now) deletedAt = Column(DateTime, nullable=True) expirationAt = Column(DateTime, nullable=False) senha = Column(String(50), nullable=False) status = Column(Boolean, nullable=False) id_empresa = Column(String(50), nullable=False) id_usuario = Column(Integer, nullable=False) email = Column(String(255), nullable=True) class EnterpriseTable(Base): __tablename__ = 'Enterprise' id = Column(String(50), primary_key=True) name = Column(String(255), nullable=False) cnpj = Column(String(50), nullable=False) banco = Column(Text, nullable=True) email = Column(String(255), nullable=True) createdAt = Column(DateTime, default=datetime.now) updatedAt = Column(DateTime, default=datetime.now, onupdate=datetime.now) deletedAt = Column(DateTime, nullable=True) status = Column(Boolean, nullable=False, default=True) class LogoTable(Base): __tablename__ = 'logo' id = Column(Integer, primary_key=True, autoincrement=True) logo = Column(Text, nullable=False) id_empresa = Column(String(50), nullable=False) createdAt = Column(DateTime, default=datetime.now) updatedAt = Column(DateTime, default=datetime.now, onupdate=datetime.now) deletedAt = Column(DateTime, nullable=True) status = Column(Boolean, nullable=False) class LogTable(Base): __tablename__ = 'log' id = Column(Integer, primary_key=True, autoincrement=True) id_usuario = Column(Integer, nullable=False) createdAt = Column(DateTime, default=datetime.now) updatedAt = Column(DateTime, default=datetime.now, onupdate=datetime.now) deletedAt = Column(DateTime, nullable=True) acao = Column(String(50), nullable=False) tabela = Column(String(50), nullable=False) id_registro = Column(String(50), nullable=False) json = Column(Text, nullable=False) status = Column(String(20), nullable=False, default='INICIO') mensagem = Column(Text, nullable=False, default='') cliente = Column(String(100), nullable=True) correlation_id = Column(String(50), nullable=True) class ServicoTable(Base): __tablename__ = 'servico' id = Column(Integer, primary_key=True, autoincrement=True) id_tecnospeed = Column(String(50), nullable=False) descricao = Column(Text, nullable=False) id_usuario = Column(Integer, nullable=False) createdAt = Column(DateTime, default=datetime.now) updatedAt = Column(DateTime, default=datetime.now, onupdate=datetime.now) deletedAt = Column(DateTime, nullable=True) status = Column(Boolean, nullable=False) class TomadorTable(Base): __tablename__ = 'tomador' id = Column(Integer, primary_key=True, autoincrement=True) id_tecnospeed = Column(String(50), nullable=False) nome = Column(String(50), nullable=False) cpf_cnpj = Column(String(50), nullable=False) email = Column(String(50), nullable=False) telefone = Column(String(50), nullable=False) id_usuario = Column(Integer, nullable=False) createdAt = Column(DateTime, default=datetime.now) updatedAt = Column(DateTime, default=datetime.now, onupdate=datetime.now) deletedAt = Column(DateTime, nullable=True) status = Column(Boolean, nullable=False) class NFSeTable(Base): __tablename__ = 'nfse' id = Column(Integer, primary_key=True, autoincrement=True) id_tecnospeed = Column(String(50), nullable=False) id_empresa = Column(String(50), nullable=False) id_usuario = Column(Integer, nullable=False) createdAt = Column(DateTime, default=datetime.now) updatedAt = Column(DateTime, default=datetime.now, onupdate=datetime.now) deletedAt = Column(DateTime, nullable=True) status = Column(Boolean, nullable=False) class NFeTable(Base): __tablename__ = 'nfe' id = Column(Integer, primary_key=True, autoincrement=True) id_tecnospeed = Column(String(50), nullable=False) id_empresa = Column(String(50), nullable=False) id_usuario = Column(Integer, nullable=False) createdAt = Column(DateTime, default=datetime.now) updatedAt = Column(DateTime, default=datetime.now, onupdate=datetime.now) deletedAt = Column(DateTime, nullable=True) status = Column(Boolean, nullable=False) # Cache de motores criados pelo SQLAlchemy por URL de conexao _engines = {} # Abstração de conexão base e de persistência de instâncias de metadados relacionais usando PostgreSQL class Banco: def __init__(self, host, port, user, password, database): conn_str = f'postgresql://{user}:{password}@{host}:{port}/{database}' if conn_str not in _engines: _engines[conn_str] = create_engine( conn_str, pool_pre_ping=True, pool_recycle=3600 ) self.engine = _engines[conn_str] self.Session = sessionmaker(bind=self.engine) self.session = self.Session() def close(self): """Encerra a sessão SQLAlchemy atual liberando do pooler.""" if hasattr(self, 'session') and self.session is not None: self.session.close() def create_tables(self): """Cria as tabelas no banco de dados.""" try: Base.metadata.create_all(self.engine) except SQLAlchemyError as e: print(f"Erro ao criar tabelas (SQLAlchemy): {e}") except Exception as e: print(f"Erro ao criar tabelas: {e}") def add(self, obj): """Adiciona um novo registro no banco.""" try: self.session.add(obj) self.session.commit() return obj except SQLAlchemyError as e: self.session.rollback() print(f"Erro ao adicionar registro (SQLAlchemy): {e}") raise e except Exception as e: self.session.rollback() print(f"Erro ao adicionar registro: {e}") raise e def get(self, model, obj_id): """Busca um registro pelo ID.""" try: return self.session.query(model).get(obj_id) except SQLAlchemyError as e: self.session.rollback() print(f"Erro ao buscar registro (SQLAlchemy): {e}") raise e except Exception as e: self.session.rollback() print(f"Erro ao buscar registro: {e}") raise e def get_all(self, model): """Retorna todos os registros de um modelo.""" try: return self.session.query(model).all() except SQLAlchemyError as e: print(f"Erro ao buscar registros (SQLAlchemy): {e}") raise e except Exception as e: print(f"Erro ao buscar registros: {e}") raise e def update(self, obj): """Atualiza um registro no banco.""" try: self.session.commit() return obj except SQLAlchemyError as e: self.session.rollback() print(f"Erro ao atualizar registro (SQLAlchemy): {e}") raise e except Exception as e: self.session.rollback() print(f"Erro ao atualizar registro: {e}") raise e def delete(self, obj): """Deleta um registro do banco.""" try: self.session.delete(obj) self.session.commit() return True except SQLAlchemyError as e: self.session.rollback() print(f"Erro ao deletar registro (SQLAlchemy): {e}") raise e except Exception as e: self.session.rollback() print(f"Erro ao deletar registro: {e}") raise e def rollback(self): """Desfaz as alterações pendentes.""" try: self.session.rollback() except SQLAlchemyError as e: print(f"Erro ao desfazer alterações (SQLAlchemy): {e}") except Exception as e: print(f"Erro ao desfazer alterações: {e}") def logar_sistema(self, id_usuario, acao, tabela, id_registro=0, json="{}", status="INICIO", mensagem="", cliente=None, correlation_id=None): """Registra uma ação no log do sistema.""" try: log = LogTable( id_usuario=id_usuario, acao=acao, tabela=tabela, id_registro=id_registro, json=json, status=status, mensagem=mensagem, cliente=cliente, correlation_id=correlation_id ) self.add(log) except SQLAlchemyError as e: print(f"Erro ao logar ação (SQLAlchemy): {e}") except Exception as e: print(f"Erro ao logar ação: {e}") @staticmethod def gerar_correlation_id(): """Gera um ID único para rastrear toda a cadeia de uma operação.""" return str(uuid.uuid4())[:8]