Env:
DB_HOST=localhost
DB_USER=SEU_USUARIO_POSTGRES
DB_PASSWORD=SUA_SENHA
DB_ADMIN_DATABASE=postgres
DB_APPLICATION_DATABASE=escolasegundoDB
Config:
from dotenv import load_dotenv
import os
class Config:
def __init__(self):
load_dotenv()
self.host = os.getenv("DB_HOST")
self.user = os.getenv("DB_USER")
self.password = os.getenv("DB_PASSWORD")
self.admin_db = os.getenv("DB_ADMIN_DATABASE")
self.app_db = os.getenv("DB_APPLICATION_DATABASE")
if not self.app_db:
raise RuntimeError("DB_APPLICATION_DATABASE não definido")
Criação manual do banco de dados:
import psycopg2
from Bd_ORMs.TreinarORm.config.config_pthon import Config
class DatabaseManual:
def __init__(self):
self.config = Config()
self.conn = None
def conectar_admin(self):
self.conn = psycopg2.connect(
host=self.config.host,
user=self.config.user,
password=self.config.password,
database=self.config.admin_db
)
self.conn.autocommit = True
print("Conectado ao banco ADMIN")
def criar_banco(self):
with self.conn.cursor() as cursor:
cursor.execute(
"SELECT 1 FROM pg_database WHERE datname = %s",
(self.config.app_db,)
)
if not cursor.fetchone():
sql = 'CREATE DATABASE "{}"'.format(self.config.app_db)
cursor.execute(sql)
print("Banco criado: {}".format(self.config.app_db))
else:
print("Banco já existe: {}".format(self.config.app_db))
def conectar_aplicacao(self):
self.conn.close()
self.conn = psycopg2.connect(
host=self.config.host,
user=self.config.user,
password=self.config.password,
database=self.config.app_db
)
print("Conectado ao banco da aplicação")
def testar_banco(self):
with self.conn.cursor() as cursor:
cursor.execute("SELECT current_database()")
print(" Banco ativo: {}".format(cursor.fetchone()[0]))
def fechar(self):
if self.conn:
self.conn.close()
print(" Conexão fechada")
Conexão ORM com o banco de dados:
from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker, declarative_base
from Bd_ORMs.TreinarORm.config.config_pthon import Config
class DatabaseORM:
def __init__(self):
self.config = Config()
self.engine = create_engine(
"postgresql://{}:{}@{}/{}".format(
self.config.user,
self.config.password,
self.config.host,
self.config.app_db
)
)
self.SessionLocal = sessionmaker(bind=self.engine)
self.Base = declarative_base()
def testar_conexao(self):
with self.engine.connect() as conn:
result = conn.execute(text("SELECT current_database()"))
print(" ORM conectada no banco: {}".format(result.scalar()))
Main:
from Bd_ORMs.TreinarORm.database.db_manual import DatabaseManual
from Bd_ORMs.TreinarORm.database.db import DatabaseORM
if __name__ == "__main__":
print("\n ETAPA MANUAL")
manual = DatabaseManual()
manual.conectar_admin()
manual.criar_banco()
manual.conectar_aplicacao()
manual.testar_banco()
manual.fechar()
print("\ ETAPA ORM")
orm = DatabaseORM()
orm.testar_conexao()
Professor(a), gostaria de validar se a arquitetura que estou usando para configuração e criação de banco de dados está correta, considerando boas práticas, segurança, reaproveitamento de código e aprendizado.
Minha aplicação funciona assim:
Uma classe Config centraliza a leitura do .env, que contém host, usuário, senha e nome do banco da aplicação.
Um módulo manual:
conecta no banco administrador;
verifica se o banco da aplicação existe;
cria o banco apenas se não existir;
testa a conexão.
Em seguida, a ORM (SQLAlchemy) conecta diretamente ao banco criado, usando o nome definido no .env.
Nas próximas execuções, o banco não é recriado, apenas reutilizado.
Caso eu crie outro sistema, posso reaproveitar o mesmo código, mudando apenas o nome do banco no .env.
Dessa forma, não é necessário criar o banco manualmente no pgAdmin nem escrever código de conexão separado para cada nova aplicação.
Minha dúvida é: essa lógica está correta? Criar o banco pelo código usando o .env e fazer a ORM se conectar ao banco já criado, de forma que, se o nome do banco no .env mudar, um novo banco seja criado automaticamente, e se o nome permanecer o mesmo, o banco existente seja reutilizado, sem precisar recriar manualmente ou escrever código de conexão separado pra cada app.