Metadata-Version: 2.4
Name: conduto
Version: 0.1.3
Summary: CLI to scaffold data migration/ELT projects with YAML schemas and a uv-managed environment.
Author: João Pedro Zanetti Gonçalves
License-Expression: MIT
Project-URL: Homepage, https://github.com/joaopedrozg/conduto
Project-URL: Repository, https://github.com/joaopedrozg/conduto
Project-URL: Issues, https://github.com/joaopedrozg/conduto/issues
Keywords: etl,elt,dagster,database,migration,schemas,cli
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Code Generators
Requires-Python: >=3.14
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: jinja2>=3.1.6
Requires-Dist: psycopg[binary]>=3.2
Requires-Dist: pyodbc>=5.1
Requires-Dist: pymysql>=1.1
Requires-Dist: questionary>=2.1.1
Requires-Dist: rich>=15.0.0
Requires-Dist: typer>=0.27.1
Dynamic: license-file

# conduto

**O duto que leva seus dados da origem ao destino.**

CLI para criar projetos de migração/ELT de dados: gera o `.env` com as credenciais dos bancos, o manifesto `main.yml`, os schemas YAML das tabelas e configura o ambiente com `uv` (`pyyaml`, `jinja2`, `polars`, `dagster`).

**Repositório:** [github.com/joaopedrozg/conduto](https://github.com/joaopedrozg/conduto)

## Funcionalidades

- Scaffold completo de projeto ELT em um único comando
- Fluxo interativo para configurar bancos de origem e destino (PostgreSQL, MySQL, SQL Server)
- Geração do `.env` com as credenciais das duas pontas do duto
- Manifesto `main.yml` com a ordem de dependência das tabelas
- Schemas YAML de exemplo (clientes, pedidos e produtos) com PK, FK, `unique` e `default`
- Ambiente Python gerenciado por `uv` com `pyyaml`, `jinja2`, `polars` e `dagster`
- Adapta-se automaticamente a um projeto uv existente (gera direto no projeto atual, sem subpasta nem `uv init`)
- Adapters de conexão com defaults por SGBD (porta, banco e usuário)
- Teste de conexão antes de gerar o projeto (com opção de digitar novamente ou seguir mesmo assim)
- Credenciais visíveis no prompt durante o preenchimento — só vão para o `.env`
- Instalação da lib oficial do SGBD escolhido (`psycopg[binary]`, `pymysql`, `pyodbc`)
- Download/instalação automática do ODBC Driver for SQL Server (Windows, Linux e macOS)
- Feedback visual com `rich` e `questionary`

## Instalação

```bash
pip install conduto
```

Ou, para usar sem sujar o ambiente atual:

```bash
uv tool install conduto
```

## Uso

Crie um novo projeto de migração:

```bash
conduto init meu_projeto
```

O comando pergunta interativamente:

1. SGBD de origem (PostgreSQL, MySQL ou SQL Server) — os defaults de porta, banco e usuário mudam conforme o SGBD
2. Credenciais de origem, digitadas de forma visível (só vão para o `.env`)
3. Teste de conexão de origem — se falhar, escolha entre digitar novamente ou continuar mesmo assim
4. SGBD de destino
5. Credenciais de destino, com o mesmo fluxo de teste

**Dentro de um projeto uv?** Se o diretório atual já tem `pyproject.toml` (por exemplo, após `uv add conduto`), o conduto se adapta: gera `.env`, `main.yml` e `schemas/` direto no projeto atual e adiciona só as dependências que faltam — sem criar subpasta nem rodar `uv init`. **Dentro de um projeto uv?** Se o diretório atual já tem `pyproject.toml` (por exemplo, após `uv add conduto`), o conduto se adapta: gera `.env`, `main.yml` e `schemas/` direto no projeto atual e adiciona só as dependências que faltam — sem criar subpasta nem rodar `uv init`. Nesse caso, use `uv run conduto init` (o nome do projeto vira opcional).

### Driver ODBC do SQL Server

O `pyodbc` precisa do driver nativo instalado no sistema. Se a conexão com SQL Server falhar por falta de driver, o `conduto init` oferece a opção **Instalar driver automaticamente**. As credenciais já digitadas ficam guardadas só em memória e, depois da instalação, o teste de conexão é reexecutado sozinho — você não precisa digitá-las novamente. Também dá para instalar direto, sem passar pelo fluxo interativo:

```bash
conduto install-sqlserver-driver
```

Esse comando funciona em Windows (winget ou MSI), Linux (apt) e macOS (Homebrew). No Windows, existe ainda um script standalone que baixa o instalador oficial — útil para instalação offline ou para automatizar fora do conduto:

Durante a instalação no Windows, se o terminal não estiver como administrador, o conduto abre a janela de permissão (UAC) na frente para você confirmar. Se houver um reinício pendente no sistema, a instalação é bloqueada com um aviso claro até você reiniciar o Windows. O download e a instalação rodam em segundo plano (sem abrir janela do PowerShell) — só a confirmação do UAC aparece.

```powershell
# só baixa o MSI
.\scripts\install-sqlserver-odbc.ps1 -DownloadOnly -OutFile .\msodbcsql18.msi

# baixa e instala (winget ou MSI; se precisar de administrador, o UAC abre na frente)
.\scripts\install-sqlserver-odbc.ps1
```

Versões suportadas: 18 (padrão) e 17 (`-Version 17`). Documentação oficial: [Download ODBC Driver for SQL Server](https://learn.microsoft.com/sql/connect/odbc/download-odbc-driver-for-sql-server).

## O que é gerado

```text
meu_projeto/
├── .env
├── main.yml
├── schemas/
│   ├── clientes.yml
│   ├── pedidos.yml
│   └── produtos.yml
└── ambiente uv (pyyaml, jinja2, polars, dagster)
```

> Fora de um projeto uv, essa estrutura é criada dentro de `meu_projeto/`. Dentro de um projeto uv já existente, os arquivos são gerados no diretório atual.

### `.env` — credenciais

Guarda as credenciais de origem e destino em variáveis `DB_ORIGEM_*` e `DB_DESTINO_*`:

```bash
DB_ORIGEM_TYPE=postgresql
DB_ORIGEM_HOST=localhost
DB_ORIGEM_PORT=5432
DB_ORIGEM_NAME=postgres
DB_ORIGEM_USER=postgres
DB_ORIGEM_PASSWORD=postgres

DB_DESTINO_TYPE=postgresql
DB_DESTINO_HOST=localhost
DB_DESTINO_PORT=5432
DB_DESTINO_NAME=postgres
DB_DESTINO_USER=postgres
DB_DESTINO_PASSWORD=postgres
```

> **Importante:** o `.env` contém credenciais e não deve ser versionado.

### `main.yml` — manifesto

Define a versão do projeto e a lista de schemas na ordem correta de dependência:

```yaml
version: "1.0"
project: meu_projeto

tables:
  - path: "schemas/clientes.yml"
  - path: "schemas/pedidos.yml"
  - path: "schemas/produtos.yml"
```

### `schemas/*.yml` — tabelas

Schemas YAML que descrevem as tabelas: tipos, chave primária, foreign keys, `unique` e `default`.

```yaml
table: clientes
schema: public
description: "Tabela de cadastro de clientes"
columns:
  - name: id
    type: integer
    primary_key: true
    nullable: false
  - name: nome
    type: varchar(255)
    nullable: false
```

Os três exemplos cobrem padrões comuns de modelagem:

| Schema | O que demonstra |
| --- | --- |
| `clientes.yml` | chave primária, coluna `unique` e `default` com `CURRENT_TIMESTAMP` |
| `pedidos.yml` | chave estrangeira com `foreign_key: clientes(id)` |
| `produtos.yml` | tipos `numeric` e `boolean`, colunas opcionais (`nullable: true`) |

### Ambiente `uv`

Se ainda não existir `pyproject.toml`, o conduto inicializa o projeto e instala as dependências do pipeline:

```bash
uv init --no-readme
uv add pyyaml jinja2 polars dagster
```

E também a lib oficial do SGBD escolhido: `psycopg[binary]` (PostgreSQL), `pymysql` (MySQL) ou `pyodbc` (SQL Server).

## Como funciona

1. `cli.py` faz as perguntas de origem e destino e monta o contexto
2. `env_render` renderiza o template do `.env`
3. `schemas_render` renderiza o `main.yml` e os schemas em `schemas/`
4. `setup_uv_environment` roda `uv init` (se necessário) e `uv add` das dependências

## Próximos passos

1. Ajuste os schemas em `schemas/` às suas tabelas reais
2. Revise o `.env` com as credenciais corretas de origem e destino
3. Escreva suas definições Dagster (assets/jobs) dentro do projeto
4. Rode e itere com `uv run dagster dev` (o Dagster já vem instalado)

## Desenvolvimento

```bash
uv sync
uv build
uv publish
```

## Licença

MIT
