IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MySQL Discussion :

Extraction données XML


Sujet :

MySQL

  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 124
    Points : 310
    Points
    310
    Par défaut Extraction données XML
    Bonjour,

    J'ai de tres nombreux fichiers XML d'un poids moyen de 15Mo chacun.
    J'ai besoin de tout inserer en BDD. Pour cela, j'ai essayé LOAD XML INFILE, mais les tags enfants ne sont pas pris en compte
    Voici ma structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <cli>
        <num_id>120</num_id>
        <contact>
            <nom>DUPOND</nom>
            <prenom>Pierre</prenom>
        </contact>
        <relation>253</relation>
        <adresse>
            <adresse_c>route de la mer</adresse_c>
            <code_postal>64200</code_postal>
            <ville>Biarritz</ville>
        </adresse>
    </cli>
    <cli>
        <num_id>121</num_id>
        <contact>
            <nom>DURANT</nom>
            <prenom>Jean</prenom>
        </contact>
        <relation>826</relation>
        <adresse>
            <adresse_c>rue de blabla</adresse_c>
            <code_postal>75002</code_postal>
            <ville>Paris</ville>
        </adresse>
    </cli>
    num_id et relation sont bien récupérées, mais il me manque nom, prenom, adresse_c, code_postal et ville.
    Quelqu'un aurait il une idée?
    Merci

  2. #2
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 066
    Points
    19 066
    Par défaut
    Salut Jimmo.

    Ton problème, c'est que ton fichier XML n'est pas correctement formaté.
    Le "load xml infile ..." ne peut lire que les niveaux 1, c'est-à-dire les colonnes NUM_ID et RELATION.

    Pour faire le chargement de la table client, je te propose de le faire en trois chargements, sur :
    --> "<CLI>" pour les colonnes "<NUM_ID>", "<RELATION>"
    --> "<CONTACT>" pour les colonnes "<NOM>", "<PRENOM>"
    --> "<ADRESSE>" pour les colonnes "<ADRESSE-C>", "<CODE_POSTAL>", "<VILLE>".

    Puis, ensuite, tu fusionnes tes trois tables en une seule. Voici l'exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
     
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE IF NOT EXISTS `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `client`
    --------------
     
    --------------
    CREATE TABLE `client`
    ( `id`           integer unsigned not null auto_increment primary key,
      `num_id`       integer unsigned not null,
      `nom`          varchar(255)     not null,
      `prenom`       varchar(255)     not null,
      `relation`     varchar(255)     not null,
      `adresse_c`    varchar(255)     not null,
      `code_postal`  varchar(255)     not null,
      `ville`        varchar(255)     not null
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    LOAD XML LOCAL INFILE 'Fichier.xml'
         INTO TABLE `client`
         CHARACTER SET latin1
         ROWS IDENTIFIED BY '<cli>'
         (`num_id`,`relation`)
    --------------
     
    --------------
    select * from client
    --------------
     
    +----+--------+-----+--------+----------+-----------+-------------+-------+
    | id | num_id | nom | prenom | relation | adresse_c | code_postal | ville |
    +----+--------+-----+--------+----------+-----------+-------------+-------+
    |  1 |    120 |     |        | 253      |           |             |       |
    |  2 |    121 |     |        | 826      |           |             |       |
    +----+--------+-----+--------+----------+-----------+-------------+-------+
    --------------
    DROP TABLE IF EXISTS `contact`
    --------------
     
    --------------
    CREATE TABLE `contact`
    ( `id`           integer unsigned not null auto_increment primary key,
      `nom`          varchar(255)     not null,
      `prenom`       varchar(255)     not null
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    LOAD XML LOCAL INFILE 'Fichier.xml'
         INTO TABLE `contact`
         CHARACTER SET latin1
         ROWS IDENTIFIED BY '<contact>'
         (`nom`,`prenom`)
    --------------
     
    --------------
    select * from contact
    --------------
     
    +----+--------+--------+
    | id | nom    | prenom |
    +----+--------+--------+
    |  1 | DUPOND | Pierre |
    |  2 | DURANT | Jean   |
    +----+--------+--------+
    --------------
    DROP TABLE IF EXISTS `adresse`
    --------------
     
    --------------
    CREATE TABLE `adresse`
    ( `id`           integer unsigned not null auto_increment primary key,
      `adresse_c`    varchar(255)     not null,
      `code_postal`  varchar(255)     not null,
      `ville`        varchar(255)     not null
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    LOAD XML LOCAL INFILE 'Fichier.xml'
         INTO TABLE `adresse`
         CHARACTER SET latin1
         ROWS IDENTIFIED BY '<adresse>'
         (`adresse_c`,`code_postal`,`ville`)
    --------------
     
    --------------
    select * from adresse
    --------------
     
    +----+-----------------+-------------+----------+
    | id | adresse_c       | code_postal | ville    |
    +----+-----------------+-------------+----------+
    |  1 | route de la mer | 64200       | Biarritz |
    |  2 | rue de blabla   | 75002       | Paris    |
    +----+-----------------+-------------+----------+
    --------------
    update     `client`  as tb1
    inner join `contact` as tb2
    on    tb2.id = tb1.id
     
    inner join `adresse` as tb3
    on    tb3.id = tb1.id
     
    set   tb1.nom         = tb2.nom,
          tb1.prenom      = tb2.prenom,
          tb1.adresse_c   = tb3.adresse_c,
          tb1.code_postal = tb3.code_postal,
          tb1.ville       = tb3.ville
    --------------
     
    --------------
    select * from client
    --------------
     
    +----+--------+--------+--------+----------+-----------------+-------------+----------+
    | id | num_id | nom    | prenom | relation | adresse_c       | code_postal | ville    |
    +----+--------+--------+--------+----------+-----------------+-------------+----------+
    |  1 |    120 | DUPOND | Pierre | 253      | route de la mer | 64200       | Biarritz |
    |  2 |    121 | DURANT | Jean   | 826      | rue de blabla   | 75002       | Paris    |
    +----+--------+--------+--------+----------+-----------------+-------------+----------+
    --------------
    drop table `contact`
    --------------
     
    --------------
    drop table `adresse`
    --------------
     
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
     
    Appuyez sur une touche pour continuer...
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 124
    Points : 310
    Points
    310
    Par défaut
    Salut Artemus24,

    Merci pour ton aide. Par contre, j'ai oublié quelques détails qui ont, je m'en rend compte, leur importance.
    Ma structure XML peut être parfois différentes dans le cas d'informations manquantes.
    par exemple, <adresse></adresse> peut être absent.
    Et dans ce cas, lorsque je lance tes requêtes, automatiquement je me retrouve avec un décalage.

    J'ai oublié de préciser aussi qu'avec ces fichiers XML, j'ai des fichiers XSD qui apparemment peuvent être utilisés pour l'importation SQL.
    Mais je ne sais pas du tout comment ça fonctionne.

  4. #4
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 066
    Points
    19 066
    Par défaut
    Salut Jimmo.

    Citation Envoyé par Jimmo
    Par contre, j'ai oublié quelques détails qui ont, je m'en rend compte, leur importance.
    Ma structure XML peut être parfois différentes dans le cas d'informations manquantes.
    par exemple, <adresse></adresse> peut être absent.
    D'après la documentation, la structure que tu devrais avoir est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <cli>
        <num_id>120</num_id>
        <nom>DUPOND</nom>
        <prenom>Pierre</prenom>
        <relation>253</relation>
        <adresse_c>route de la mer</adresse_c>
        <code_postal>64200</code_postal>
        <ville>Biarritz</ville>
    </cli>
    <cli>
        <num_id>121</num_id>
        <nom>DURANT</nom>
        <prenom>Jean</prenom>
        <relation>826</relation>
        <adresse_c>rue de blabla</adresse_c>
        <code_postal>75002</code_postal>
        <ville>Paris</ville>
    </cli>
    <cli>
        <num_id>122</num_id>
        <nom>Smith</nom>
        <prenom>John</prenom>
        <relation>333</relation>
        <ville>Londres</ville>
    </cli>
    <cli>
        <num_id>123</num_id>
        <nom>Grosjean</nom>
        <prenom>Pierre</prenom>
        <relation>17</relation>
        <adresse_c>Bld des allongés</adresse_c>
        <code_postal>13001</code_postal>
        <ville>Marseille</ville>
    </cli>
    C'est-à-dire une structure où "<cli>" correspond à une ligne, et où éventuellement, tu peux avoir des balises absentes, comme "<adresse_c>" pour cli=122.
    Autrement dit, la structure est composée de la balise "<cli>" qui désigne donc la ligne à charger dans la table MySql.
    Et à l'intérieur de cette balise, tu as présent ou absent, les balises qui correspondent à tes colonnes.
    Mais surtout pas d'imbrication d'une balise dans une autre, comme dans ton exemple avec "<adresse>".

    Si tu as la possibilité de le faire, change la structure de tes fichiers XML, en faisant en sorte qu'ils soient alignés sur tes tables MySql.

    Pour charger la table, voici l'exemple qui est bien plus simple que précédemment. On n'est même plus obligé de préciser les noms des colonnes.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE IF NOT EXISTS `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `client`
    --------------
     
    --------------
    CREATE TABLE `client`
    ( `id`           integer unsigned not null auto_increment primary key,
      `num_id`       integer unsigned not null,
      `nom`          varchar(255)     not null,
      `prenom`       varchar(255)     not null,
      `relation`     varchar(255)     not null,
      `adresse_c`    varchar(255)     not null,
      `code_postal`  varchar(255)     not null,
      `ville`        varchar(255)     not null
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    LOAD XML LOCAL INFILE 'Fichier.xml'
         INTO TABLE `client`
         CHARACTER SET latin1
         ROWS IDENTIFIED BY '<cli>'
    --------------
     
    --------------
    select * from client
    --------------
     
    +----+--------+----------+--------+----------+------------------+-------------+-----------+
    | id | num_id | nom      | prenom | relation | adresse_c        | code_postal | ville     |
    +----+--------+----------+--------+----------+------------------+-------------+-----------+
    |  1 |    120 | DUPOND   | Pierre | 253      | route de la mer  | 64200       | Biarritz  |
    |  2 |    121 | DURANT   | Jean   | 826      | rue de blabla    | 75002       | Paris     |
    |  3 |    122 | Smith    | John   | 333      |                  |             | Londres   |
    |  4 |    123 | Grosjean | Pierre | 17       | Bld des allongés | 13001       | Marseille |
    +----+--------+----------+--------+----------+------------------+-------------+-----------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
     
    Appuyez sur une touche pour continuer...
    Citation Envoyé par Jimmo
    Et dans ce cas, lorsque je lance tes requêtes, automatiquement je me retrouve avec un décalage.
    C'est normal, car la structure de chaque ligne du fichier XML doit toujours être identique.

    Citation Envoyé par Jimmo
    J'ai oublié de préciser aussi qu'avec ces fichiers XML, j'ai des fichiers XSD qui apparemment peuvent être utilisés pour l'importation SQL.
    Mais je ne sais pas du tout comment ça fonctionne.
    Dans la documentation MySql : https://dev.mysql.com/doc/refman/5.7/en/load-xml.html
    il n'y a aucune référence à un autre fichier (XSD) dans la syntaxe de la commande "load xml local infile ...".

    Tu te retrouves limités par l'organisation de tes fichiers XML.

    Une autre solution, si ton fichier XML est variable au niveau de la structure, est de faire une procédure stockée :
    --> http://jcrozier.developpez.com/tutor...gbd/mysql/xml/

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 124
    Points : 310
    Points
    310
    Par défaut
    Il est bien la le problème, en fait, j'ai environ 4000 fichiers xml pour environ 15Mo/fichier.
    Donc changer la structure me parait compliquée. Surtout que la structure que j'ai présentée n'est qu'un exemple, en réalité, elle est bien plus complexe.
    Actuellement je suis en train de tester le code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    $xml = simplexml_load_file("cli.xml");
    $file = fopen('phpXml.sql', 'w');
    $string = "";
    $i = 0;
    $len = count($xml->cli);
     
    foreach($xml->cli as $cli) {
    	if ($i == $len - 1) {
            $string .= "('',";
    		$string .= (string)$cli->num_id.",";
    		$string .= (string)$cli->relation.",";
    		$string .= "'".(string)$cli->contact->nom."',";
    		$string .= "'".(string)$cli->contact->prenom."',";
    		$string .= "'".(string)$cli->adresse->adresse_c."',";
    		$string .= (string)$cli->adresse->code_postal.",";
    		$string .= "'".(string)$cli->adresse->ville."');";
        }
    	else{
    		$string .= "('', ";
    		$string .= (string)$cli->num_id.",";
    		$string .= (string)$cli->relation.",";
    		$string .= "'".(string)$cli->contact->nom."',";
    		$string .= "'".(string)$cli->contact->prenom."',";
    		$string .= "'".(string)$cli->adresse->adresse_c."',";
    		$string .= (string)$cli->adresse->code_postal.",";
    		$string .= "'".(string)$cli->adresse->ville."'),";
    		$string .= "\n";
    	}
    	$i++;
    }
    fwrite($file, $string);
    //echo $string;
    fclose($file);
    Ça permet de générer un fichier SQL.
    Tu en penses quoi?

  6. #6
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 066
    Points
    19 066
    Par défaut
    Salut Jimmo.

    J'ai repris ton idée, en lisant le fichier xml et en rangeant les résultats dans une table.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    <!doctype html>
    <html>
    <head>
    <title>XML !</title>
     
    <body>
    <?php
    /*----------------------------------------------*/
    /*     Récupération fichier au format 'XML'     */
    /*----------------------------------------------*/
     
    $xml    = simplexml_load_file('cli.xml');
     
    $length = count($xml->cli);
     
    /*-----------------------------------------------------*/
    /* Informations pour la connexion à la base de données */
    /*-----------------------------------------------------*/
     
    $nom_du_serveur  = "mysql:host=localhost;dbname=base";
    $nom_utilisateur = "root";
    $mot_de_passe    = "root";
     
    $options         = array(
    	PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES latin1",
    	PDO::ATTR_CASE               => PDO::CASE_LOWER,
    	PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    	PDO::ATTR_PERSISTENT         => false,
    	PDO::ATTR_AUTOCOMMIT
    );
     
    /*----------------------*/
    /* Connexion au Serveur */
    /*----------------------*/
     
    try {
    	$link = new PDO($nom_du_serveur, $nom_utilisateur, $mot_de_passe, $options);
    }
    catch (Exception $e)
    {
    	echo "Connection à MySql impossible : ", $e->getMessage();
    	die();
    }
     
    /*---------------------*/
    /* lecture fichier xml */
    /*---------------------*/
     
    $ins = $link->prepare("insert into client (`num_id`,`nom`,`prenom`,`relation`,`adresse_c`,`code_postal`,`ville`) values (:p1,:p2,:p3,:p4,:p5,:p6,:p7)");
     
    $i=0;
    while ($i < $length)
    {
      try {
        $ins->bindParam('p1', $xml->cli[$i]->num_id);
        $ins->bindParam('p2', $xml->cli[$i]->contact->nom);
        $ins->bindParam('p3', $xml->cli[$i]->contact->prenom);
        $ins->bindParam('p4', $xml->cli[$i]->relation);
        $ins->bindParam('p5', $xml->cli[$i]->adresse->adresse_c);
        $ins->bindParam('p6', $xml->cli[$i]->adresse->code_postal);
        $ins->bindParam('p7', $xml->cli[$i]->adresse->ville);
     
        $ins->execute();
      }
      catch ( Exception $e )
      {
        echo "Une erreur est survenue dans le l'insert : ", $e->getMessage();
        die();
      }
     
      $i++;
    }
    /*---------------------------*/
    /* Vidage de la table client */
    /*---------------------------*/
     
    try {
    	$sel = $link->query("SELECT * FROM client");
    }
    catch ( Exception $e )
    {
    	echo "Une erreur est survenue dans le select : ", $e->getMessage();
    	die();
    }
     
    echo "<pre>";
    printf("+--------+--------+--------+----------+-----------------+-------------+----------+\n");
    printf("| Num Id |   Nom  | Prénom | Relation |     Adresse     | Code Postal |   Ville  |\n");
    printf("+--------+--------+--------+----------+-----------------+-------------+----------+\n");
     
    try {
    	while ($row = $sel->fetch(PDO::FETCH_ASSOC))
    		printf("|%7d |%7s |%7s |%9s |%16s |%12s |%9s |\n", $row['num_id'],$row['nom'],$row['prenom'],$row['relation'],$row['adresse_c'],$row['code_postal'],$row['ville']);
    }
    catch ( Exception $e )
    {
    	echo "Une erreur est survenue dans la lecture du select : ", $e->getMessage();
    	die();
    }
     
    printf("+--------+--------+--------+----------+-----------------+-------------+----------+\n");
    echo "</pre>";
     
    $sel->closeCursor();
     
    /*-----*/
    /* fin */
    /*-----*/
     
    $link = null;
     
    ?>
    </body>
    </html>
    C'est basique, mais au moins, cela fonctionne !

    Et voici le résultat à l'affichage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    +--------+--------+--------+----------+-----------------+-------------+----------+
    | Num Id |   Nom  | Prénom | Relation |     Adresse     | Code Postal |   Ville  |
    +--------+--------+--------+----------+-----------------+-------------+----------+
    |    120 | DUPOND | Pierre |      253 | route de la mer |       64200 | Biarritz |
    |    121 | DURANT |   Jean |      826 |                 |             |          |
    |    122 |  SMITH |   John |      999 |Bld des allonges |       13000 |Marseille |
    +--------+--------+--------+----------+-----------------+-------------+----------+
    Le bloc adresse dans mon exemple est totalement absent pour le client 121. Aucun affichage !
    Avec ce principe, nous pouvons lire tous champs du fichier XML.
    L'inconvénient est de faire un script php pour chaque fichier XML à charger.

    Conclusion : soit créer un fichier XML avec un seul niveau d'imbrication, quand cela est possible, soit faire cela en php.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  7. #7
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 124
    Points : 310
    Points
    310
    Par défaut
    J'ai donc décidé de le faire en php.
    Par contre je suis resté sur mon idée de générer un fichier SQL et ensuite de l’insérer via la console SQL (beaucoup plus rapide sachant que c'est systématiquement entre 40 000 et 100 000 lignes à insérer).
    En tout cas merci pour ton aide.

  8. #8
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 066
    Points
    19 066
    Par défaut
    Salut Jimmo.

    Citation Envoyé par Jimmo
    Par contre je suis resté sur mon idée de générer un fichier SQL et ensuite de l’insérer via la console SQL (beaucoup plus rapide sachant que c'est systématiquement entre 40 000 et 100 000 lignes à insérer).
    Je n'ai pas tout compris de l'utilité de ta demande.

    Je suppose que tu dois migrer des fichiers au format XML vers des tables MySql vide.
    Sauf que la structure de tes fichiers XML ne permet pas de faire l'insertion directement dans tes tables définitives.

    L'idée de base est de charger un fichier de type XML dans une table de travail.
    C'est pourquoi la colonne 'id' va numéroter dans l'ordre les lignes extraites du fichier XML.
    Comme il n'y a pas d'index qui pourrait ralentir le temps d'exécution de l'insert, le chargement est rapide.
    Tu peux aussi désactiver certaines fonctionnalités pour gagner encore plus de temps, juste avant de faire le chargement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    -- =============
    -- Désactivation
    -- =============
     
    TRUNCATE Cities;
     
    set unique_checks      = 0;
    set foreign_key_checks = 0;
    set sql_log_bin        = 0;
     
    alter table Cities DISABLE KEYS;
     
    commit;
    Puis après le chargement, tu peux les rétablir.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    -- ==========
    -- Activation
    -- ==========
     
    alter table Cities ENABLE KEYS;
     
    set unique_checks      = 1;
    set foreign_key_checks = 1;
    set sql_log_bin        = 1;
     
    commit;
    Comme tu as 4000 fichiers, il serait bon aussi d'ajouter une colonne dans tes tables de travail pour identifier chaque lot.

    C'est au final, quand tu as toutes tes tables de travail à ta disposition que tu peux faire le dispatching vers les tables définitives.

    Juste une dernière question. Ce chargement doit se faire une et une seule fois, ou bien d'une manière périodique ?

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  9. #9
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 124
    Points : 310
    Points
    310
    Par défaut
    J'ai effectivement environ 4000 fichiers à importer en bdd. Je ne peux pas toucher à la structure XML car le nombre de fichiers est beaucoup trop important.
    Mon script php permet de récupérer toutes les données du fichier xml et l'enregistre dans un fichier sql. Il ne me reste plus qu'à importer ce fichier sql et tout fonctionne.
    L'insertion ne se fait qu'une seule fois et ensuite des insertions hebdomadaires mais uniquement de quelques dizaines de lignes.
    Aucune requête de type UPDATE ou DELETE.
    Pour charger mon fichier xml, j'utilise le code suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $filename = "fichier1.xml";
    $xml = simplexml_load_file($filename);
    Le problème, je dois manuellement renseigner le nom du fichier xml.
    Y a t il une possibilité de scanner le dossier et récupérer les noms de fichiers et les traiter automatiquement l'un après l'autre?

  10. #10
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 066
    Points
    19 066
    Par défaut
    Salut jimmo.

    Citation Envoyé par jimmo
    J'ai effectivement environ 4000 fichiers à importer en bdd.
    Tes 4000 fichiers XML ont tous la même structure ?

    Citation Envoyé par jimmo
    L'insertion ne se fait qu'une seule fois et ensuite des insertions hebdomadaires mais uniquement de quelques dizaines de lignes.
    Aucune requête de type UPDATE ou DELETE.
    C'est de l'archivage que tu fais ?

    Citation Envoyé par jimmo
    Y-a-t-il une possibilité de scanner le dossier et récupérer les noms de fichiers et les traiter automatiquement l'un après l'autre?
    Pour lister les fichiers ayant comme suffixe ".xml", tu procèdes ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    <!doctype html>
    <html>
    <head>
    <meta charset="ISO-8859-1" />
    <title>List des fichiers !</title>
    <link rel="stylesheet" type="text/css" href="Css/Styles.css">
    </head>
     
    <body>
    <h1>Chargement fichier de type XML !</h1>
    <pre>
    <?php
    $chemin = "F:/Site-02/Ex_05/XML";
     
    if ($handle = opendir($chemin)) 
    {
    	while ($file = readdir($handle))
    	{
    		if (stristr($file, '.xml'))
    		{
    			echo "fichier ==> ".$file."\n";
    		}
    	}
     
    	closedir($handle);
    }
    ?>
    </pre>
    </body>
    </html>
    Je l'ai testé et ça fonctionne.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  11. #11
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 124
    Points : 310
    Points
    310
    Par défaut
    Salut,
    effectivement ce n'est que de l'archivage.
    Ensuite je créé une api de lecture.
    Par contre, et la je change un peu de sujet...
    L’accès à la base de données via l'api demande un enregistrement préalable.
    Je génère une clé api unique.
    Comment vérifier l’authenticité de la clé?
    Car j'aimerai éviter un code php du genre
    $req= $db->prepare('SELECT api_key FROM user WHERE api_key=:api_key')
    ......
    si résultat ok =>récupération des informations dans la bdd
    si résultat pas ok => La clé api est fausse

    je n'en ai pas la moindre idée

  12. #12
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 066
    Points
    19 066
    Par défaut
    Salut Jimmo.

    J'ai pas bien compris l'utilité de cette clef ? Ni ce que cela représente ?
    Est-ce un mot de passe ? Ou une manière d'identifier l'archive que l'utilisateur peut consulter ?

    Ne serait-il pas mieux de restreindre l'accès, via MySql, de tes archives en fonction de l'identifiant user + hôte à la base de données ?
    En gros, de restreindre la sécurité aux seuls utilisateurs concernés.
    Ce qui implique de mettre l'archivage dans une autre base de données destinées uniquement à cela.
    En fonction des utilisateurs, tu peux même restreindre les accès à quelques tables, voire aussi à quelques colonnes de ces mêmes tables.
    Mais tu devras faire l'usage des view !

    Si tu veux utiliser le select, mais sans le mettre dans le script php, une solution est de faire une procédure stockée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
        DEFAULT CHARACTER SET `latin1`
        DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `test`
    --------------
     
    --------------
    create table `test` (
      `id`    integer unsigned auto_increment NOT NULL PRIMARY KEY,
      `clef`  char(255)                       NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `test` (`clef`) values (md5('12345679'))
    --------------
     
    --------------
    select * from test
    --------------
     
    +----+----------------------------------+
    | id | clef                             |
    +----+----------------------------------+
    |  1 | defac44447b57f152d14f30cea7a73cb |
    +----+----------------------------------+
    --------------
    create procedure `api_key` (
    IN   in_clef varchar(255),
    OUT out_res     char(02)
    )
    DETERMINISTIC
    NO SQL
    BEGIN
    set out_res = ifnull((select 'ok' from test where clef = md5(in_clef)), 'ko');
    END
    --------------
     
    --------------
    CALL api_key('12345679', @tst)
    --------------
     
    --------------
    select @tst as resultat
    --------------
     
    +----------+
    | resultat |
    +----------+
    | ok       |
    +----------+
    --------------
    CALL api_key('12345678', @tst)
    --------------
     
    --------------
    select @tst as resultat
    --------------
     
    +----------+
    | resultat |
    +----------+
    | ko       |
    +----------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
     
    Appuyez sur une touche pour continuer...
    Sinon, après, je ne voie pas trop ce que l'on peut faire d'autre.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  13. #13
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 124
    Points : 310
    Points
    310
    Par défaut
    Bonjour,
    en fait, cette clé unique permet d'identifier l'utilisateur (équivalent a un couple login+password)
    Je voudrai éviter les aller retour de requêtes. Alors effectivement, j'avais pensé aux procédures stockées. Mais comme je n'en ai jamais fais, je voulais voir s'il existait autre chose.
    ou alors peut être existe-il un autre système d'identification. j'ai lu différentes choses mais sans trop savoir quoi en penser....
    bref.. Bon dimanche

  14. #14
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 066
    Points
    19 066
    Par défaut
    Salut Jimmo.

    Précédemment, je disais de faire une connexion personnalisée à la base de données MySql, en mettant un user+password différent pour chaque utilisateur.
    Car si tu t'identifies par user+password, en mettant la même chose pour tous les utilisateurs qui vont se connecter, ta clef api va faire double emploi.
    Autant ne pas traiter ta clef api, et permettre une identification personnalisé (user+password) pour chaque utilisateur, lors de la connexion à la base de données.

    As-tu beaucoup d'utilisateurs qui vont consulter tes archives ?

    Ce que tu peux faire aussi, c'est demander une identification par Apache :
    --> https://httpd.apache.org/docs/2.4/fr/howto/auth.html

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  15. #15
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 124
    Points : 310
    Points
    310
    Par défaut
    salut Artemus24,

    en fait, mdp + login pour la création du compte, et clé unique pour accéder à la base de donnés.
    Je suis passé par une procédure stockée. Le boulot se fait bien donc je garde ce système pour le moment.
    Par contre, j'ai lu qu'une procédure stockée prenait de la place en bdd. en quoi est ce gourmand? pourquoi ne pas mettre le maximum de requêtes en bdd?
    Autre point, je sais, je m’éparpille énormément
    J'ai besoin de réaliser une requête sql toutes les nuits. Pour cela, j'utilise crontab.
    Je voudrai juste savoir si la façon dont cela est fait est propre ou pas du tout.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    crontab -e
    * 4 * * *  source /path/to/script/script.cmd
    le code de script.cmd
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mysql -u root -h host -D bddn -pPassword < /path/to/scriptSql/script.sql
    le script script sql
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DELETE FROM maTable WHERE status=0
    Voila tout... Merci

  16. #16
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 381
    Points : 19 066
    Points
    19 066
    Par défaut
    Salut Jimmo.

    Citation Envoyé par Jimmo
    Autre point, je sais, je m’éparpille énormément
    Mais non.

    Citation Envoyé par Jimmo
    Je suis passé par une procédure stockée. Le boulot se fait bien donc je garde ce système pour le moment.
    Par contre, j'ai lu qu'une procédure stockée prenait de la place en bdd. en quoi est ce gourmand? pourquoi ne pas mettre le maximum de requêtes en bdd?
    Cela ne prend rien comme place. Tu utilises une procédure stockée, quand tu dois faire un traitement complexe, qui va passer son temps à faire des allez-retour entre php et MySql.
    Le mieux est de tout faire du coté MySql, donc sous forme de procédure stockée, afin d'optimiser le traitement. Donc oui, c'est gourmand en I/O.
    Il ne faut pas non plus abuser, et tout faire avec des procédures stockées.
    Par exemple, un batch de nuit, qui va balayer la base de données afin de faire quelques mise à jour est une bonne solution.
    La où tu perds du temps, c'est l'inter-connexion entre php et mysql.

    Je travaille avec des scripts MySql qui sont déclenchés par un batch Windows et donc, je ne fais pas de Linux.
    Pour déclencher un script MySql, tu fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mysql --user=root  --host=localhost  --password=toor  --database=bddn  --verbose  --force  source /path/to/scriptSql/script.sql >> output.txt
    Je préfère mettre les options en entiers (avec deux tirets) plutôt que la forme abrégée (un seul tiret) :
    --> https://dev.mysql.com/doc/refman/5.7...d-options.html

    Pour le script mysql, ne pas oublier de préciser la base de données :
    [code]use nom_de_la_base_de_données;
    delete from `matable` where `status` = 0;
    Attention aux mots réservés. Tu peux les mettre entre ` (touche altgr + 8).

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  17. #17
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    124
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 124
    Points : 310
    Points
    310
    Par défaut
    Merci pour les infos,
    J'apprends et comble du bonheur, ce que j'apprends fonctionne. Voila qui fait plaisir
    et ici la suite de mes questions
    http://www.developpez.net/forums/d15...s-differentes/

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Batch] batch Extraction données XML (entre 2 balise)
    Par alucardu77600 dans le forum Scripts/Batch
    Réponses: 1
    Dernier message: 24/12/2014, 13h06
  2. Extraction de données xml sur un serveur avec extjs
    Par dasdo dans le forum Ext JS / Sencha
    Réponses: 1
    Dernier message: 30/07/2009, 20h03
  3. Extract données dans un fichier .XML ?
    Par merssemic dans le forum SQL
    Réponses: 4
    Dernier message: 12/10/2007, 11h00
  4. [XML][tinyXML] Problême d'extraction de données XML ac tinyxml
    Par Jahprend dans le forum Bibliothèques
    Réponses: 1
    Dernier message: 19/03/2007, 09h35
  5. [XSLT] php xml xslt extraction données
    Par Cyrille1969 dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 26/04/2006, 23h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo