Despeje um banco de dados mysql para um backup de texto simples (CSV) da linha de comando

92

Eu gostaria de evitar o mysqldump, uma vez que ele sai em um formato que só é conveniente para o mysql ler. CSV parece mais universal (um arquivo por tabela está bem). Mas se houver vantagens no mysqldump, sou todo ouvidos. Além disso, gostaria de algo que possa executar na linha de comando (linux). Se for um script mysql, dicas de como fazer isso seriam úteis.

Dreeves
fonte

Respostas:

140

Se você consegue lidar com uma tabela de cada vez e seus dados não são binários, use a -Bopção do mysqlcomando. Com esta opção, ele irá gerar arquivos TSV (separados por tabulação) que podem ser importados para o Excel, etc, com bastante facilidade:

% echo 'SELECT * FROM table' | mysql -B -uxxx -pyyy database

Como alternativa, se você tiver acesso direto ao sistema de arquivos do servidor, use o SELECT INTO OUTFILEque pode gerar arquivos CSV reais:

SELECT * INTO OUTFILE 'table.csv'
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
    LINES TERMINATED BY '\n'
FROM table
Alnitak
fonte
obrigado! sua segunda "tabela" deve ser "banco de dados", certo? nenhuma opção para CSV em vez de TSV que você conhece?
dreeves
duh - sim, deveria ter lido 'banco de dados'. Não, não há opção para CSV, este é o melhor que conheço sem usar o 'select into outfile' embutido do MySQL, que pode fazer CSV, mas grava os arquivos no servidor, não no cliente.
Alnitak
como forçar a substituição no arquivo de saída?
JCm
11
Observe que quando um caminho relativo (ou simplesmente um nome de arquivo) é fornecido, o arquivo aparecerá em seu diretório MYSQL, e não em seu diretório shell atual (isto é, de onde \. file.sqllê). Como tal, dependendo da sua instalação, você provavelmente o encontrará em/var/lib/mysql/[db_name]/table.csv
Mala
32

No próprio MySQL, você pode especificar a saída CSV como:

SELECT order_id,product_name,qty
FROM orders
INTO OUTFILE '/tmp/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'

De http://www.tech-recipes.com/rx/1475/save-mysql-query-results-into-a-text-or-csv-file/

Paul Tomblin
fonte
2
Não consigo encontrar o arquivo despejado no diretório que especifiquei, por que isso?
JCm
@JCm ele despeja no servidor
Alnitak
26

Você pode despejar um banco de dados inteiro de uma vez com a mysqldump's --tabopção. Você fornece um caminho de diretório e ele cria um .sqlarquivo com a CREATE TABLE DROP IF EXISTSsintaxe e um .txtarquivo com o conteúdo, separados por tabulação. Para criar arquivos separados por vírgulas, você pode usar o seguinte:

mysqldump --password  --fields-optionally-enclosed-by='"' --fields-terminated-by=',' --tab /tmp/path_to_dump/ database_name

Esse caminho precisa ser gravável pelo usuário mysql e pelo usuário que executa o comando, portanto, para simplificar, recomendo chmod 777 /tmp/path_to_dump/primeiro.

chmac
fonte
1
Continuei voltando a esta resposta, é definitivamente a melhor maneira de exportar todas as tabelas para um arquivo delimitado.
joevallender
mysqldump: You must use option --tab with --fields-...
Marco Marsala
Como root: GRANT FILE ON *.* TO 'user1'@'localhost';- stackoverflow.com/a/15014385/1707015 . No meu caso, eu tive que pegar /var/lib/mysql-files/(ao invés de /tmp/), definir o usuário para mysql: mysql e definir os direitos para 777 - stackoverflow.com/a/32737616/1707015 .
qräbnö
18

A opção select into outfile não funcionaria para mim, mas a forma indireta abaixo de enviar arquivo delimitado por tabulação através do SED funcionou:

mysql -uusername -ppassword -e "SELECT * from tablename" dbname | sed 's/\t/","/g;s/^/"/;s/$/"/' > /path/to/file/filename.csv
Sri
fonte
1
Este comando resultou na tsubstituição da letra por ", "no arquivo de saída. Não exatamente o que eu estava procurando.
BrennanR de
9

Aqui está o comando mais simples para ele

mysql -h<hostname> -u<username> -p<password> -e 'select * from databaseName.tableNaame' | sed  's/\t/,/g' > output.csv

Se houver uma vírgula no valor da coluna, podemos gerar .tsv em vez de .csv com o seguinte comando

mysql -h<hostname> -u<username> -p<password> -e 'select * from databaseName.tableNaame' > output.csv
minhas23
fonte
Para CSV: funciona onde eu só preciso da vírgula. mysql -hlocalhost -uroot -e 'select * from databaseName.tableNaame' | sed 's/\t/,/g' > /tmp/output.csv`
3

Se você realmente precisa de um "Backup", também precisa do esquema de banco de dados, como definições de tabelas, definições de visualização, procedimentos de armazenamento e assim por diante. Um backup de um banco de dados não é apenas dos dados.

O valor do formato mysqldump para backup é especificamente que é muito FÁCIL usá-lo para restaurar bancos de dados mysql. Um backup que não é restaurado facilmente é muito menos útil. Se você está procurando um método para fazer backup confiável dos dados do mysql para que possa restaurar para um servidor mysql, acho que você deve ficar com a ferramenta mysqldump.

O Mysql é gratuito e funciona em muitas plataformas diferentes. Configurar um novo servidor mysql para o qual posso restaurar é simples. Não estou nem um pouco preocupado em não conseguir configurar o mysql para fazer uma restauração.

Eu ficaria muito mais preocupado com a falha de um backup / restauração personalizado baseado em um formato frágil, como csv / tsv. Tem certeza de que todas as aspas, vírgulas ou tabulações que estão em seus dados seriam escapadas corretamente e, em seguida, analisadas corretamente por sua ferramenta de restauração?

Se você está procurando um método para extrair os dados, veja vários nas outras respostas.

Zoredache
fonte
obrigado, muito útil! você me convenceu. Eu tenho outros motivos para querer uma maneira rápida de obter um despejo csv por meio de um comando de linha de comando. estou esperando por uma "resposta aceita". (embora eu provavelmente pudesse juntar as peças neste ponto a partir das respostas atuais, acho que com um script mysql).
dreeves
Vejo muito valor em ter um backup usando o método nativo e também extrações para outros fins.
Zoredache
mk-parallel-restore pode restaurar um backup CSV criado com mk-parallel dump, para que você possa obter o melhor dos dois mundos. Na verdade, mk-parallel-restore faz um trabalho melhor garantindo que todos os gatilhos definidos sejam restaurados por último.
Paul Dixon
3

Você pode usar o script abaixo para obter a saída para arquivos csv. Um arquivo por tabela com cabeçalhos.

for tn in `mysql --batch --skip-page --skip-column-name --raw -uuser -ppassword -e"show tables from mydb"`
do 
mysql -uuser -ppassword mydb -B -e "select * from \`$tn\`;" | sed 's/\t/","/g;s/^/"/;s/$/"/;s/\n//g' > $tn.csv
done

user é o seu nome de usuário, password é a senha se você não quiser ficar digitando a senha para cada tabela e mydb é o nome do banco de dados.

Explicação do script: A primeira expressão em sed substituirá as tabulações por "," portanto, você tem os campos entre aspas duplas e separados por vírgulas. O segundo inserir aspas duplas no início e o terceiro inserir aspas duplas no final. E o último cuida do \ n.

Kiran Pathuru
fonte
Isso principalmente me levou aonde eu precisava ir, mas fiquei surpreso quando a letra "t" foi substituída por vírgulas: stackoverflow.com/a/2610121/8400969
Michael
E isso deve dizer --skip-column-namesna minha versão do mysql, também
Michael
2

Verifique mk-parallel-dump que faz parte do conjunto de ferramentas maatkit sempre útil . Isso pode despejar arquivos separados por vírgula com a opção --csv.

Isso pode fazer todo o seu banco de dados sem especificar tabelas individuais, e você pode especificar grupos de tabelas em uma tabela de conjunto de backup.

Observe que ele também despeja definições de tabela, visualizações e acionadores em arquivos separados. Além de fornecer um backup completo de uma forma mais universalmente acessível, também pode ser restaurado imediatamente com mk-parallel-restore

Paul Dixon
fonte
Este pode não ser o backup ideal, mas é completamente incrível para COMPARTILHAR. Obrigado!
atroon
maatkitparece fazer parte do percona toolkitagora, mas não consigo encontrar as ferramentas correspondentes.
sjas
1

Resposta do PowerShell de duas linhas:

# Store in variable
$Global:csv = (mysql -uroot -p -hlocalhost -Ddatabase_name -B -e "SELECT * FROM some_table") `
| ConvertFrom-Csv -Delimiter "`t"

# Out to csv
$Global:csv | Export-Csv "C:\temp\file.csv" -NoTypeInformation

Boom-bata-boom

-D = o nome do seu banco de dados

-e = consulta

-B = delimitado por tabulação

Kolob Canyon
fonte
1

Se você quiser despejar todo o banco de dados como csv

#!/bin/bash

host=hostname
uname=username
pass=password

port=portnr
db=db_name
s3_url=s3://bxb2-anl-analyzed-pue2/bxb_ump/db_dump/



DATE=`date +%Y%m%d`
rm -rf $DATE

echo 'show tables' | mysql -B -h${host} -u${uname} -p${pass} -P${port} ${db} > tables.txt
awk 'NR>1' tables.txt > tables_new.txt

while IFS= read -r line
do
  mkdir -p $DATE/$line
  echo "select * from $line" | mysql -B -h"${host}" -u"${uname}" -p"${pass}" -P"${port}" "${db}" > $DATE/$line/dump.tsv
done < tables_new.txt

touch $DATE/$DATE.fin


rm -rf tables_new.txt tables.txt
veera
fonte