Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[script] Convertir SQL > csv
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index French
View previous topic :: View next topic  
Author Message
Tony Clifton
l33t
l33t


Joined: 07 Jul 2004
Posts: 686
Location: Rennes

PostPosted: Sun Oct 30, 2011 9:43 pm    Post subject: [script] Convertir SQL > csv Reply with quote

Bonsoir,

j'ai un gros fichier SQL (quelques Go) que je souhaiterais convertir en CSV.

Pour ce faire, j'avais pensé faire un grep de tout ce qui commence par INSERT dans le fichier import.sql, afin d'obtenir quelque chose comme ça :
import.sql wrote:
INSERT INTO `table1` VALUES ('chpA1', 'chpA2', 'chpA3', 'chpA4');
INSERT INTO `table2` VALUES ('chpB1', 'chpB2');


Ensuite je voulais extraire le nom de la table et la liste des champs pour chaque insertion afin de stocker les valeurs des champs dans un fichier qui porterait le nom de la table, soit :
table1 wrote:
'chpA1', 'chpA2', 'chpA3', 'chpA4'

table2 wrote:
'chpB1', 'chpB2''


Seulement voila, je bloque là, j'ai essayé avec AWK mais j'ai aucune idée de comment m'y prendre. Et en bash j'ai réussi à extraire le nom de la table et les valeurs avec expr pour une ligne, avec les commandes suivantes :
Code:
expr "$STR" :  'INSERT INTO `\(.*\)`'
expr "$STR" :  'INSERT INTO `.*` VALUES (\(.*\))'
, mais je doute que ce soit la bonne solution.

Pouvez-vous m'aidez ?

Merci
_________________
La seule certitude que j'ai, c'est d'être dans le doute ! P. Desproges
Back to top
View user's profile Send private message
truc
Advocate
Advocate


Joined: 25 Jul 2005
Posts: 3199

PostPosted: Tue Nov 01, 2011 9:10 am    Post subject: Reply with quote

Le problème avec cette approche, c'est qu'il y a probablement des ' échappées ( ' ' ) dans les valeurs, et ça risque de ne pas fonctionner si notre approche est trop simple.

De même, est-ce que tes INSERTs sont toujours de cette forme? Style, est-ce qu'il y en a avec seulement quelques colonnes?
_________________
The End of the Internet!
Back to top
View user's profile Send private message
Tony Clifton
l33t
l33t


Joined: 07 Jul 2004
Posts: 686
Location: Rennes

PostPosted: Tue Nov 01, 2011 11:54 am    Post subject: Reply with quote

Merci pour ta réponse !

Ma problématique était plus ludique qu'autre chose (rien que faire un grep sur le fichier SQL prend plusieurs heures, alors du bash…), car je m'intéresse aux regex appliquées à sed, awk et autres. Je trouve ça vraiment très intéressant, ça doit vraiment être un plus de bien les maîtriser. Mais lorsque j'essaye une mise en application avec des cas réels, je m'aperçois que c'est beaucoup trop compliqué — ou alors j'ai vraiment l'esprit tordu :roll:
_________________
La seule certitude que j'ai, c'est d'être dans le doute ! P. Desproges
Back to top
View user's profile Send private message
truc
Advocate
Advocate


Joined: 25 Jul 2005
Posts: 3199

PostPosted: Tue Nov 01, 2011 12:16 pm    Post subject: Reply with quote

Bah, si tu veux on peut supposer que tu n'as que des INSERT normaux avec zéro échappement, toujours tout sur la même ligne et bref que des trucs supers cools et on peut déjà commencer à s'amuser avec ça.

Si je comprends bien, tu voudrais donc ne faire un traitement que sur les INSERT (lignes commençant par INSERT), tu peux donc, avec sed et awk, n'effectuer des opérations que sur ces lignes grace à ce sélécteur /^INSERT[[:space::]/.

Après, tu veux remplir tes fichiers dont le nom dépend du deuxième champ, alors, là on a un comportement un peu dynamique si j'puis dire (c'est quel temps ça d'ailleurs, si j'puis dire?! C'est français seulement?), du coup, nous allons plutôt travailler avec awk.

remarque: tu pourrais également d'abord faire un traitement avec sed, pour pouvoir ensuite faire le travail d'écriture dans les fichiers avec awk plus facilement. Mais on va voir déjà où tu nous emmènes avec awk puis on changera peut-être de cap par la suite.

Bon, histoire que tout soit bien clair, donne nous déjà un exemple de ligne que tu as en entrée et de ce que tu veux obtenir en sortie.
_________________
The End of the Internet!
Back to top
View user's profile Send private message
Tony Clifton
l33t
l33t


Joined: 07 Jul 2004
Posts: 686
Location: Rennes

PostPosted: Tue Nov 01, 2011 2:14 pm    Post subject: Reply with quote

Whaou ! La classe j'vais faire du sed et du awk en même temps 8) .

truc wrote:
Après, tu veux remplir tes fichiers dont le nom dépend du deuxième champ, alors, là on a un comportement un peu dynamique si j'puis dire (c'est quel temps ça d'ailleurs, si j'puis dire?! C'est français seulement?), du coup, nous allons plutôt travailler avec awk.


Ce langage là, je le maîtrise un peu mieux ; donc oui, il s'agit bien du verbe pouvoir conjugué au présent de l'indicatif. C'est moins usité que « je peux », donc un peu plus littéraire peut-être.
_________________
La seule certitude que j'ai, c'est d'être dans le doute ! P. Desproges
Back to top
View user's profile Send private message
truc
Advocate
Advocate


