Vider une base de données mysql dans une sauvegarde en texte brut (CSV) à partir de la ligne de commande

92

Je voudrais éviter mysqldump car cela sort sous une forme qui n'est pratique que pour mysql à lire. CSV semble plus universel (un fichier par table est très bien). Mais s'il y a des avantages à mysqldump, je suis toute oreille. Aussi, j'aimerais quelque chose que je puisse exécuter à partir de la ligne de commande (linux). Si c'est un script mysql, des pointeurs sur la façon de faire une telle chose seraient utiles.

dreeves
la source

Réponses:

140

Si vous pouvez gérer une table à la fois et que vos données ne sont pas binaires, utilisez l' -Boption de la mysqlcommande. Avec cette option, il générera des fichiers TSV (séparés par des tabulations) qui peuvent être importés dans Excel, etc., assez facilement:

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

Alternativement, si vous avez un accès direct au système de fichiers du serveur, utilisez SELECT INTO OUTFILEce qui peut générer de vrais fichiers CSV:

SELECT * INTO OUTFILE 'table.csv'
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
    LINES TERMINATED BY '\n'
FROM table
Alnitak
la source
Merci! votre deuxième "table" devrait être "base de données", non? aucune option pour CSV au lieu de TSV que vous connaissez?
dreeves
duh - oui, il aurait dû lire «base de données». Non, il n'y a pas d'option pour CSV, c'est le meilleur que je connaisse sans utiliser le 'select into outfile' intégré de MySQL, qui peut faire CSV, mais écrit les fichiers sur le serveur, pas sur le client.
Alnitak le
comment forcer l'écrasement sur le fichier de sortie?
JCm
11
Notez que lorsqu'un chemin relatif (ou simplement un nom de fichier) est donné, le fichier apparaîtra dans votre répertoire MYSQL, et non dans votre répertoire shell actuel (c'est-à-dire d'où \. file.sqllit). En tant que tel, en fonction de votre installation, vous le trouverez probablement à/var/lib/mysql/[db_name]/table.csv
Mala
32

Dans MySQL lui-même, vous pouvez spécifier une sortie CSV comme:

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

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

Paul Tomblin
la source
2
Je n'arrive pas à trouver le fichier sauvegardé dans le répertoire que j'ai spécifié, pourquoi?
JCm
@JCm il décharge sur le serveur
Alnitak
26

Vous pouvez vider une base de données entière en une seule fois avec l' mysqldump's --taboption. Vous fournissez un chemin de répertoire et il crée un .sqlfichier avec la CREATE TABLE DROP IF EXISTSsyntaxe et un .txtfichier avec le contenu, séparés par des tabulations. Pour créer des fichiers séparés par des virgules, vous pouvez utiliser les éléments suivants:

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

Ce chemin doit être accessible en écriture à la fois par l'utilisateur mysql et par l'utilisateur exécutant la commande, donc pour plus de simplicité, je recommande d' chmod 777 /tmp/path_to_dump/abord.

chmac
la source
1
Je revenais sans cesse sur cette réponse, c'est certainement le meilleur moyen d'exporter toutes les tables dans un fichier délimité.
joevallender
mysqldump: You must use option --tab with --fields-...
Marco Marsala
En tant que root: GRANT FILE ON *.* TO 'user1'@'localhost';- stackoverflow.com/a/15014385/1707015 . Dans mon cas, j'ai dû prendre /var/lib/mysql-files/(au lieu de /tmp/), définir l'utilisateur sur mysql: mysql et définir les droits sur 777 - stackoverflow.com/a/32737616/1707015 .
qräbnö
18

L'option de sélection dans le fichier ne fonctionnait pas pour moi, mais la méthode détournée ci-dessous pour acheminer un fichier délimité par des tabulations via SED a fonctionné:

mysql -uusername -ppassword -e "SELECT * from tablename" dbname | sed 's/\t/","/g;s/^/"/;s/$/"/' > /path/to/file/filename.csv
Sri
la source
1
Cette commande a entraîné le tremplacement de la lettre par ", "dans le fichier de sortie. Pas exactement ce que je cherchais.
BrennanR
9

Voici la commande la plus simple pour cela

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

S'il y a une virgule dans la valeur de la colonne, nous pouvons générer .tsv au lieu de .csv avec la commande suivante

