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

SQLite Discussion :

Import CSV dans base SQLite vide mais structurée, possible ?


Sujet :

SQLite

  1. #1
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Import CSV dans base SQLite vide mais structurée, possible ?
    Bonjour à tous,

    j'ai besoin de votre avis sur un projet que je viens de commencer. Il s'agit de traiter l'information contenue dans plusieurs tables extraites au format csv (1 fichier = 1 table) à partir d'une base de données. Le but étant de pouvoir in fine réaliser un certain nombre de requêtes statiques sur ces tables par l'intermédiaire d'un exécutable ou script.
    Voici comment je pense concevoir la chose:

    1\ Utilisation de SQLite comme SGDB
    2\ Création d'une base dans SQLite et création d'une structure identique à la base de données originelle
    3\importation des fichiers csv dans chacune des tables précédemment créées
    4\réalisation d'un script (Python ?) ou programme permettant d'automatiser l'étape précédente et d'envoyer les requêtes ...

    Pour résumer, initialement, en entrée, l'utilisateur final à des fichiers csv + une base de données SQL "vide" + un script/appli. Pour finir, en sortie, l'utilisateur obtient un ou plusieurs fichiers (txt, html ou xls à définir) résultat des requêtes prédéfinis dans mon script.

    Étant débutant dans le monde parfois bien obscur du développement informatique (en tout cas pour moi !), j'aimerai que vous vous prononciez sur la faisabilité de la chose. Je suis bien entendu preneur de toutes les remarques, consignes, aides au développement, choix logiciel, Tips ..!

    D'autre part, j'indique qu'il n'est pas facile (voir faisable) de réaliser des requêtes sur la base de données initiales ayant permis de générer les fichiers csv, ça serait trop simple ...

    Merci pour votre attention.

  2. #2
    Membre actif

    Inscrit en
    Décembre 2004
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 169
    Points : 225
    Points
    225
    Par défaut
    Bonjour,

    Évidemment, la question amène une réponse positive : SQLite est justement taillé pour ce genre de manipulation.

    Imaginons une table dans une base vide :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    create table users (
    id integer,
    nom text,
    prenom text,
    datnais text);
    Un fichier texte "fichier.csv" du genre :
    1;Grandimortal;Paul;23/12/1998
    2;Grandalpha;Jean;08/01/1981
    Alors un script d'importation serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    .mod csv
    .separator ;
    .import fichier.csv users
    Si ce script est nommé "importer.sql" alors il suffit de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sqlite3 mabase.db ".read importer.sql"
    pour que le script soit exécuté et les données ajoutées à la table "users".

    Si on veut que les données importées effacent et remplacent toute la table il suffit de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    delete * from users;
    .mod csv
    .separator ;
    .import fichier.csv users
    Si on veut ignorer la première ligne du csv car elle contient les noms de colonnes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    delete * from users;
    .mod csv
    .separator ;
    .import fichier.csv users
    delete * from users where rowid = 1;

    Naturellement, le script d'importation peut être complexe, il peut lancer des traitements, dumper des données dans des fichiers de sortie,... bref, SQLite est un outil qui s'insère parfaitement dans des fichiers de commandes.

  3. #3
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Merci pour ta réponse bigane, je me replonge dans ce projet après une interruption involontaire ...
    Sachant que dans mon fichier .CSV le premier enregistrement correspond aux noms des colonnes, n'y-a-t-il pas la possibilité de l'indiqué au moment de l'import et ainsi condenser la création d'une nouvelle table et l'import effective des données ?

  4. #4
    Membre actif

    Inscrit en
    Décembre 2004
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 169
    Points : 225
    Points
    225
    Par défaut
    Bonjour,

    Sachant que dans mon fichier .CSV le premier enregistrement correspond aux noms des colonnes, n'y-a-t-il pas la possibilité de l'indiqué au moment de l'import et ainsi condenser la création d'une nouvelle table et l'import effective des données ?
    Non à ma connaissance il n'y a pas de moyen de l'indiquer en ligne de commande. La fonction d'importation n'existe que dans l'exécutable sqlite3, c'est une sorte de mise en pratique de la librairie. Car, il faut se le rappeler, sqlite est une librairie de fonction que l'on peut modifier et incorporer dans un projet soit directement (sources en c) soit en passant par une dll (ou équivalent sous Linux).

    Donc, le programme sqlite3 est un cadeau, un plus, que les développeurs nous mettent à disposition. Il évolue très peu et possède un "bug" référencé au niveau de l'importation des chaînes textes en csv.
    Ainsi, en mode ".csv", le séparateur est une virgule par défaut. Mais si l'on importe ceci dans un fichier csv :
    1,"une route, un pont"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    create table essai ( id int, info text);
    .mod csv
    .import essai.txt essai
    Le moteur d'importation plante car il ne voit pas que la seconde virgule fait partie d'un champ texte.

    Error: essai.txt line 1: expected 2 columns of data but found 3
    Une bonne solution consiste à modifier le caractère de séparation des champs pour obtenir un caractère inutilisé dans les champs.
    exemples :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    .separator "|" (séparation par défaut au lancement de sqlite3)
    ou
    .separator "\t" (pour la tabulation)
    ou 
    .separator "¤" (un caractère rare) ...


    Voilà, tu es prévenu. Il faut faire des essais mais c'est un outil passionnant.
    ++

  5. #5
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Je te remercie pour tous ces bons conseilles. Avec les informations que j'ai pu glaner à droite et à gauche je pense avoir une bonne vision d'ensemble sur mon projet.

    Je pense réaliser la création de la BD SQLite et l'importation des fichiers CSV en rajoutant quelques ligne C# à un programme existant. Par contre, pour ce qui est des requêtes permettant d'interroger la base cela sera sous forme de script afin de donner l'opportunité aux futurs utilisateurs de les modifier si le besoin sans faisait sentir. Reste à savoir sous quel format sortiront les données tirées d'une requête de type SELECT * FFROM ... Je n'ai pas encore étudié la question mais il serait interressant d'avoir également des fichiers CSV en sortie de Script ! Toujours preneur de bons conseille !?
    A+

  6. #6
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Question du vendredi soir ...

    Pour l'importation d'un fichier CSV sauvegardé à un autre endroit que l'exectable sqlite3.exe, on fait comment ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    .mod csv
    .separator ;
    .import "./CSVDirectory/users.csv" tableUsers
    ce bout de code ne passe pas ..?

  7. #7
    Membre actif

    Inscrit en
    Décembre 2004
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 169
    Points : 225
    Points
    225
    Par défaut
    Bonjour,

    Ta syntaxe est parfaite (mais je ne l'ai testé que sous DOS), le problème vient d'ailleurs.

    Donne le message de erreur si tu veux de l'aide sur ce point.

    Sinon, au cas où, j'ai légèrement retravaillé SQLite3.exe afin d'avoir un import compatible avec la majorité des exports en csv (notamment ceux d'OpenOffice par défaut avec virgule comme séparateur de champ et les guillements).
    Au résultat, j'importe sans difficulté les fichiers sauvegardés en CSV de ce type :

    1,"une phrase avec virgule,
    et retour chariot","",Un_champ_sans_guillemet,,"des ""guillemets"" ici !"
    J'ai posté le code sur le forum en VO, mais au cas où, je me répète un peu ici.
    Ce qui est dommage, c'est que l'indentation ait sauté dans le mail... mais bon, ça peu aider.

    ++

    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
    Patch source code of shell.c :
    ==============================
     
     
    /* patch for shell.c version 3_6_23_1 */
     
     
    // I modified the local_getline() function
     
    // from line 41:
     
    #if defined(HAVE_READLINE) && HAVE_READLINE==1
    # include <readline/readline.h>
    # include <readline/history.h>
    #else
    # define readline(p) local_getline(p,stdin,0)
    # define add_history(X)
    # define read_history(X)
    # define write_history(X)
    # define stifle_history(X)
    #endif
     
     
    // from line 368:
     
    static char *one_input_line(const char *zPrior, FILE *in){
    char *zPrompt;
    char *zResult;
    if( in!=0 ){
    return local_getline(0, in, 0); /* not in csv mode */
    }
     
     
    // function local_getline(), from line 320 :
     
    /* NB: bCsvMode = 1, if the function is used by the .import command */
     
    static char *local_getline(char *zPrompt, FILE *in, const int bCsvMode){
    char *zLine;
    int nLine;
    int n;
    int eol;
    int bEscaped; /* Escape CRLF when quoted */
     
    if( zPrompt && *zPrompt ){
    printf("%s",zPrompt);
    fflush(stdout);
    }
    nLine = 100;
    zLine = malloc( nLine );
    if( zLine==0 ) return 0;
    n = 0;
    eol = 0;
    bEscaped = 0;
    while( !eol ){
    if( n+100>nLine ){
    nLine = nLine*2 + 100;
    zLine = realloc(zLine, nLine);
    if( zLine==0 ) return 0;
    }
    if( fgets(&zLine[n], nLine - n, in)==0 ){
    if( n==0 ){
    free(zLine);
    return 0;
    }
    zLine[n] = 0;
    eol = 1;
    break;
    }
    while( zLine[n] ){
    if( zLine[n]=='"' && bCsvMode ) bEscaped = 1 - bEscaped;
    n++;
    }
    if( !bEscaped && n>0 && zLine[n-1]=='\n' ){
    n--;
    if( n>0 && zLine[n-1]=='\r' ) n--;
    zLine[n] = 0;
    eol = 1;
    }
    }
    zLine = realloc( zLine, n+1 );
    return zLine;
    }
     
     
     
    // and from line 1628 :
     
     
    sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
    zCommit = "COMMIT";
    while( (zLine = local_getline(0, in, 1))!=0 ){ /* csv mode */
    char *z;
    char *q;
    int bEscaped; /* to escape quote + comma + quote */
    int bFieldQuoted;
    bEscaped = 0;
    i = 0;
    lineno++;
    if( *zLine=='"' ){
    azCol[0] = zLine + 1; /* ignore the first quote */
    bFieldQuoted = 1;
    }else{
    azCol[0] = zLine;
    bFieldQuoted = 0;
    }
    for(i=0, z=zLine, q=zLine; *z ; z++){
    if( *z=='"' ) bEscaped = 1 - bEscaped;
    if( bEscaped==0 && *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
    if( bFieldQuoted==1 && *q=='"') *q = 0; /* ignore the last quote */
    *z = 0;
    i++;
    if( i<nCol ){
    azCol[i] = &z[nSep];
    if( *azCol[i]=='"' ){
    azCol[i]++; /* ignore the first quote */
    bFieldQuoted = 1;
    }else{
    bFieldQuoted = 0;
    }
    z += nSep-1;
    }
    }
    q = z;
    } /* end for */
    if( bEscaped==0 && bFieldQuoted==1 && *q=='"' ) *q = 0; /* ignore the last quote */
    *z = 0;
    if( i+1!=nCol ){
    fprintf(stderr,
    "Error: %s line %d: expected %d columns of data but found %d\n",
    zFile, lineno, nCol, i+1);
    zCommit = "ROLLBACK";
    free(zLine);
    rc = 1;
    break; /* from while */
    }
    for(i=0; i<nCol; i++){
    /* find and reduce double quotes */
    for( bEscaped=0, z=azCol[i], q=azCol[i]; *z ; z++, q++){
    if( *z=='"' ) z++;
    *q = *z;
    }
    *q = 0;
    sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
    }
    sqlite3_step(pStmt);
    rc = sqlite3_reset(pStmt);
    free(zLine);
     
     
    // end

  8. #8
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    merci pour ton aide,
    A+

Discussions similaires

  1. Réponses: 2
    Dernier message: 08/01/2015, 18h32
  2. [MySQL-5.5] Importer contenu de fichier csv dans base de données MySQL
    Par sydko dans le forum Administration
    Réponses: 2
    Dernier message: 16/10/2013, 14h13
  3. [Shell] import CSV dans une base de données.
    Par AngeDéchu dans le forum Shell et commandes GNU
    Réponses: 11
    Dernier message: 18/01/2012, 21h14
  4. [SQL-Server] importer csv dans une base de sql server avec php
    Par berroudji dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 21/06/2010, 09h23
  5. importer CSV dans une base
    Par altair8080 dans le forum Ruby on Rails
    Réponses: 8
    Dernier message: 20/09/2009, 14h51

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