CommunityEscrita e Ediçãogithub.com

royashbrook/sql-spider

Extrator de grafo de dependências SQL determinístico e mapeador de clausura a partir de um objeto raiz. Extensível para múltiplos dialetos, com exportação opcional para graphify. Habilidade pronta para agentes de IA.

O que é sql-spider?

O sql-spider é uma ferramenta de engenharia reversa de banco de dados que constrói um grafo de dependências puro e offline a partir de código SQL, sem nunca se conectar diretamente a um banco de dados. Ele emite consultas SQL somente leitura e ingere os resultados CSV para mapear objetos como tabelas, procedimentos armazenados e views. Suporta múltiplos dialetos SQL (T-SQL por padrão, SQLite/MySQL/PostgreSQL via SqlParserCS) através de um extrator extensível. O processo executa em ciclos iterativos onde o agente (você) age como adaptador do banco, executando as consultas emitidas e alimentando os resultados de volta até que o grafo esteja fechado (um único componente conectado, sem órfãos). É ideal para documentar esquemas legados, responder perguntas como "o que referencia essa tabela?" ou encontrar a clausura completa em torno de um objeto raiz, sendo seguro para produção por ser estritamente somente leitura e rodar um ciclo por vez sob revisão.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add royashbrook/sql-spider

Installed? Explore more Escrita e Edição skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

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 que proc_x realmente 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:

  1. seed / round emite arquivos de consulta .sql somente leitura em um diretório de saída.
  2. Você executa essas consultas contra o banco de dados (a etapa do adaptador) e salva cada resultado como um CSV.
  3. absorb incorpora os CSVs de volta no corpus como .sql.
  4. round re-extrai, escreve um grafo + uma visualização HTML, e prepara as próximas consultas de pull, ou reporta a clausura.
  5. 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 .sql emitido 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-standard para 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ão query X. Uma tabela referenciada é um destino (arestas apontam para dentro), então query (uma caminhada para fora) retorna apenas a própria tabela, enquanto explain mostra 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 no graph.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 select com um preâmbulo de segurança de no-lock / deadlock-victim / set nocount on. Nunca edite uma para uma operação de escrita. Nunca execute insert / 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 (round até 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

comandoo 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-spider e SKILL_DIR inalterados.
  • 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.

Habilidades Relacionadas