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 :

Erreur sur insertion d'une date dans MySQL


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 42
    Points : 16
    Points
    16
    Par défaut Erreur sur insertion d'une date dans MySQL
    Bonjour,

    C'est une question qui me semble être plus liée à Python qu'à MySQL car je peux faire l'insertion sans problème avec phpmyadmin.

    Je m'explique :
    Mon programme fonctionne très bien si j'enlève l'insertion du champ date.
    Si je l'ajoute (et j'en ai vraiment besoin) j'ai l'erreur suivante :

    Traceback (most recent call last):
    File "C:\Users\pidlas\Documents\rudder_find.py", line 58, in <module>
    extract(info)
    File "C:\Users\pidlas\Documents\rudder_find.py", line 46, in extract
    cursor.execute(query, (serveur, etat, directive, regle, date,))
    File "C:\Python27\lib\site-packages\MySQLdb\cursors.py", line 183, in execute
    query = query % db.literal(args)
    TypeError: not all arguments converted during string formatting
    Dans ma base MySQL, le champs date est déclaré en datetime. Donc le format attendu est : AAAA-MM-JJ HH:MM:SS
    Ma variable python date est exactement formaté comme cela.
    Pour être encore plus sûr j'ai utilisé le module datetime pour réaliser une conversion chaîne vers date.

    Rien n'y fait. Avec ou sans conversion j'ai le même message d'erreur.

    Voici mon code Python :

    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
     
    # -*- coding: utf-8 -*-
    # modules nécessaires
    from os import chdir
    import MySQLdb as mdb
    import sys
    import datetime
     
    # variables pour la BDD
    serveur = ''
    etat = ''
    regle = ''
    directive = ''
     
    # répertoire où se trouve les logs
    chdir("c:/Users/pidlas/Documents/rudder/")
     
    def extract(log):
        for ligne in log:
            debut_date = ligne.find('[')
            fin_date = ligne.find(']')
            date = ligne[debut_date+1:fin_date-5]
            date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
            sep_N = ligne.find('N:')
            serveur = ligne[ligne.find('[',sep_N)+1:ligne.find(']',sep_N)]
            sep_S = ligne.find('S:')
            etat = ligne[ligne.find('[',sep_S)+1:ligne.find(']',sep_S)]
            sep_R = ligne.find('R:')
            regle = ligne[ligne.find('[',sep_R)+1:ligne.find(']',sep_R)]
            sep_D = ligne.find('D:')
            directive = ligne[ligne.find('[',sep_D)+1:ligne.find(']',sep_D)]
     
            try:
                db = mdb.connect('localhost', 'root', '', 'rudder');
                cursor = db.cursor()
                query = """INSERT IGNORE INTO serveur (nom_serveur) VALUES (%s)"""
                cursor.execute(query, (serveur,))
                query = """INSERT IGNORE INTO etat (nom_etat) VALUES (%s)"""
                cursor.execute(query, (etat,))
                query = """INSERT IGNORE INTO directive (nom_directive) VALUES (%s)"""
                cursor.execute(query, (directive,))
                query = """INSERT IGNORE INTO regle (nom_regle) VALUES (%s)"""
                cursor.execute(query, (regle,))
                query = """INSERT INTO serveur_etat_directive_regle (serveur, id_etat, id_directive, id_regle, date)
                        SELECT id_serveur, id_etat, id_directive, id_regle FROM serveur, etat, directive, regle
                        WHERE nom_serveur = %s AND nom_etat = %s AND nom_directive = %s AND nom_regle = %s"""
                cursor.execute(query, (serveur, etat, directive, regle, date,))
            except mdb.Error, e:
                print "Error %d: %s" % (e.args[0],e.args[1])
                sys.exit(1)
            db.commit()
     
        info.close()
        db.close()
        return logfile
     
    if __name__ == "__main__":
        with open('non-compliant-reports.log','r') as info:
            extract(info)
    Je débute dans tout cela et j'apprécierai votre aide et vos conseils.

    Cordialement.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 781
    Points
    36 781
    Par défaut
    Salut,
    En regardant en diagonale, le message d'erreur dit: "not all arguments converted during string formatting".
    Le nombre de %s dans le statement SQL:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    """INSERT INTO serveur_etat_directive_regle (serveur, id_etat, id_directive, id_regle, date)
                        SELECT id_serveur, id_etat, id_directive, id_regle FROM serveur, etat, directive, regle
                        WHERE nom_serveur = %s AND nom_etat = %s AND nom_directive = %s AND nom_regle = %s"""
    est 4.
    Le nombre d'items dans la liste "(serveur, etat, directive, regle, date,)" est 5.
    C'est cohérent, non?

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

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 42
    Points : 16
    Points
    16
    Par défaut
    Merci Wiztricks.
    C'est en effet très pertinent.
    Comme puis-je faire alors ?
    L'insertion a besoin de ce champ date, et il est vrai que ma sélection ne va pas chercher cette donnée dans les tables car elle provient de mon fichier log.
    Du coup c'est une question liée à SQL.
    Je vais donc la poser dans le bon forum.
    Dans l'attente si tu as une idée, je suis preneur.

    Cordialement.

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 781
    Points
    36 781
    Par défaut
    ben, il faudrait ajouter un placeholder pour la "date" dans le 'SELECT' qui attrape le paramètre. Un truc du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    sql = """INSERT INTO serveur_etat_directive_regle (
                      serveur, id_etat, id_directive, id_regle, date)
                SELECT id_serveur, id_etat, id_directive, id_regle, %s 
                        FROM serveur, etat, directive, regle
                        WHERE nom_serveur = %s AND 
                              nom_etat = %s AND nom_directive = %s 
                              AND nom_regle = %s"""
    Puis, on passe les paramètres dans l'ordre attendu:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
         cursor.execute(sql, (date, serveur, etat, directive, regle))
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 42
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    En mettant en place ta solution, je n'ai plus de message d'erreur ET aucun enregistrement n'est inséré dans la base ?!
    Pourtant le db_commit() est bien présent et la base se remplit bien si j'enlève le champs date.
    J'ai vérifié les noms de colonnes.
    Une autre idée ?
    Je continue de chercher mais je suis un peu à court.

    Cordialement.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 42
    Points : 16
    Points
    16
    Par défaut
    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    query = """INSERT INTO serveur_etat_directive_regle (id_serveur, id_etat, id_directive, id_regle, date)
    SELECT id_serveur, id_etat, id_directive, id_regle, %s FROM serveur, etat, directive, regle
    WHERE nom_serveur = %s AND nom_etat = %s AND nom_directive = %s AND nom_regle = %s"""
    cursor.execute(query, (serveur, etat, directive, regle, date,))

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 781
    Points
    36 781
    Par défaut
    Salut,
    C'est quoi la différence? La position du champ date dans le tuple?
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 42
    Points : 16
    Points
    16
    Par défaut
    Salut,

    Le champ date est en cinquième position dans INSERT , dans le SELECT aussi et dans l'ordre des arguments de l''execute' aussi. C'est cohérent, non ?

    Qu'est-ce qui est si évident que je loupe ?

    En attendant, j'ai réussi à faire ce que je voulais en changeant la structure de ma base et en ajoutant le champ date dans la table serveur.

    J'aimerai quand même réussir cet INSERT SELECT avec le champ date venant d'une variable. Je suis sûr que cela me sera utile.

    Cdlt.

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 781
    Points
    36 781
    Par défaut
    Salut,
    Comment faire l'association entre les "%s" du query et la séquence d'objets du tuple passé en paramètres? C'est pas "magique".
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 42
    Points : 16
    Points
    16
    Par défaut
    Salut,

    Dans la clause WHERE ?

    <code>
    """....
    WHERE nom_serveur = %s AND nom_etat = %s AND nom_directive = %s AND nom_regle = %s AND date = %s """
    </code>

    Ceci est-il la réponse ?

    Cdlt.

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 781
    Points
    36 781
    Par défaut
    C'est un peu plus cohérent.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 42
    Points : 16
    Points
    16
    Par défaut
    Salut,

    Avec cette requête,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     query = """INSERT INTO serveur_etat_directive_regle (id_serveur, id_etat, id_directive, id_regle, log_date)
    SELECT id_serveur, id_etat, id_directive, id_regle, %s FROM serveur, etat, directive, regle
    WHERE nom_serveur = %s AND nom_etat = %s AND nom_directive = %s AND nom_regle = %s  AND log_date = %s"""
    cursor.execute(query, (serveur, etat, directive, regle, date))
    J'ai l'erreur suivante :

    Traceback (most recent call last):
    File "C:\Users\pidlas\Documents\rudder_find.py", line 61, in <module>
    extract(info)
    File "C:\Users\pidlas\Documents\rudder_find.py", line 48, in extract
    cursor.execute(query, (serveur, etat, directive, regle, date))
    File "C:\Python27\lib\site-packages\MySQLdb\cursors.py", line 183, in execute
    query = query % db.literal(args)
    TypeError: not enough arguments for format string
    Il y a pourtant autant d'arguments que de colonnes dans le INSERT et le SELECT.

    Merci par avance de votre guidance.

    Cdlt.

  13. #13
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 180
    Points : 321
    Points
    321
    Par défaut
    Bonjour,
    Selon la doc de DP API, avec cette forme de passage de paramètres, tu dois
    en fournir autant qu'il y a de placeholders dans le texte de ta requête. Et-ce, même si cela implique de passer plusieurs fois le même.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     query = """INSERT INTO serveur_etat_directive_regle (id_serveur, id_etat, id_directive, id_regle, log_date)
    SELECT id_serveur, id_etat, id_directive, id_regle, %s FROM serveur, etat, directive, regle
    WHERE nom_serveur = %s AND nom_etat = %s AND nom_directive = %s AND nom_regle = %s  AND log_date = %s"""
    cursor.execute(query, (serveur, etat, directive, regle, date,serveur, etat, directive, regle, date))
    En outre, ils doivent être dans le même ordre.

    Sinon, regarde dans la doc de ton module mysql s'il n'existe pas une possibilité
    d'utiliser des placeholders nommés et de passer alors un dict. Ce serait plus élégant et surtout plus lisible.

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 42
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    Je n'ai pas encore essayé la commande cursor.execute() que tu me proposes mais je te réponds déjà sur le dictionnaire. Pour utiliser un dictionnaire, j'ai besoin d'avoir une clef unique. Or, les données que je gère ne me le permette pas. Les clefs uniques sont directement auto-incrémentés par la BDD.

    Je teste et je te donne le résultat.

    Merci encore pour cette nouvelle piste.

  15. #15
    Membre éprouvé Avatar de Marc3001
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2008
    Messages
    829
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2008
    Messages : 829
    Points : 1 275
    Points
    1 275
    Par défaut
    A noter que % est à remplacer par str.format() bien plus propre et simple à utiliser. source

    Tu te mélanges un peu les pinceaux entre le formatage (remplacement des placeholder %s par des variables) de ta requête et son exécution par la base.

    Dans ton dernier post, c'est Python qui te gueule dessus en précisant que tu lui donnes 5 variables mais 6 placeholder dans la chaîne..... Il ne sait donc pas quoi mettre dans le dernier.....
    Le logiciel, c'est comme le sexe, c'est meilleur quand c'est libre.

    Linus Torvalds

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 42
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    En utilisant la syntaxe de chticricri, l'erreur suivante apparaît :

    Traceback (most recent call last):
    File "C:\Users\pidlas\Documents\rudder_find.py", line 61, in <module>
    extract(info)
    File "C:\Users\pidlas\Documents\rudder_find.py", line 48, in extract
    cursor.execute(query, (serveur, etat, directive, regle, date, serveur, etat, directive, regle, date))
    File "C:\Python27\lib\site-packages\MySQLdb\cursors.py", line 183, in execute
    query = query % db.literal(args)
    TypeError: not all arguments converted during string formatting
    J'utilise le module MySQLdb de la version 2.7 de Python. C'est peut être important à connaître.

    Cordialement.

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 781
    Points
    36 781
    Par défaut
    Salut
    Débrouillez vous comme vous voulez mais tant qu'il n'y aura pas autant d'éléments dans le tuple que de %s dans le statement SQL, çà ne fonctionnera pas.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  18. #18
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 180
    Points : 321
    Points
    321
    Par défaut
    Désolé, je n'avais pas fait très attention aux placeholders

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     query = """INSERT INTO serveur_etat_directive_regle (id_serveur, id_etat, id_directive, id_regle, log_date)
    SELECT id_serveur, id_etat, id_directive, id_regle, %s FROM serveur, etat, directive, regle
    WHERE nom_serveur = %s AND nom_etat = %s AND nom_directive = %s AND nom_regle = %s  AND log_date = %s"""
    cursor.execute(query, (date, serveur, etat, directive, regle, date))
    Si j'ai bien saisi, les premier et dernier paramètres à passer sont la date.

    Décidément, je travaille trop

  19. #19
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 781
    Points
    36 781
    Par défaut
    Salut,
    Votre mouture est semblable à celle que j'avais proposée au PO avant qu'il modifie son schéma (ajout de date dans la table serveur).
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  20. #20
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 180
    Points : 321
    Points
    321
    Par défaut Juste un détail
    Quel module utilise-tu pour te connecter à mysql ?

    Selon la réponse, il est possible ou nom d'effectuer quelque chose du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     query = """INSERT INTO serveur_etat_directive_regle (id_serveur, id_etat, id_directive, id_regle, log_date)
    SELECT id_serveur, id_etat, id_directive, id_regle, :log_date FROM serveur, etat, directive, regle
    WHERE nom_serveur = nom_serveur AND nom_etat = :nom_etat AND nom_directive = :nom_directive AND nom_regle =:nom_regle  AND log_date = :log_date"""
    cursor.execute(query, dict(log_date=date,nom_serveur=serveur,nom_etat=etat,nom_regle=regle))
    La différence est qu'ici on ne passe qu'une seule fois chaque paramètre. En outre, les conversions de type sont réalisées en toute transparence.
    Mais il faut que ton module supporte ce type d'appel

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. insertion d'une date dans une table mysql
    Par hunter99 dans le forum SGBD
    Réponses: 6
    Dernier message: 14/12/2007, 23h17
  2. insertion d'une date dans une table
    Par yousfi.z dans le forum JDBC
    Réponses: 3
    Dernier message: 07/08/2006, 15h32
  3. Insertion d'une date dans une table avec vba
    Par skeut dans le forum Access
    Réponses: 2
    Dernier message: 21/02/2006, 08h54
  4. [Format Date] erreur sur insertion d'une date
    Par philobedo dans le forum SQL
    Réponses: 4
    Dernier message: 14/06/2005, 10h41
  5. insertion d'une date dans visual foxpro
    Par yvescollet dans le forum Bases de données
    Réponses: 4
    Dernier message: 10/05/2005, 15h39

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