Joined: 25 Jul 2005
Posts: 3199

PostPosted: Tue Nov 01, 2011 4:45 pm    Post subject: Reply with quote

arf, j'viens de voir que t'avais déjà donner des exemples de tout ça(fichiers en entrée et en sortie)

Code:
INSERT INTO `table1` VALUES ('chpA1', 'chpA2', 'chpA3', 'chpA4');
INSERT INTO `table2` VALUES ('chpB1', 'chpB2');


On est bien d'accord, c'est pour jouer, les noms des tables ainsi que les champs sont sans caractères spéciaux, ni rien de génant...

Code:
<inputFile awk -f joujou.awk


avec
joujou.awk:

# awk travaille avec les Extended REGEXP, contrairement à sed par défaut,
# ça va surement t'embrouiller au début...
# on se place sur les bonnes lignes (attention la ligne suivante risque d'être
# coupée sur le forum)
/^INSERT[[:space:]]+INTO[[:space:]]+`[^`]+`[[:space:]]+VALUES[[:space:]]*\(.*\)[[:space:]]*;[[:space:]]*$/ {
   # puis on extrait le nom de la table dans le champ numéro 3
   table=substr($3, 2, length($3)-2);

   # $0 contient toute la ligne, il nous suffit de ne garder que la partie entre les ()
   sub(/^[^(]+\([[:space:]]*/, "", $0)
   # sub opère par défaut sur $0, donc normalement, ceci est équivalent
   ## sub(/^[(]+([[:space:]]*/, "")

   # puis la parenthèse fermante et le ';'
   sub(/[[:space:]]*\)[[:space:]]*;[[:space:]]*$/, "")

   # si tu veux vérifier:
   #print table, ":", $0

   # il nous suffit maintenant d'écrire le tout dans le bon fichier, ce que
   # awk nous permet de faire très simplement
   # comme on est cool, on maintient quand même une liste des fichiers qu'on
   # va ouvrir en écriture pour ensuite les refermer
   # cette liste va d'ailleurs nous servir pour savoir si on écrase le fichier
   # si il existe déjà ou si on écrit à la fin
   if (table in opened_files)
      print >> table
   else
      print > table

   # on est fou, on va aussi faire des (modestes) stats à la fin!
   opened_files[table]++
}
END {
   # on ferme maintenant tous les fichiers dans lesquels on a écrit
   for (name in opened_files) {
      close(name, "to")
      printf "%10d ligne(s) écrite(s) dans le fichier %s\n", opened_files[name], name
   }
}



Bon, c'est bien commenté! Tu devrais t'y retrouver...

bon, hormis avec tes exemples, j'ai pas vraiment tester ce truc, donc, attentions aux chats...
_________________
The End of the Internet!
Back to top
View user's profile Send private message
Tony Clifton
l33t
l33t


Joined: 07 Jul 2004
Posts: 686
Location: Rennes

PostPosted: Tue Nov 01, 2011 6:25 pm    Post subject: Reply with quote

Merci pour le script ! Ca me permet de comprendre certaines commandes sur lesquelles j'ai pu m'arracher les cheveux (Mais NON, j'vous dis qu'c'est pas possible !!!! … Et bien si en fait :-D).

Tout ça me fait réaliser que je dois me documenter sur ces outils (langages même ?), je ne connais pas l'équivalence du site php.net du PHP pour AWK ou sed mais si il n'y en a pas il faudra alors que j'achète mon premier bouquin d'informatique.
_________________
La seule certitude que j'ai, c'est d'être dans le doute ! P. Desproges
Back to top
View user's profile Send private message
StinGer_Uesugi
Tux's lil' helper
Tux's lil' helper


Joined: 12 Nov 2010
Posts: 139
Location: Milky Way > Solar System > Earth > France > Paris > Home

PostPosted: Wed Nov 02, 2011 9:01 am    Post subject: Reply with quote

Et sinon, un script en Perl ou Python ? Bon ça va revenir au même que awk et sed au final, et ça fonctionnera pas forcément plus vite. Mais ça peut permettre de faire pas mal de chose en traitement ligne par ligne.

Sinon, awk est vraiment très très puissant. J'ai déjà fait du traitement (en production) dans l'autre sens avec : transformer des fichiers CSV en fichiers SQL pour insertion dans une BDD. Et quand tu connais un peu awk, tu fais des programmes de fou en une dizaine de ligne, à peine.

Et si tu cherches un livre sur awk, pas besoin de chercher loin, tu prends la base : The awk programming language. J'ai commencé par là, et franchement, y a tout dedans...
_________________
Why drink and drive when you can smoke and fly ?
Back to top
View user's profile Send private message
Tony Clifton
l33t
l33t


Joined: 07 Jul 2004
Posts: 686
Location: Rennes

PostPosted: Wed Nov 02, 2011 5:08 pm    Post subject: Reply with quote

Merci pour le conseil, j'vais trouver ça dès que j'ai un instant :-)


StinGer_Uesugi wrote:
transformer des fichiers CSV en fichiers SQL pour insertion dans une BDD


C'est justement ce que je voulais éviter, j'ai récemment appris par mon expérience que c'était à bannir sur des BDD qui commence à titiller le Go voire plus : import en 18h avec fichier SQL contre 90 min pour la même base de données en CSV.
_________________
La seule certitude que j'ai, c'est d'être dans le doute ! P. Desproges
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index French All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum