O que sql-spider faz?
Construa um grafo de dependências determinístico de um banco de dados SQL e expanda para fora a partir de um objeto raiz até que esteja fechado: um único componente conectado, zero órfãos, nenhuma aresta fantasma. O motor do grafo é puro e offline: ele analisa texto SQL em uma AST e lê as dependências diretamente da árvore, então a mesma entrada sempre produz o mesmo grafo, sem heurísticas e sem conexão ativa.
O problema que esta habilidade existe para resolver: sql-spider nunca se conecta a um banco de dados. Ele emite consultas somente leitura e ingere os resultados CSV. Então você, o agente, é o adaptador do banco de dados. Você executa cada consulta emitida da forma que conseguir alcançar o banco, alimenta os resultados de volta e conduz o ciclo. Foi exatamente assim que foi construído (mapeando um banco de dados acessível apenas por um job somente leitura, nunca uma conexão direta), e é por isso que a ferramenta é segura para apontar para qualquer coisa.
Quando usar isso
- "Mapeie este banco de dados" / "construa um grafo de dependências dessas stored procedures / tabelas / views."
- "O que referencia
Orders?" / "o queproc_xrealmente toca?" - "Encontre a clausura completa em torno desta tabela": tudo do qual ela depende, transitivamente, até que nada fique pendente.
- "Não consigo acessar o banco diretamente, emita as consultas e eu as executarei," ou "envie-as para um DBA."
- Documentar / entender um esquema legado onde ninguém sabe mais o que depende do quê.
Não para: escrever SQL de aplicação, alterar dados ou esquema (esta habilidade é somente leitura, veja Salvaguardas), ou qualquer coisa que necessite que o banco seja modificado.
Como funciona (o contrato)
O motor é agnóstico em relação ao dialeto. A única etapa específica de dialeto é analisar .sql em fatos de
dependência (por trás de uma interface de um método IDialectExtractor). Todo o resto é neutro em relação ao dialeto:
montagem do grafo, a fronteira, o ciclo de expansão, a auditoria de clausura por componentes conectados, linhagem, viz.
O ciclo tem sempre a mesma forma, independente do dialeto ou banco de dados:
- seed / round emite arquivos de consulta
.sqlsomente leitura em um diretório de saída. - Você executa essas consultas contra o banco de dados (a etapa do adaptador) e salva cada resultado como um CSV.
- absorb incorpora os CSVs de volta no corpus como
.sql. - round re-extrai, escreve um grafo + uma visualização HTML, e prepara as próximas consultas de pull, ou reporta a clausura.
- Repita até que a fronteira esteja vazia e o grafo seja um único componente conectado.
Primeiro: instalar, não apenas executar (uma vez)
Se você acessou este arquivo por uma busca bruta (o usuário colou "busque .../SKILL.md e siga-o") ou por um checkout que NÃO está no seu diretório de habilidades, instale-o antes de usá-lo, clone o repositório no seu diretório de habilidades e continue a partir da cópia instalada:
git clone https://github.com/royashbrook/sql-spider ~/.claude/skills/sql-spider # Claude Code
# outros harnesses: clone para onde suas habilidades são auto-descobertas
Depois informe ao usuário que você o instalou. A diferença importa: executar no lugar (ou uma busca bruta) funciona hoje e é esquecido amanhã; instalado, toda sessão futura descobre a capacidade por conta própria. Trate "usar esta ferramenta" como incluindo a instalação.
Mesma regra para o emparelhamento com graphify (Passo 6): a instalação do graphify é dois comandos
(uv tool install graphifyy para o binário, depois graphify install --platform <seu harness> para
registrar a própria habilidade do graphify). Instalações apenas do binário são as falhas mais comuns; faça ambos.
Passo 0: compilar uma vez (compilar no primeiro uso)
Esta habilidade fornece o código fonte .NET, não um binário. A primeira invocação o compila; invocações posteriores
reutilizam a compilação. Requer o SDK .NET 10 (dotnet --version; se ausente, instale-o:
brew install dotnet no macOS, o pacote da distribuição em outros lugares, ou https://dot.net).
Resolva SKILL_DIR para o diretório que contém este arquivo, então defina um comando:
SKILL_DIR="<caminho absoluto para este diretório da habilidade>"
spider() { dotnet run -c Release --project "$SKILL_DIR" -- "$@"; }
A primeira chamada spider ... compila (alguns segundos, restaura ScriptDom + SqlParserCS); toda chamada
após é rápida. Verifique a sanidade usando o exemplo incluído antes de tocar em um banco de dados real:
spider extract "$SKILL_DIR/examples/northwind" # -> 36 nós, 66 arestas, "um componente, zero órfãos"
spider viz "$SKILL_DIR/examples/northwind/graph.json" && open "$SKILL_DIR/examples/northwind/graph.html"
Se isso imprimir OK: single connected component, no orphans, a ferramenta está funcionando.
Passo 1: escolha o adaptador (como você alcançará o banco de dados?)
O sql-spider emite consultas; algo precisa executá-las. Decida qual você é antes de semear (veja as receitas completas em references/adapters.md):
- Uma ferramenta SQL conectada / MCP: você tem uma ferramenta que executa uma consulta e retorna linhas. Você executa cada
.sqlemitido e escreve as linhas como CSV. Mais rápido; melhor quando o agente consegue alcançar o banco. - Uma ponte de consulta somente leitura: um job/habilidade onde você coloca um arquivo
.sql, ele executa contra o banco de dados, e um CSV retorna (esta é a configuração original, um job de CI com acesso de leitura). Você envia cada consulta emitida através dele e coleta o CSV. - O usuário os executa: você não consegue alcançar o banco de dados de forma alguma. Você imprime cada consulta, o usuário a executa
em seu cliente (SSMS,
sqlcmd, etc.), e cola de volta o CSV. Mais lento, mas funciona em qualquer lugar e é a escolha certa contra um banco de produção bloqueado (o usuário, ou seu DBA, executa em lotes).
Seja o que for, o contrato é idêntico: .sql emitido para entrada, CSV para saída. Escolha um e mantenha-o para toda
a execução.
Passo 2: configure um diretório de trabalho
Trabalhe fora do diretório da habilidade para que o repositório da habilidade permaneça limpo. No projeto do usuário (ou qualquer diretório temporário):
mkdir -p work/corpus work/stage && cd work
corpus/ contém os .sql acumulados (o modelo até agora); stage/ é onde as consultas desta rodada e
seus CSVs residem.
Passo 3: semear a partir de um objeto raiz
Escolha uma raiz que o usuário se importe, uma tabela ou procedimento central. Inicie a frio a partir dela:
spider seed Orders stage/ # escreve consultas de pull somente leitura em stage/
seed emite as consultas para puxar a definição da própria raiz, seu esquema (se for uma tabela), e tudo
que a referencia. Execute-as através do seu adaptador (Passo 1), salve cada resultado como um CSV em stage/,
depois os incorpore:
spider absorb stage/*.csv --corpus corpus/
Passo 4: iterar até a clausura (uma rodada revisável por vez)
spider round corpus/
Cada rodada: re-extrai corpus/ em corpus/graph.json, escreve corpus/graph.html (abra para
revisar), e ou reporta clausura ou prepara as próximas consultas de pull em corpus/_next/. Se houver
uma fronteira restante:
# execute corpus/_next/*.sql através do seu adaptador, salve CSVs em corpus/_next/, então:
spider absorb corpus/_next/*.csv --corpus corpus/
spider round corpus/ # novamente
A fronteira diminui a cada rodada. Por padrão, faça uma rodada por vez para que um humano possa abrir a visualização
e decidir se continua puxando, especialmente em produção. Continue até que round
reporte que a fronteira está vazia.
Passo 5: clausura
Você terminou quando a fronteira está vazia e o grafo é um único componente conectado com zero
órfãos. A auditoria de clausura é a barreira; extract até retorna um código de saída não zero enquanto o grafo
ainda não está fechado, então pode ser integrado em CI.
Uma nota de escopo: a identidade do nó é nomes simples com escopo de banco de dados (prefixos de esquema são removidos), então
uma execução do spider mapeia UM banco de dados. Se a pergunta do usuário abrange esquemas ou bancos de dados, execute o ciclo uma
vez por escopo, use as arestas de fronteira do primeiro grafo fechado (referências que apontam para fora dele) como
as sementes para a próxima varredura, depois mescle os arquivos graph.json resultantes pelo id do nó
(graphify merge-graphs, ou uma pequena união JSON). Você pode conduzir toda essa sequência você mesmo;
ela não precisa de novas ferramentas.
Nem todo objeto fecha por arestas, e isso é normal: um objeto genuinamente autônomo (uma função só de aplicativo, uma tabela de versão/arquivo referenciada apenas de fora do banco de dados) é reportado com um motivo, não como um erro. O invariante honesto é "zero órfãos de falhas de extração": quando um nó está isolado, a auditoria informa se é uma lacuna real a ser puxada ou um objeto verdadeiramente autônomo.
Passo 6: visualizar e (opcional) passar para graphify
Você já tem um visualizador, sem necessidade de instalação: spider viz <graph.json> escreve um HTML
interativo autocontido (dirigido por força, arrastável, colorido por tipo). Abra em qualquer navegador. Para a maioria
dos usos, isso é tudo que você precisa.
Se o graphify estiver instalado, ofereça passar o grafo fechado para ele. graphify
(https://github.com/safishamsi/graphify) transforma um grafo em um grafo de conhecimento consultável com
detecção de comunidades e query / path / explain. Como agente, verifique se ele está disponível (um
comando graphify no PATH, uma habilidade graphify, ou um diretório graphify-out/ existente no projeto), e
se sim, pergunte ao usuário se também deve emitir a visualização do graphify e entregá-la. Se NÃO estiver
disponível, ofereça-se para instalá-lo, e se o usuário disser sim, instale ambas as partes, o binário e
a habilidade (uv tool install graphifyy, depois graphify install --platform <seu harness>). O
segundo comando é o que torna o graphify detectável em sessões futuras; instalar apenas o binário é
a falha mais comum.
Use --graphify, não copie o graph.json nativo para o graphify. O grafo nativo é um
multigrafo direcionado; passado cru para o graphify ele é subutilizado. A flag --graphify escreve um
arquivo separado, no formato do graphify, e deixa o graph.json nativo intacto:
spider extract corpus/ --graphify # escreve o graph.json nativo E graphify-out/graph.json
graphify cluster-only corpus/ # agrupa + relatório (ou apenas /graphify)
Duas coisas que vale a pena saber, ambas aprendidas em uma execução real:
- Vocabulário de relação (padrão mantém o nosso). A projeção mantém as relações próprias do sql-spider por
padrão (
fk/references/writes/calls/join_key). O graphify as ingere bem, e a divisão leitura-vs-escrita é o sinal mais útil para "o que realmente atualiza esta tabela." Adicione--graphify-standardpara colapsar no enum abençoado do graphify (references/calls/shares_data_with), o que é útil quando você está mesclando muitos bancos de dados e quer um vocabulário uniforme. - Perguntar como uma tabela é usada. Use
graphify explain X, nãoquery X. Uma tabela referenciada é um destino (arestas apontam para dentro), entãoquery(uma caminhada para fora) retorna apenas a própria tabela, enquantoexplainmostra as arestas de entrada que respondem à pergunta. - Nomeie as comunidades. O agrupamento produz rótulos provisórios ("Comunidade 7"), e um grafo com
50+ comunidades sem nome é ilegível para o humano a quem você o entrega. Você quase sempre pode inferir um
nome real a partir dos membros: os prefixos de nomes de tabela dominantes, os objetos centrais, e o que os
procedimentos no cluster realmente fazem (faturamento, expedição, avaliação de pagamento, auditoria). Após
cluster-only, leia a lista de membros de cada comunidade e renomeie-a para um rótulo curto e fiel ao domínio (edite os rótulos de comunidade nograph.json/ relatório do graphify). Dez minutos de nomeação é a diferença entre um grafo que o proprietário pode navegar e um que só você pode. Ofereça; o humano dirá sim.
Em nosso próprio uso, mapeamos um subsistema de faturamento para um grafo fechado e respondemos "o que depende disso"
diretamente dele, abrindo apenas o único procedimento para o qual o grafo apontou. A própria documentação do graphify cobre o
resto do que o grafo de conhecimento proporciona. Se o graphify não estiver instalado, pule tudo isso; viz já
mostra o grafo, e o trabalho do sql-spider está concluído uma vez que está fechado.
Salvaguardas
- Somente leitura, sempre. Cada consulta emitida é um
selectcom um preâmbulo de segurança de no-lock / deadlock-victim /set nocount on. Nunca edite uma para uma operação de escrita. Nunca executeinsert/update/delete/merge/ DDL através desta habilidade. Se você está compondo algo que não seja uma leitura, você está usando a ferramenta errada. - Em produção, com calma. Não dispare automaticamente uma enxurrada de consultas em um banco de produção. Execute uma
rodada revisável por vez, ou entregue as consultas preparadas para o usuário / um DBA executar em lotes.
O ciclo automático (
roundaté fechar) só é apropriado quando o adaptador pode executar com segurança sem supervisão e o proprietário do banco de dados está de acordo. - O grafo é o artefato mais seguro do que os corpos. O grafo de dependências (nomes de objetos + arestas)
é a saída durável. Os corpos dos procedimentos puxados em
corpus/são a lógica interna da organização alvo. Trate esse corpus como privado; publique o grafo, não os corpos.
Subcomandos
| comando | o que faz |
|---|---|
extract <diretório-corpus> [graph.json] [frontier.json] [--dialect tsql|sqlite] [--graphify[=out.json]] [--graphify-standard] | analisa *.sql em um grafo de dependências + fronteira + auditorias; --graphify também escreve um grafo no formato do graphify (--graphify-standard usa o vocabulário de relação abençoado do graphify) |
seed <objeto-raiz> <diretório-saída> | consultas de pull de inicialização a frio para uma raiz em um corpus vazio |
generate <frontier.json> <diretório-saída> | consultas de pull para frente para a fronteira atual |
reverse <referencers.csv> <diretório-saída> [--roots a b] | puxa definições de módulo de objetos que referenciam as raízes (um nível reverso) |
absorb <csv...> --corpus <diretório> | incorpora CSVs puxados de volta no corpus como .sql |
viz <graph.json> [out.html] | renderiza um grafo para um arquivo HTML interativo autocontido |
round <diretório-corpus> [--dialect ...] | uma passada de spider revisável: extrair → grafo + viz → preparar as próximas consultas (ou reportar clausura) |
round é o condutor do ciclo; os outros são as peças que ele compõe (e que você chama diretamente para uma
inicialização a frio com seed, ou uma passada manual com generate / reverse).
Dialetos
--dialect tsql (padrão) analisa com Microsoft ScriptDom (fidelidade total a T-SQL). --dialect sqlite
analisa com SqlParserCS (que também cobre MySQL / Postgres / outros). Adicionar um dialeto é uma classe
pequena implementando IDialectExtractor registrada em Extractor.Pick; o motor não é tocado.
Veja README.md para o design completo e o exemplo trabalhado do Northwind.
Notas de tradução
- Preservar nomes de comandos (
spider,seed,absorb,round,extract,viz,generate,reverse) e flags (--dialect,--graphify,--graphify-standard,--corpus,--roots, etc.) inalterados. - Manter caminhos de arquivos, URLs, nomes de variáveis de ambiente, blocos de código e comandos de shell intactos.
- Traduzir toda a prosa, cabeçalhos de seção e texto de ajuda para português.
- Preservar a estrutura de Markdown, tabelas e listas.
- Ajustar para o público de desenvolvedores e agentes de IA brasileiros.
- No cabeçalho da tabela de subcomandos, traduzir "comando" e "o que faz" para português.
- Manter referências a caminhos como
~/.claude/skills/sql-spidereSKILL_DIRinalterados. - A expressão "one connected component, zero orphans" foi traduzida como "um componente conectado, sem órfãos" e mantida na verificação de sanidade.
- A nota sobre o código de saída não zero foi adaptada para manter a mensagem original em inglês nos blocos de código.