# Utilitarios de Banco de Dados

O modulo `arandu.db` fornece funcoes de baixo nivel para configuracao do banco de dados. Sao usadas internamente pelo `MemoryClient`, mas estao disponiveis para casos de uso avancados onde voce precisa de controle direto sobre o engine e o ciclo de vida das sessoes.

```python
from arandu.db import create_engine, create_session_factory, init_db
```

---

## create_engine

Cria um engine async do SQLAlchemy a partir de uma string de conexao.

Converte automaticamente `postgresql://` para `postgresql+psycopg://` se o prefixo do driver async estiver ausente.

```python
def create_engine(database_url: str) -> AsyncEngine
```

| Parametro | Tipo | Descricao |
|-----------|------|-----------|
| `database_url` | `str` | String de conexao PostgreSQL. |

**Retorna:** Instancia de `AsyncEngine`.

```python
from arandu.db import create_engine

engine = create_engine("postgresql://user:pass@localhost:5432/mydb")
# Internamente se torna: postgresql+psycopg://user:pass@localhost:5432/mydb
```

---

## create_session_factory

Cria uma fabrica de sessoes async vinculada ao engine fornecido.

```python
def create_session_factory(engine: AsyncEngine) -> async_sessionmaker[AsyncSession]
```

| Parametro | Tipo | Descricao |
|-----------|------|-----------|
| `engine` | `AsyncEngine` | O engine async para vincular as sessoes. |

**Retorna:** `async_sessionmaker[AsyncSession]` com `expire_on_commit=False`.

```python
from arandu.db import create_engine, create_session_factory

engine = create_engine("postgresql://user:pass@localhost:5432/mydb")
SessionFactory = create_session_factory(engine)

async with SessionFactory() as session:
    # Use a sessao para queries
    ...
```

---

## init_db

Cria todas as tabelas de memoria no banco de dados do consumidor.

Usa `Base.metadata.create_all` -- seguro para chamar multiplas vezes (cria apenas tabelas que ainda nao existem). Garante que todas as classes de modelo SQLAlchemy estejam registradas antes de criar as tabelas.

```python
async def init_db(engine: AsyncEngine) -> None
```

| Parametro | Tipo | Descricao |
|-----------|------|-----------|
| `engine` | `AsyncEngine` | O engine async para criar as tabelas. |

```python
from arandu.db import create_engine, init_db

engine = create_engine("postgresql://user:pass@localhost:5432/mydb")
await init_db(engine)
```

---

## Schema do Banco de Dados

O SDK define seus modelos SQLAlchemy em `arandu.models`. As tabelas principais incluem:

| Tabela | Descricao |
|--------|-----------|
| `memory_events` | Registros de eventos imutaveis (mensagens do usuario com embeddings). |
| `memory_facts` | Fatos extraidos com triplas entidade/atributo/valor e embeddings. |
| `memory_entities` | Registro de entidades (pessoas, lugares, pets, etc.). |
| `memory_entity_aliases` | Aliases para resolucao de entidades. |
| `memory_entity_relationships` | Arestas do knowledge graph entre entidades. |
| `memory_clusters` | Clusters semanticos de fatos relacionados. |
| `memory_meta_observations` | Padroes detectados, insights e preferencias comportamentais. |
| `memory_attribute_registry` | Registro de chaves de atributo customizadas por usuario. |
| `session_observations` | Observacoes de nivel L1 de sessao do observer. |

Todas as tabelas usam chaves primarias UUID e incluem `user_id` para isolamento multi-tenant. As tabelas `memory_facts` e `memory_events` possuem colunas de embedding `pgvector` para busca semantica.

!!! info "Gerenciamento de Schema"
    Para deploys em producao, considere usar migracoes Alembic em vez de `init_db()`. A funcao `init_db()` e conveniente para desenvolvimento e testes, mas nao lida com migracoes de schema para tabelas existentes.
