22import os
33from typing import AsyncGenerator
44
5+ from sqlalchemy import text
56from sqlalchemy .ext .asyncio import async_sessionmaker , create_async_engine
67from sqlmodel import Field , SQLModel
78from sqlmodel .ext .asyncio .session import AsyncSession
89
910from app .services .database import models # noqa F401
11+ from app .services .database .models import ( # noqa F401
12+ Community ,
13+ Library ,
14+ LibraryRequest ,
15+ News ,
16+ Subscription ,
17+ )
1018
1119logger = logging .getLogger (__name__ )
1220
3240 engine ,
3341 class_ = AsyncSession ,
3442 expire_on_commit = False ,
35- #echo=True, # expire_on_commit=False é importante!
43+ # echo=True, # expire_on_commit=False é importante!
3644)
3745
3846
@@ -59,24 +67,57 @@ async def init_db():
5967 """
6068 Inicializa o banco de dados:
6169 1. Verifica se o arquivo do banco de dados existe.
62- 2. Se não existir, cria o arquivo e todas as tabelas definidas
63- nos modelos SQLModel nos imports e acima .
70+ 2. Conecta ao banco e verifica se as tabelas existem.
71+ 3. Cria tabelas faltantes se necessário .
6472 """
65- if not os .path .exists (DATABASE_FILE ):
66- logger .info (
67- f"Arquivo de banco de dados '{ DATABASE_FILE } ' não encontrado."
68- f"Criando novo banco de dados e tabelas."
69- )
73+ try :
74+ # Cria o diretório do banco se não existir
75+ db_dir = os .path .dirname (DATABASE_FILE )
76+ if db_dir and not os .path .exists (db_dir ):
77+ os .makedirs (db_dir , exist_ok = True )
78+ logger .info (f"Diretório criado: { db_dir } " )
79+
80+ # Verifica se o arquivo existe
81+ db_exists = os .path .exists (DATABASE_FILE )
82+
83+ if not db_exists :
84+ logger .info (
85+ f"Arquivo de banco de dados '{ DATABASE_FILE } ' não encontrado. "
86+ f"Criando novo banco de dados."
87+ )
88+ else :
89+ logger .info (f"Conectando ao banco de dados '{ DATABASE_FILE } '." )
90+
91+ # Sempre tenta criar as tabelas (create_all é idempotente)
92+ # Se as tabelas já existem, o SQLModel não fará nada
7093 async with engine .begin () as conn :
7194 # SQLModel.metadata.create_all é síncrono e precisa
7295 # ser executado via run_sync
7396 await conn .run_sync (SQLModel .metadata .create_all )
74- logger .info ("Tabelas criadas com sucesso." )
75- else :
76- logger .info (
77- f"Arquivo de banco de dados '{ DATABASE_FILE } '"
78- f"já existe. Conectando."
79- )
97+
98+ # Verifica quais tabelas foram criadas/existem
99+ async with AsyncSessionLocal () as session :
100+ result = await session .execute (
101+ text (
102+ "SELECT name FROM sqlite_master WHERE type='table' "
103+ "ORDER BY name"
104+ )
105+ )
106+ tables = [row [0 ] for row in result .fetchall ()]
107+
108+ if not db_exists :
109+ message = "Banco de dados e tabelas criados com sucesso."
110+ logger .info (message )
111+ else :
112+ message = "Estrutura do banco de dados verificada."
113+ logger .info (message )
114+
115+ tables_message = f"Tabelas disponíveis: { ', ' .join (tables )} "
116+ logger .info (tables_message )
117+
118+ except Exception as e :
119+ logger .error (f"Erro ao inicializar banco de dados: { e } " )
120+ raise
80121
81122
82123async def get_session () -> AsyncGenerator [AsyncSession , None ]:
0 commit comments