<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>php-experts.org - développement php et internet &#187; import</title>
	<atom:link href="http://www.php-experts.org/tag/import/feed" rel="self" type="application/rss+xml" />
	<link>http://www.php-experts.org</link>
	<description>Ressources sur le développement internet, PHP/MySQL, Ajax, marketing online, référencement...</description>
	<lastBuildDate>Sun, 27 Jun 2010 23:09:22 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CSV et MySQL : SELECT INTO OUTFILE et LOAD DATA INFILE</title>
		<link>http://www.php-experts.org/bases-de-donnees/mysql/csv-mysql-select-into-outfile-load-data-infile-206</link>
		<comments>http://www.php-experts.org/bases-de-donnees/mysql/csv-mysql-select-into-outfile-load-data-infile-206#comments</comments>
		<pubDate>Mon, 27 Apr 2009 01:05:07 +0000</pubDate>
		<dc:creator>Didier</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[csv]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[import]]></category>
		<category><![CDATA[LOAD DATA INFILE]]></category>
		<category><![CDATA[SELECT INTO OUTFILE]]></category>

		<guid isPermaLink="false">http://www.php-experts.org/?p=206</guid>
		<description><![CDATA[J&#8217;ai eu à me pencher sur les imports-exports sous MySQL. Mon but était de disposer de fichiers utilisables dans un format &#8220;humain&#8221; (comprendre: que les gens du marketing pouvaient exploiter avec leur cher Excel) sans pour autant passer par des scripts de conversion hasardeux et lourds pour le serveur. Il a donc fallu que je [...]]]></description>
			<content:encoded><![CDATA[<p>J&#8217;ai eu à me pencher sur les <strong>imports-exports sous MySQL</strong>. Mon but était de disposer de fichiers utilisables dans un format &#8220;humain&#8221; (comprendre: que les gens du marketing pouvaient exploiter avec leur cher Excel) sans pour autant passer par des scripts de conversion hasardeux et lourds pour le serveur. Il a donc fallu que je cherche les meilleures solutions pour pouvoir générer et importer des <strong>fichiers CSV dans MySQL</strong>,mon SGBDR favori. J&#8217;ai dû me servir du couple SELECT INTO OUTFILE pour les exports, et LOAD DATA INFILE pour les imports. Petit rappel syntaxique.<br />
<span id="more-206"></span></p>
<h2>Exports CSV avec MySQL : SELECT INTO OUTFILE</h2>
<p>Le principe de <strong>SELECT INTO OUTFILE</strong> est simple: réaliser un export de données en écrivant un resultset (résultats d&#8217;exécution d&#8217;une requête) directement dans un fichier CSV sur le serveur. Pour cela, l&#8217;utilisateur avec lequel vous vous connectez à MySQL doit avoir le priilège &#8220;FILE&#8221;. Autre remarque, vous ne pourrez en aucun cas écraser un fichier déjà existant sur le serveur (ceci pour la simple et bonne raison qu&#8217;il serait assez dommageable d&#8217;écraser, par exemple, votre fichier /etc/passwd).</p>
<p>Voici donc la syntaxe, finalement assez simple, de la fonction SELECT INTO OUTFILE :</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">SELECT</span> champ</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">FROM</span> <span class="kw1">TABLE</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">WHERE</span> champ = <span class="st0">&#8216;valeur cherchée&#8217;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INTO</span> <span class="kw1">OUTFILE</span> <span class="st0">&#8216;/var/dump.csv&#8217;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">FIELDS</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; TERMINATED <span class="kw1">BY</span> <span class="st0">&#8216;;&#8217;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">OPTIONALLY</span> <span class="kw1">ENCLOSED</span> <span class="kw1">BY</span> <span class="st0">&#8216;&quot;&#8217;</span></div>
</li>
</ol>
</div>
<p>Dans le fichier exporté, les champs ne sont pas délimités, sauf si vous utilisez FIELDS ENCLOSED BY. Le OPTIONALLY spécifie que seules les chaînes de caractères doivent être encadrées.<br />
Le délimiteur par défaut est l&#8217;espace. Pour en utiliser un autre (virgule, point-virgule, tabulation, &#8230;) il faut utiliser la directive FIELDS TERMINATED BY. Evidemment, on peut utiliser des caractères spéciaux comme la tabulation &#8216;t&#8217; ou le retour à la ligne &#8216;n&#8217; (éventuellement CR+LF sous Windows, donc &#8216;rn&#8217;). Il existe aussi LINES TERMINATED BY pour contrôler le caractère de fin de ligne.</p>
<p>Du coup, en lançant sur la base de mon blog cette requête :</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">mysql&gt; <span class="kw1">SELECT</span> ID,post_title,comment_count</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">FROM</span> <span class="st0">`wp_posts`</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">WHERE</span> <span class="st0">`post_status`</span> = <span class="st0">&#8216;publish&#8217;</span></div>
</li>
<li class="li1">
<div class="de1"> <span class="kw1">ORDER</span> <span class="kw1">BY</span> <span class="st0">`post_date`</span> <span class="kw1">DESC</span> <span class="kw1">LIMIT</span> <span class="nu0">3</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">INTO</span> <span class="kw1">OUTFILE</span> <span class="st0">&#8216;/tmp/blog_posts.dump&#8217;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">FIELDS</span></div>
</li>
<li class="li1">
<div class="de1">TERMINATED <span class="kw1">BY</span> <span class="st0">&#8216;;&#8217;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">OPTIONALLY</span> <span class="kw1">ENCLOSED</span> <span class="kw1">BY</span> <span class="st0">&#8216;&quot;&#8217;</span>;</div>
</li>
</ol>
</div>
<p>j&#8217;ai pu récupérer un fichier plat qui donnait :</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">179;&quot;plugin : yURL ReTwitt&quot;;1
</div>
</li>
<li class="li1">
<div class="de1">22;&quot;5 plugins indispensables pour coder en PHP avec l&#8217;IDE Eclipse&quot;;0
</div>
</li>
<li class="li1">
<div class="de1">138;&quot;plugin : wp_list_sub_pages()&quot;;0</div>
</li>
</ol>
</div>
<p>Soit, un joli fichier CSV bien propre, directement exploitable (pourquoi pas par Excel).</p>
<h2>Imports de CSV dans MySQL : LOAD DATA INFILE</h2>
<p>Le LOAD DATA INFILE, qui permet de faire l&#8217;exact inverse du INTO OUTFILE, est tout aussi simple à utiliser. Dans les bonnes conditions, c&#8217;est vraiment l&#8217;un des outils d&#8217;<strong>import MySQL</strong> les plus puissants.<br />
Déjà, bonne nouvelle, la syntaxe des commandes qui permet à LOAD DATA INFILE de repérer les débuts et fin de champs (et de ligne) est la même que pour SELECT INTO OUTFILE. On retrouve donc sans surprise les FIELDS TERMINATED BY et autres joyeusetés.<br />
Une gestion des doublons est aussi possible grâce aux mots-clefs IGNORE et REPLACE, qui parlent d&#8217;eux-même. Déclenchés en cas de doublon dans une clé (primaire ou unique), REPLACE effacera l&#8217;ancienne ligne pour la remplacer par la nouvelle. Attention donc, vous perdrez donc la pérennité de vos ID puisque ceux-ci changeront lors de l&#8217;import de données. IGNORE permettra simplement de conserver l&#8217;ancienne ligne, les nouvelles données n&#8217;étant pas écrites: vous conservez vos ID mais perdez le bénéfice de l&#8217;import sur cette ligne.<br />
Vous pouvez aussi spécifier la liste des champs dans lesquelles les données doivent être stockées avec la syntaxe classique &#8220;(champ1, champ2, champ3)&#8221; (sans guillemets) en fin de commande.<br />
Pour prendre un exemple, avec un fichier de la forme :</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">1;120;&quot;texte1&quot;;
</div>
</li>
<li class="li1">
<div class="de1">2;240;&quot;texte2&quot;;</div>
</li>
</ol>
</div>
<p>En imaginant qu&#8217;on ne veut garder que l&#8217;id (champ 1) et le texte (champ 3), et les insérer dans les champs correspondants de la table SQL &#8220;data&#8221;, on peut utiliser le paramètre @dummy pour demander au serveur d&#8217;ignorer l&#8217;un des champs du CSV. Cela nous donne une requête de la forme :</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">LOAD</span> <span class="kw1">DATA</span> <span class="kw1">INFILE</span> <span class="st0">&#8216;/tmp/data.csv&#8217;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INTO</span> <span class="kw1">TABLE</span> <span class="st0">`data`</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">FIELDS</span></div>
</li>
<li class="li1">
<div class="de1">TERMINATED <span class="kw1">BY</span> <span class="st0">&#8216;;&#8217;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">OPTIONALLY</span> <span class="kw1">ENCLOSED</span> <span class="kw1">BY</span> <span class="st0">&#8216;&quot;&#8217;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#40;</span>id, @dummy, texte<span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Et si par malheur votre fichier commence par 2 lignes d&#8217;entête, pas de souci, vous pouvez présicer IGNORE 2 LINES dans la requête pour que soient ignorées les 2 premières lignes.</p>
<p>Et voila. Deux commandes, finalement pas bien complexes une fois qu&#8217;on les a prises en main, qui permettent de gérer efficacement les imports/exports de fichiers CSV sous MySQL. Pour faire suite à cet article, nous verrons bientôt comment optimiser la vitesse de vos INSERT dans MySQL.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.php-experts.org/bases-de-donnees/mysql/csv-mysql-select-into-outfile-load-data-infile-206/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
