AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 302217
Accepted
outis
outis
Asked: 2021-11-06 19:11:54 +0800 CST2021-11-06 19:11:54 +0800 CST 2021-11-06 19:11:54 +0800 CST

Como os resultados formatados (JSON) do MySQL Shell podem ser salvos em um arquivo?

  • 772

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.

mysql mysql-shell
  • 1 1 respostas
  • 751 Views

1 respostas

  • Voted
  1. Best Answer
    outis
    2021-11-06T19:11:54+08:002021-11-06T19:11:54+08:00

    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 \pagercomando 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 mysqlshargumentos específicos para executar a consulta. Para um shell Unix:

    sql="SELECT table_catalog, table_schema, table_name, engine, create_time, table_collation
        FROM tables
        WHERE table_schema='INFORMATION_SCHEMA' AND table_name LIKE 'T%';"
    mysqlsh -u user --sql --result-format=json/array --schema=INFORMATION_SCHEMA --execute "$sql" > results.json
    

    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, \pagerpode ser definido como um comando (shell de login) que exibirá os resultados em um arquivo. Se você quiser ver os resultados também, use qualquer teecomando que o sistema tenha.

    \option resultFormat json/array
    \pager tee results.json
    \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%';
    

    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.jsonou \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.jsonou Select -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:

    \pager sed '$d' | tee results.json | less
    

    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 Resultou ClassicResultobjetos. 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 o jsonmó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.JSONEncodernão suporta Resulte ClassicResult, 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 exemplo Date, colunas). Este último pode ser feito de forma bastante sucinta.

    Primeiro, campos. Um método simples para saber se jsonpode 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 usando get_field.

    def row_field(row, name):
        """Get a field by name from a row, converting it to a built-in type if necessary."""
        field = row.get_field(name)
        try:
            json.dump(row.get_field(name))
        except:
            field = str(field)
        return 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.

    def nativize(results):
        """Convert SQL query results to built-in types."""
        rows = results.fetch_all()
        return [{name:row_field(row, name) for name in results.column_names} for row in rows]
    

    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 para json.dump().

    def dump_json(results, file=None, **kwargs):
        """Dump (or return) results as JSON to a file.
        
        If no `file` is given, returns JSON results as string.
        """
        data = nativize(results)
        if file:
            fp = open(file, 'w')
            json.dump(data, fp, **kwargs)
            fp.close()
        else:
            return json.dumps(data, **kwargs)
    

    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 jsoninstruçã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 ):

    if 'ext' not in globals():
        ext = shell.create_extension_object()
        shell.register_global("ext", ext, {"brief":"MySQL Shell extension plugins."})
    
    try:
        shell.add_extension_object_member(ext, "dump_json", dump_json, {
            'brief': 'Writes or returns the JSON representation of results to a given file.',
            'parameters': [
                {
                    'name': 'results',
                    'type': 'object',
                    'brief': 'Query results.',
                },
                {
                    'name': 'file',
                    'type': 'string',
                    'brief': 'output pathname',
                    'required': False,
                },
            ]
        })
    except Exception as e:
        shell.log("ERROR", f'Failed to register util.dump_json: {e}.')
    

    A dump_jsonfunção pode então ser acessada via extglobal no MySQL Shell:

    \py
    query="""SELECT table_catalog, table_schema, table_name, engine, create_time, table_collation
        FROM tables
        WHERE table_schema='INFORMATION_SCHEMA' AND table_name LIKE 'T%';
    """
    \use information_schema
    results = session.run_sql(query)
    ext.dump_json(results, 'path/to/results.json')
    

    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 exte adicionar dump_jsona ela deve ser deixado de fora) e importo 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 viaos dos utilvários métodos de E/S de arquivo do e , mas não a saída geral do arquivo. utilerra 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.

    • 2

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve