Um tanto único entre os aplicativos oficiais do MySQL, o MySQL Shell oferece saída JSON (fácil). No prompt do shell do MySQL, digitar o seguinte obterá resultados como uma matriz de objetos JavaScript (um para cada linha):
\option resultFormat json/array
\use information_schema
SELECT table_catalog, table_schema, table_name, engine, create_time, table_collation
FROM tables
WHERE table_schema='INFORMATION_SCHEMA' AND table_name LIKE 'T%';
Isso é então passado para um pager para exibição na tela. Como a saída pode ser redirecionada ou salva em um arquivo (chamado, por exemplo, results.json)?
(Nota: a consulta pode ser qualquer coisa. O acima é fornecido como um caso de teste simples, mas não trivial, que deve ser executado em qualquer instalação do MySQL.)
Como o MySQL Shell está disponível em várias plataformas, as soluções agnósticas de plataforma são preferidas, mas soluções para plataformas específicas também são interessantes.
Soluções simples
Pelo que posso determinar, existem duas maneiras simples. Um é de uma linha de comando do shell de login no modo não interativo, e o outro é (ab)usar o
\pager
comando do MySQL Shell.Shell de login
A maneira do shell de login é o que você faria para capturar qualquer saída de comando, juntamente com
mysqlsh
argumentos específicos para executar a consulta. Para um shell Unix:Para o PowerShell, a variável seria definida de forma diferente (ou seja, com
sv sql "..."
), mas o resto seria o mesmo.\pager truques
O antigo cliente mysql tem um
tee
comando que pode enviar a saída para um arquivo. Embora o MySQL Shell não tenha um comando semelhante,\pager
pode ser definido como um comando (shell de login) que exibirá os resultados em um arquivo. Se você quiser ver os resultados também, use qualquertee
comando que o sistema tenha.Se você não quiser ver os resultados, use um comando de shell de login que não produz saída, como
\pager cat >results.json
ou\pager type >results.json
.Observe que cada resultado da consulta substituirá o anterior (com um pouco de truque, você provavelmente poderia criar um comando que escolheria um nome de arquivo que não existe toda vez que for executado).
Observe também que a saída incluirá o resumo do resultado (" <N> linhas no conjunto ( <tempo> s)") no final. Se você não quiser isso, remova-o do arquivo ou canalize os resultados por meio de um comando que o removerá antes de enviar para um arquivo (por exemplo ,
grep -E -v '^[0-9]+ rows in set \([.0-9]+ sec\)$' | tee results.json
ouSelect -SkipLast 1 | Tee-Object results.json
; consulte " Oposto de cauda: todas as linhas, exceto as últimas n linhas " para mais opções de Unix).Você ainda pode canalizar os resultados por meio de um pager, se desejar visualizar os resultados paginados. Por exemplo:
Soluções complexas
Pitão
Interativamente, o Python pode ser usado, mas apenas com auxiliares definidos adequadamente. Como essa solução depende de codificação, é potencialmente fora do tópico para DBA.SE e mais adequada para SO. No entanto, a alternativa de criar uma pergunta relacionada no SO para esta solução beira a postagem cruzada e fragmenta a resposta, então a solução é apresentada aqui.
Nos modos programáticos (JS ou Python), os resultados da consulta são
Result
ouClassicResult
objetos. O MySQL Shell irá formatá-los ao exibi-los, mas os resultados em si não têm formato. Isso significa que em qualquer modo programático, os resultados teriam que ser formatados programaticamente antes de serem enviados.O mecanismo Python tem
open
, e ojson
módulo está disponível. Entre os dois, funções adequadas podem ser definidas para formatar os resultados como JSON e enviá-los para um arquivo.json.JSONEncoder
não suportaResult
eClassicResult
, portanto, um JSONEncoder adequado precisaria ser definido, ou eles precisariam ser convertidos em tipos internos, assim como quaisquer campos que não sejam tipos internos (por exemploDate
, colunas). Este último pode ser feito de forma bastante sucinta.Primeiro, campos. Um método simples para saber se
json
pode codificar um campo é experimentá-lo e lidar com a falha convertendo o valor em uma string. Além disso, o campo deve ser buscado pelo nome da linha usandoget_field
.Converter para um built-in é bastante simples: os resultados devem ser buscados e, em seguida, as compreensões de lista e dict montarão os dados de linha em tipos internos, usando o acima
row_field()
para buscar e converter campos.json.dump()
converterá objetos suportados em JSON e produzirá um determinado objeto de arquivo. Para unir tudo, aqui está uma função para converter resultados, abrir um arquivo e passá-los parajson.dump()
.As funções acima podem ser adicionadas a um plugin a partir da versão 8.0.17. No diretório 'plugins' em sua plataforma, coloque as funções acima (e uma
import json
instrução) no script init em uma pasta de plugins (por exemplo, 'dump_json/init.py'), junto com o seguinte para criar uma extensão e adicionar o arquivo função de saída (adaptada do plugin de exemplo ):A
dump_json
função pode então ser acessada viaext
global no MySQL Shell:Se estiver usando uma versão anterior a 8.0.17, crie um módulo Python com as funções auxiliares (o código para criar uma extensão
ext
e adicionardump_json
a ela deve ser deixado de fora) eimport
o módulo de dentro do shell do MySQL.Becos-sem-saída
De dentro de um shell interativo,
INTO OUTFILE
é tratado pelo servidor, portanto não tem a chance de ser formatado pelo MySQL Shell. De maneira mais geral, o SQL é interpretado do lado do servidor e não tem uma maneira de direcionar um cliente para salvar os resultados em um arquivo, portanto, o modo SQL interativo no MySQL Shell não oferece solução por conta própria.O JavaScript não tem uma maneira padrão (interna ou de uma biblioteca) de acessar arquivos. A API MySQL JS oferece alguns de seus próprios métodos, como ler arquivos de texto via
os
dosutil
vários métodos de E/S de arquivo do e , mas não a saída geral do arquivo.util
erra o alvo em duas contagens: embora tenha alguns métodos de saída de arquivo, eles só podem despejar bancos de dados e tabelas (não resultados de consultas arbitrárias) e apenas no formato de despejo padrão. (Um método de interesse geral, no entanto, éutil.importJSON
, que suporta a importação de um arquivo JSON para um armazenamento de documentos.)Além disso, o modo JavaScript não parece ter o objeto JSON padrão para produzir a saída JSON.