mysql -h<hostname> -u<username> -p<password> -e 'select * from databaseName.tableNaame' > output.csv
minhas23
la source
Pour CSV: cela fonctionne là où j'ai juste besoin d'une virgule. mysql -hlocalhost -uroot -e 'select * from databaseName.tableNaame' | sed 's/\t/,/g' > /tmp/output.csv`
3

Si vous avez vraiment besoin d'une "sauvegarde", vous avez également besoin d'un schéma de base de données, comme des définitions de table, des définitions de vue, des procédures de stockage, etc. Une sauvegarde d'une base de données ne se limite pas aux données.

La valeur du format mysqldump pour la sauvegarde est spécifiquement qu'il est très FACILE de l'utiliser pour restaurer les bases de données mysql. Une sauvegarde qui n'est pas facilement restaurée est beaucoup moins utile. Si vous recherchez une méthode pour sauvegarder de manière fiable les données mysql afin de pouvoir les restaurer sur un serveur mysql, je pense que vous devriez vous en tenir à l'outil mysqldump.

Mysql est gratuit et fonctionne sur de nombreuses plates-formes différentes. La configuration d'un nouveau serveur mysql sur lequel je peux restaurer est simple. Je ne suis pas du tout inquiet de ne pas pouvoir configurer mysql pour pouvoir effectuer une restauration.

Je serais beaucoup plus inquiet d'une sauvegarde / restauration personnalisée basée sur un format fragile comme l'échec de csv / tsv. Êtes-vous sûr que tous vos guillemets, virgules ou onglets qui se trouvent dans vos données seraient correctement échappés, puis analysés correctement par votre outil de restauration?

Si vous recherchez une méthode pour extraire les données, voyez-en plusieurs dans les autres réponses.

Zoredache
la source
merci, très utile! tu m'as convaincu. J'ai d'autres raisons de vouloir un moyen rapide d'obtenir un vidage csv via une commande en ligne de commande. j'attends cela pour la "réponse acceptée". (bien que je puisse probablement le reconstituer à ce stade à partir des réponses actuelles, je suppose avec un script mysql).
dreeves le
Je vois beaucoup de valeur à avoir à la fois une sauvegarde en utilisant la méthode native et également des extraits à d'autres fins.
Zoredache le
mk-parallel-restore peut restaurer une sauvegarde CSV créée avec mk-parallel dump, afin que vous puissiez tirer le meilleur parti des deux mondes. En fait, mk-parallel-restore fait un meilleur travail en s'assurant que tous les déclencheurs que vous avez définis sont restaurés en dernier.
Paul Dixon
3

Vous pouvez utiliser le script ci-dessous pour obtenir la sortie vers des fichiers csv. Un fichier par table avec en-têtes.

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 est votre nom d'utilisateur, password est le mot de passe si vous ne voulez pas continuer à taper le mot de passe pour chaque table et mydb est le nom de la base de données.

Explication du script: La première expression de sed, remplacera les tabulations par "," donc vous avez des champs entre guillemets et séparés par des virgules. Le deuxième insère un guillemet double au début et le troisième insère un guillemet double à la fin. Et le dernier s'occupe du \ n.

Kiran Pathuru
la source
Cela m'a surtout amené là où je devais aller, mais j'ai été surpris lorsque la lettre "t" a été remplacée par des virgules: stackoverflow.com/a/2610121/8400969
Michael
Et cela devrait dire --skip-column-namesdans ma version de mysql, aussi
Michael
2

Découvrez mk-parallel-dump qui fait partie de la suite d'outils toujours utile de maatkit . Cela peut vider les fichiers séparés par des virgules avec l'option --csv.

Cela peut faire toute votre base de données sans spécifier de tables individuelles, et vous pouvez spécifier des groupes de tables dans une table de jeu de sauvegarde.

Notez qu'il vide également les définitions de table, les vues et les déclencheurs dans des fichiers séparés. En plus de fournir une sauvegarde complète sous une forme plus universellement accessible, il est également immédiatement restaurable avec mk-parallel-restore

Paul Dixon
la source
Ce n'est peut-être pas la sauvegarde idéale, mais c'est tout à fait génial pour le PARTAGE. Je vous remercie!
atroon
maatkitsemble faire partie du percona toolkitmaintenant, mais je ne trouve pas les outils correspondants.
sjas
1

Réponse PowerShell à deux lignes:

# 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

Boum-bata-boom

-D = le nom de votre base de données

-e = requête

-B = délimité par des tabulations

Canyon de Kolob
la source
1

Si vous voulez vider toute la base de données en tant que 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
la source