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

Python Discussion :

Convertion csv vers python


Sujet :

Python

  1. #21
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 696
    Par défaut
    Citation Envoyé par dedalios Voir le message
    Déjà la lecture des données ce fait 1 ligne par 1 ligne .
    puis j'ai conditionné le chargement de "records" en cherchant a vérifier si le tuple record existait ou pas dans la liste "records"
    Si vous aviez la curiosité de faire un print de records juste avant l'insertion en base, vous verriez que votre modification ne sert à rien car records contient au plus 2 lignes.

    Après, la solution (que je préfère plutôt maintenir le tas de records qui ont déjà été écrit) est de regarder ce que sait faire sqlite côté INSERT pour gérer cela i.e. modifier la requête SQL ''insert into actes(code, libelle) values(?,?)''' mais en connaissance de cause (et poser des questions dans un forum base de données).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  2. #22
    Membre éclairé Avatar de dedalios
    Homme Profil pro
    concepteur d'application
    Inscrit en
    Février 2008
    Messages
    495
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : concepteur d'application
    Secteur : Santé

    Informations forums :
    Inscription : Février 2008
    Messages : 495
    Par défaut Solution
    Bonjour voici la solution -Est-ce la meilleur ?
    je vais tester sur des volumes plus important

    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
    # coding: utf-8  
    import csv
    import sqlite3
    from collections import namedtuple
     
    record = namedtuple('record', 'code, libelle')
     
    def EstceNull(src):
        if src =='NULL':
            return  None
        else:
            return src
     
    class Reader:
        def __init__(self, file):
            self._reader = csv.reader(file, delimiter=' ')
     
        def get_records(self, count=3):
            records = []
            try:
                for _ in range(count): #injection par groupe de 3 lignes et vérifier les doublons
                    row = next(self._reader)
                    # on construit les tuples 
                    enregistrement = record(int(row[0]), EstceNull(row[1]))
                    # on vérifie les doubles  
                    if(enregistrement  not in records):
                        records.append(enregistrement)
            except StopIteration:
                pass
            except:
                raise
            return records
     
     
    class Writer:
        def __init__(self, path=':memory:'):
        #def __init__(self, path='mem.db'):    
            cnx = self._cnx = sqlite3.connect(path)
            commandesql = '''drop table if  exists actes;  ''' 
     
            try:
                cnx.execute(commandesql)   
            except sqlite3.Error as e: 
                print("Problème"+ " :" +   e.args[0]  + " sur commande /n"+ commandesql )
                self._cnx.rollback()
            else:
                self._cnx.commit()      
     
            commandesql =    '''create table if not exists
                    actes(code integer, libelle text ,  
                    CONSTRAINT code_pk PRIMARY KEY(code));'''
     
            try:
                cnx.execute(commandesql)  
            except sqlite3.Error as e: 
                print("Problème"+ " :" +   e.args[0]  + " sur commande /n"+ commandesql )
                self._cnx.rollback()
            else:
                self._cnx.commit()        
     
     
        def writesmany(self, records):
            with self._cnx:
                try:
                    self._cnx.executemany('''insert into actes(code, libelle) values(?,?)''', records)
                except sqlite3.Error as e:
                    print("Problème"+ " :" +   e.args[0]  + " sur commande d'insertion /n" )  
     
                    print("\t"  +str(records))
                    self._cnx.rollback()
                    # dans le cas d'un problème d'injection multipls on repasse à la mono injection au cas par cas
                    # et on laisse les mécasnisme de sécurite de la base agir
                    self.writemono( records)
                else: 
                    self._cnx.commit()
     
        def writemono(self, records):
            with self._cnx:
                for enregistrement in records:
                    try:
                        self._cnx.execute('''insert into actes(code, libelle) values(?,?)''', enregistrement)
                    except sqlite3.Error as e:
                        print("Problème"+ " :" +   e.args[0]  + " sur commande d'insertion /n" )  
     
                        print("\t"  +str(enregistrement))
                        self._cnx.rollback()
                    else: 
                        self._cnx.commit()
     
        def dump(self):
            with self._cnx:
                for row in self._cnx.execute('select * from actes'):
                    print (row)
     
     
     
    def load(reader, writer):
        while 1:
     
            records = reader.get_records()
            print(records)
            if not records: break
            writer.writesmany(records)
     
     
    if __name__ == '__main__':
        from io import StringIO
     
        actes = ('1 aaa\n'
                 '2 bbb\n'
                 '3 ccc\n'
                 '4 ddd\n'
                 '4 ddd\n'
                 '5 eeeeee\n'
                 '6 fefeefe\n'
                 '3 ccc\n'
                 '3 ccc\n'
                 '101 xxxx\n'
                 '9 NULL\n'
                 '111 NULL\n'
                 )
     
        writer = Writer()
        load(Reader(StringIO(actes)), writer)
        writer.dump()

    Le résultat des print

    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
    [record(code=1, libelle='aaa'), record(code=2, libelle='bbb'), record(code=3, libelle='ccc')]
    [record(code=4, libelle='ddd'), record(code=5, libelle='eeeeee')]
    [record(code=6, libelle='fefeefe'), record(code=3, libelle='ccc')]
    Problème :UNIQUE constraint failed: actes.code sur commande d'insertion /n
    	[record(code=6, libelle='fefeefe'), record(code=3, libelle='ccc')]
    Problème :UNIQUE constraint failed: actes.code sur commande d'insertion /n
    	record(code=3, libelle='ccc')
    [record(code=101, libelle='xxxx'), record(code=9, libelle=None), record(code=111, libelle=None)]
    []
    (1, 'aaa')
    (2, 'bbb')
    (3, 'ccc')
    (4, 'ddd')
    (5, 'eeeeee')
    (6, 'fefeefe')
    (9, None)
    (101, 'xxxx')
    (111, None)
    Principe la classe reader charge la liste records de 3 tuples extrait du "fichier" en mémoire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       def get_records(self, count=3):
    Traite et effectue les convertions des données du "fichier" en mémoire en tuple .
    Il injecte ce tuple dans la liste "records" en vérifiant sur s'il n'est pas déjà présent.

    La classe write s'occuper de la base de donneés
    Elle construit et charge la base.
    les insertions par defaut sont faite via une commande executemany (writesmany)
    mais si la base retour une impossibilité d'insertion
    on charge les donnees à l'unite (writemono) avec la même sécurité sur le processus d'insertion

  3. #23
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 696
    Par défaut
    Citation Envoyé par dedalios Voir le message
    Bonjour voici la solution -Est-ce la meilleur ?
    En ce qui me concerne, je pense vous avoir déjà répondu et suggéré d'ouvrir la documentation de sqlite3 pour étudier les options à ajouter à INSERT dans ce cas.
    Ce qui permettrait de traiter les doublons en ne modifiant qu'une seule ligne du code initial.

    Après si vous voulez faire çà en testant, s'il y a des doublons (sans le tester sur tous les enregistrements) puis en gérant les IntegrityError de l'INSERT de base (le test précédent ne servant à rien)... c'est comme vous voulez mais c'est pas la peine de demander si c'est "le meilleur".

    Pour info:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    record = namedtuple('record', 'code, libelle')
     
    def EstceNull(src):
        if src =='NULL':
            return  None
        else:
            return src
    s'écrit aussi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> class record(namedtuple('record', 'code, libelle')):
    ...       def __new__(cls, code, libelle):
    ...           if libelle == 'NULL':
    ...              libelle = None
    ...           return super().__new__(cls, code, libelle)
    ...
    >>> record(1, 'NULL')
    record(code=1, libelle=None)
    >>> record(1, 'NULA')
    record(code=1, libelle='NULA')
    >>>
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #24
    Membre éclairé Avatar de dedalios
    Homme Profil pro
    concepteur d'application
    Inscrit en
    Février 2008
    Messages
    495
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : concepteur d'application
    Secteur : Santé

    Informations forums :
    Inscription : Février 2008
    Messages : 495
    Par défaut SQL et INSERT
    A ma connaissance en base de donnée dans une insertion multi enregistrement le rollback invalide l'insertion du bloc complet d'instruction et ne fait pas de différence entre le fait que tout ou partie des enregistrements ne soit valide ou pas.

    S'il existe une clé primaire sur code dans la table actes alors

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    insert into actes(code, libelle) values(
    (10,"xxx") ,
    (11,"xxx") ,
    (12,"xxx") ,
    (10,"xxx") ,
    (10,"xxx") );
    l'intégralité de la requêtes sql est rejeté pour une anomalie de clé primaire.

    Je suppose que concernant l'utilisation d'un fichier , il suffirait de modifier la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       load(Reader(StringIO(actes)), writer)
    pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        load(Reader("monfichier.csv" ), writer)
    pour autant je me demande comment faire pour ne pas traiter le première enregistrement du fichier csv...

  5. #25
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 696
    Par défaut
    Citation Envoyé par dedalios Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    insert into actes(code, libelle) values(
    (10,"xxx") ,
    (11,"xxx") ,
    (12,"xxx") ,
    (10,"xxx") ,
    (10,"xxx") );
    Allez je vous redonne la page de la documentation d'INSERT sur sqlite3 à lire (les autres SGDB implémentent cela autrement).

    Citation Envoyé par dedalios Voir le message
    Je suppose que concernant l'utilisation d'un fichier , il suffirait de modifier la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       load(Reader(StringIO(actes)), writer)
    pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        load(Reader("monfichier.csv" ), writer)
    pour autant je me demande comment faire pour ne pas traiter le première enregistrement du fichier csv...
    Vous pouvez le faire pour tous les fichiers de façon arbitraire; en fonction de votre connaissance du fichier en ajoutant un paramètre genre skip=n qui jette les n premières lignes; ou en réalisant une heuristique qui s'amuse à détecter si la première ligne est une en-tête et alors la sauter...
    De toutes façons, puisque vous allez faire des conversions ou des tests d'intégrité vous devez avoir des informations sur le type de donnée de chaque colonne ne serait-ce que pour pousser des tuples correct vis à vis du schéma de la table: s'il y a des colonnes contenant autre chose que des chaînes de caractères, une heuristique basique est facile à réaliser.

    Et si vous ne vous en sortez pas, il serait temps d'ouvrir un nouvelle discussion car le sujet de celle-ci étant:
    Citation Envoyé par dedalios Voir le message
    Je cherche donc realiser les insertions en base par bloc de 50 voir 100 insert .
    çà fait longtemps qu'on y a répondu.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #26
    Membre éclairé Avatar de dedalios
    Homme Profil pro
    concepteur d'application
    Inscrit en
    Février 2008
    Messages
    495
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : concepteur d'application
    Secteur : Santé

    Informations forums :
    Inscription : Février 2008
    Messages : 495
    Par défaut Curieuse effet
    CAS N°1

    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
     
    # coding: utf-8  
    import csv
    import sqlite3
    from collections import namedtuple
     
    def EstceNull(src):
        if src =='NULL':
            return  None
        else:
            return src
     
    record = namedtuple('record', 'code, libelle')
     
    class Reader:
        def __init__(self, file):
            self._reader = csv.reader(file, delimiter=' ')
     
        def get_records(self, count=5):
            records = []
            try:
                for _ in range(count):
                    row = next(self._reader)
                    records.append(record(int(row[0]), EstceNull( row[1])))
            except StopIteration:
                pass
            except:
                raise
            return records
     
     
    class Writer:
        def __init__(self, path=':memory:'):
            cnx = self._cnx = sqlite3.connect(path)
            cnx.execute('''create table if not exists actes(code integer, libelle text);''')
     
        def write(self, records):
            with self._cnx:
                self._cnx.executemany('''insert or ignore into actes(code, libelle) values(?,?)''', records)
     
        def dump(self):
            with self._cnx:
                for row in self._cnx.execute('select * from actes'):
                    print (row)
     
    def load(reader, writer):
        while 1:
     
            records = reader.get_records()
            if not records: break
            writer.write(records)
     
     
    if __name__ == '__main__':
        from io import StringIO
     
        actes = ('1 aaa\n'
                 '2 bbb\n'
                 '3 ccc\n'
                 '4 ddd\n'
                 '5 ddd\n'
                 '6 ddd\n'
                 '15 eeee\n'
                 '2 bbb\n'
                 '33 qqq\n'
                 '15 NULL\n'
                 '2 bbb\n'
                 '33 qqq\n'
                 )
     
        writer = Writer()
        load(Reader(StringIO(actes)), writer)
        writer.dump()
    CAN°2
    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
    # coding: utf-8  
    import csv
    import sqlite3
    from collections import namedtuple
     
    def EstceNull(src):
        if src =='NULL':
            return  None
        else:
            return src
     
    class record(namedtuple('record', 'code, libelle')):
        def __new__(cls, code, libelle):
            if libelle == 'NULL':
                libelle = None
                return super().__new__(cls, code, libelle)
     
    class Reader:
        def __init__(self, file):
            self._reader = csv.reader(file, delimiter=' ')
     
        def get_records(self, count=5):
            records = []
            try:
                for _ in range(count):
                    row = next(self._reader)
                    records.append(record(int(row[0]), row[1]))
            except StopIteration:
                pass
            except:
                raise
            return records
     
     
    class Writer:
        def __init__(self, path=':memory:'):
            cnx = self._cnx = sqlite3.connect(path)
            cnx.execute('''create table if not exists actes(code integer, libelle text);''')
     
        def write(self, records):
            with self._cnx:
                self._cnx.executemany('''insert or ignore into actes(code, libelle) values(?,?)''', records)
     
        def dump(self):
            with self._cnx:
                for row in self._cnx.execute('select * from actes'):
                    print (row)
     
    def load(reader, writer):
        while 1:
     
            records = reader.get_records()
            if not records: break
            writer.write(records)
     
     
    if __name__ == '__main__':
        from io import StringIO
     
        actes = ('1 aaa\n'
                 '2 bbb\n'
                 '3 ccc\n'
                 '4 ddd\n'
                 '5 ddd\n'
                 '6 ddd\n'
                 '15 eeee\n'
                 '2 bbb\n'
                 '33 qqq\n'
                 '15 NULL\n'
                 '2 bbb\n'
                 '33 qqq\n'
     
     
                 )
     
        writer = Writer()
        load(Reader(StringIO(actes)), writer)
        writer.dump()
    Si je comprends tes propos le résultat devrait être identique?

    la class record ce chargeant de la convertion du texte 'NULL' en valeur None

  7. #27
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 696
    Par défaut
    Je vois que vous vous êtes enfin décidé à ouvrir la documentation de sqlite3...

    Citation Envoyé par dedalios Voir le message
    Si je comprends tes propos le résultat devrait être identique?
    Voilà. Sauf que, vu l'indentation que vous avez mis à la ligne 16 le code n°2 doit se vautrer (ce que vous pourriez signaler)... Et c'est ce qu'il se passe lorsqu'on ne comprends pas le code qu'on recopie.

    L'idée est de pousser dehors tout ce qui concerne la construction de "record" à partir de la "row" récupérée par le Reader du CSV. Le boulot du Reader est juste de faire des paquets de "records". Si on l'encombre de ce détail, on aurait autant de Reader que de fichiers CSV. Ce qui n'est pas malin.

    Et si vous ne vous en sortez pas, ouvrez une nouvelle discussion.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #28
    Membre éclairé Avatar de dedalios
    Homme Profil pro
    concepteur d'application
    Inscrit en
    Février 2008
    Messages
    495
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : concepteur d'application
    Secteur : Santé

    Informations forums :
    Inscription : Février 2008
    Messages : 495
    Par défaut
    Oui je vois l'indentation du return est mal placé il se retrouve intégé au IF et donc si le test de la valeur "NULL" n'est pas validé la fonction ne retourne aucune valeur


    Code erroné
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class record(namedtuple('record', 'code, libelle')):
        def __new__(cls, code, libelle):
            if libelle == 'NULL':
                      libelle = None
                      return super().__new__(cls, code, libelle)
    code correcte

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class record(namedtuple('record', 'code, libelle')):
        def __new__(cls, code, libelle):
            if libelle == 'NULL':
                      libelle = None
            return super().__new__(cls, code, libelle)



    Le boulot du Reader est juste de faire des paquets de "records"
    par contre il nest pas la pour charger les données d'un fichier extrerne il faut un autre mécanisme

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Convertion char vers int
    Par barthelv dans le forum C
    Réponses: 8
    Dernier message: 08/10/2011, 21h45
  2. Importation CSV vers base de données
    Par Brice Yao dans le forum Bases de données
    Réponses: 1
    Dernier message: 29/06/2005, 13h42
  3. [Conseil] Import de fichier CSV vers MySQL
    Par ShinJava dans le forum JDBC
    Réponses: 6
    Dernier message: 15/03/2005, 19h14
  4. Importation de fichier CSV vers une base Interbase
    Par PrinceMaster77 dans le forum ASP
    Réponses: 3
    Dernier message: 15/03/2005, 15h18

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