Conceitos centrais
Objetos
Seção intitulada “Objetos”| Conceito | Em uma frase |
|---|---|
| Workbook | Contêiner de trabalho (≠ arquivo). Agrupa tabelas, sheets, versões e políticas |
| Source | O arquivo original enviado (immutable). auto (totalmente automático) / staged (controle explícito: analyze → ajuste do parse-spec → materialize) |
| Table | Dataset tipado, com row ID e versionado. O objeto principal do agente. Há tabelas base (editáveis) e derived (saída de transforms) |
| Transform | Template SQL (Jinja2) / Python. Vincula {{ arg }} às tabelas de entrada via args e produz o artifact de saída. A unidade de lineage |
| Sheet | Composition de exibição que não guarda dados. Os blocks referenciam tabelas (n:m) e o render compõe tudo em xlsx |
| Chart | Chart criado pelo agente. Guarda config e recipe (a tool e os parâmetros usados na geração) |
| Version | versions.commit(label) = label imutável apontando para um snapshot. O revert restaura as tabelas derivadas pelo mecanismo de snapshot (re-execução do DAG) — edições de linha em tabelas base são gerenciadas pelo histórico do log de edits |
| Job | Handle de operações assíncronas (upload com async=true etc.). jobs.wait() ou o webhook job.completed |
| Workspace | Objeto de fronteira (membros, cobrança, governança). Desenvolvedores podem administrar vários workspaces com uma Account API key |
Edição de linhas e lock otimista
Seção intitulada “Edição de linhas e lock otimista”Toda escrita exige expected_version (o etag da tabela). Se estiver defasado, a resposta é 409 — o SDK lança ConflictError. Não há retry automático (para nunca sobrescrever em silêncio uma edição concorrente): o contrato é reler (rows() retorna edit_version) → reaplicar → tentar de novo.
page = client.tables.rows(wb, "sales")client.tables.upsert_rows( wb, "sales", rows=[{"__d2b_row_id": 3, "amount": 999}], # row_id present = update, absent = insert expected_version=page["edit_version"],)Idempotência
Seção intitulada “Idempotência”O SDK anexa automaticamente um Idempotency-Key a toda chamada de mutação (mesma chave + mesmo body reproduzem a resposta original). Retries de rede não causam aplicação dupla. Se você chama o HTTP diretamente, adicione o header por conta própria.
Modelo de promoção (o raw nunca some em silêncio)
Seção intitulada “Modelo de promoção (o raw nunca some em silêncio)”A ingestão auto constrói as tabelas estruturadas do D2B a partir de uma cópia raw fiel de cada planilha. As tabelas estruturadas assumem o nome do arquivo e as tabelas raw são rebaixadas para state=archived (o registro e o lineage permanecem). Com tables.lineage() você volta até as tabelas raw e, se precisar, rematerializa a planilha original com tables.unarchive(). Com structuring=defer as tabelas raw aterrissam primeiro e a mesma promoção acontece quando a estruturação termina; se até lá algo derivado tiver sido criado sobre uma tabela raw, a promoção é adiada automaticamente (nada quebra downstream).
Frescor (staleness)
Seção intitulada “Frescor (staleness)”Escritas interativas, como edições de linha, não recalculam imediatamente as tabelas derivadas downstream — elas as marcam como stale. Você vê isso em freshness: {stale, stale_since} no GET .../tables/{name}, e recalcula tudo em ordem de dependência com POST /workbooks/{id}/recompute (MCP recompute_stale). A execução de transforms propaga de forma eager (a saída está sempre fresca).
Governança
Seção intitulada “Governança”Políticas por tag de coluna × role (mask / deny) são aplicadas na camada de dados. Colunas mascaradas retornam como NULL tipado, sinalizadas em masked_columns. Dá para fazer um dry-run antecipado com GET .../tables/{name}/access. A mesma política vale para export, profile, MCP e até o preview do arquivo bruto — não há caminho de contorno (em um workbook com governança, preview / revise dos bytes brutos são recusados).
JSON Schema de linha (para constrained decoding)
Seção intitulada “JSON Schema de linha (para constrained decoding)”Um OpenAPI estático não consegue tipar o conteúdo das tabelas (a forma da linha depende dos dados). Por isso, o “JSON Schema de uma linha” de cada tabela pode ser obtido em tempo de execução:
GET /api/v1/workbooks/{wb}/tables/{name}/schema?format=json-schemaNo MCP, get_schema(..., include_json_schema=true). O schema retornado é gerado a partir do conjunto de colunas já com as políticas aplicadas (colunas deny não aparecem), com additionalProperties: false, todas as células nullable e __d2b_row_id significando “omitido = insert / presente = update”. Um harness de agente pode usá-lo para restringir a geração do payload de upsert_rows (constrained decoding).
Histórico
Seção intitulada “Histórico”- snapshot: commit imutável.
POST /snapshots/POST /snapshots/{id}/restore - version: um nome para um snapshot (
POST /versions,POST /versions/{label}/revert) - op log: registra todas as mutações em ordem (
GET /ops). Ops de linha são aplicadas em reverso comPOST /ops/{id}/undo(o histórico é append-only) - branch / merge:
POST /exportcomrecord_branch=truecongela as linhas no momento do export; o arquivo editado volta porPOST /tables/{name}/merge, um 3-way merge célula a célula chaveado por row ID. Células alteradas dos dois lados vão para a fila de conflicts