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 :

psycopg2 : requete Insert ne fonctionne pas


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Inscrit en
    Octobre 2010
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 30
    Points : 26
    Points
    26
    Par défaut psycopg2 : requete Insert ne fonctionne pas
    Bonjour,

    Je suis sur un python 3.7 et un postgresql 9.6.

    J'ai créé sous postgresql une table client(Nom_client,Age_client)

    J'ai utilisé Tkinter pour faire une petite grille de saisie avec 2 Entry et un bouton pour lancer la requête sql. Voici un extrait du code :

    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
     
     
    def Enregistrer(P_Nom,P_Age):
        host = "localhost"
        user = "postgres"
        dbname = "Evaluation"
        password = "admin"
     
        # Constrcution de la chaine de connection
        conn_string = "host={0} user={1} dbname={2} password={3} ".format(host, user, dbname, password)
        conn = psycopg2.connect(conn_string) 
        cursor = conn.cursor()
     
        cursor.execute("INSERT INTO client (nom_client,age_client) VALUES(%s,%s)", ([P_Nom],[P_Age]))
        conn.commit()

    .............

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #Bouton Enregistrer
    BoutonEnregistrer = Button(master, text ='Enregistrer', command = lambda : Enregistrer(Nom.get(),Age.get()))


    Tout fonctionne bien ...sauf que lorsque je regarde le contenu de mes champs dans postgresql, je vois apparaître {Dupont} dans le champs Nom et {42} dans le champs Age... donc avec des crochets en trop.

    En fait, j'ai un soucis dans la clause Insert :
    cursor.execute("INSERT INTO client (nom_client,age_client) VALUES(%s,%s)", ([P_Nom],[P_Age]))

    avec la dernière partie pour récupérer les valeurs passées en paramètres dans la fonction Enregistrer.

    Si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cursor.execute("INSERT INTO client (nom_client,age_client) VALUES(%s,%s)", ('P_Nom','P_Age'))
    ou bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cursor.execute("INSERT INTO client (nom_client,age_client) VALUES(%s,%s)", (P_Nom,P_Age))
    J'ai toujours des erreurs.

    La seule solution qui fonctionne est la première mais elle me met des {} dans le contenu du champs.

    Je début en Python... je tourne depuis 3 heures sur ce problème en consultant les forum... et là je commence à être un peu sec.

    Toute aide sera la bienvenue. Merci à vous !!

    JM

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Déjà commence par afficher la valeur et le type de P_Nom et P_Age quand tu entres dans ta fonction.

    Ensuite, en plus de Python, faudrait aussi te mettre à sql. Parce que la bonne syntaxe d'un insert sur un champ X de type "char[n]" c'est insert into "table" ("champX") values('chaine'). Donc depuis Python ça deviendrait cursor.execute("INSERT INTO \"client\" (\"nom_client\", \"age_client\") VALUES('%s','%s')", (P_Nom, P_Age)) (sous réserve que P_Nom et P_Age soient des strings).

    Bon, ok cette syntaxe est un peu lourde. Tu peux alors shunter les guillemets doubles aux noms des tables et colonnes mais à la seule condition que tes noms de tables et de colonnes n'aient pas de majuscules (et donc insert into table (champX) values('chaine') ne fonctionnera pas.

    Ou alors tu peux créer une fonction qui rajoute les guillemets doubles (ce que j'ai fait)
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import re
    setIFS=lambda elem: "{0}{1}{0}".format(
    	"\"",
    	re.sub(
    		r"\.",
    		r"{0}.{0}".format("\""),
    		elem,
    	),
    )
    Elle est un peu complexe car quand on utilise les schémas sous Postgres, une table "tableT" d'un schéma "schemaS" se nomme alors "schemaS"."tableT". Donc je l'ai faite pour qu'un appel style setIFS("schemaS.tableT") donne au final une chaine "schemaS"."tableT".

    Il ne reste que la question des quotes simples qui doivent encadrer la chaine à insérer car il y a là une petite subtilité: si la chaine à insérer contient déjà des quotes simples (ex "aujourd'hui"), il faut alors les doubler pour Postgres (ex insert into table values('aujourd''hui'). Fort heureusement, psycopg2 te propose une fonction qui le fait pour toi: psycopg2.extensions.QuotedString("chaine").getquoted() (il faut bien sûr importer "psycopg2.extensions"). Fonction que tu peux encapsuler dans une lambda quoted_string=lambda txt: psycopg2.extensions.QuotedString(txt).getquoted() pour simplifier.

    Donc au final, ta requête sera écrite de cette façon:
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    cursor.execute(
    	"INSERT INTO %s (%s, %s) VALUES (%s, %s)", (
    		setIFS("client"),
    		setIFS("nom_client"),
    		setIFS("age_client"),
    		quoted_string(P_Nom),
    		quoted_string(P_Age),
    	)
    )

    Ou alors (car un dev Python aime bien tout ce qui est "itération" ce qui factorise les traitements et favorise les évolutions)
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    cursor.execute(
    	"INSERT INTO %s (%s) VALUES (%s)", (
    		setIFS("client"),
    		", ".join(setIFS(x) for x in ("nom_client", "age_client")),
    		", ".join(quoted_string(x) for x in (P_Nom, P_Age)),
    	)
    )

    Accessoirement ta connexion psycopg2 peut être optimisée si tu utilises un dico. Exemple
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    param={
    	"host" : "localhost",
    	"port" : 5432,
    	"user" : "postgres",
    	"password" : "admin",
    	"dbname" : "Evaluation",
    }
    conn = psycopg2.connect(**param)

    Et n'oublie pas
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre du Club
    Inscrit en
    Novembre 2009
    Messages
    96
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 96
    Points : 51
    Points
    51
    Par défaut
    Bonjour,

    En principe il ne faut pas mettre des crochets dans la clause insert :
    cursor.execute("INSERT INTO client (nom_client,age_client) VALUES(%s,%s)", ([P_Nom],[P_Age]))

    Quel message d'erreur aurez-vous avec la synatxe suivante : .???
    cursor.execute("INSERT INTO client (nom_client,age_client) VALUES(%s,%s)", (P_Nom, P_Age) )

  4. #4
    Nouveau membre du Club
    Inscrit en
    Octobre 2010
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 30
    Points : 26
    Points
    26
    Par défaut
    Citation Envoyé par bazoga Voir le message
    Bonjour,

    En principe il ne faut pas mettre des crochets dans la clause insert :
    cursor.execute("INSERT INTO client (nom_client,age_client) VALUES(%s,%s)", ([P_Nom],[P_Age]))

    Quel message d'erreur aurez-vous avec la synatxe suivante : .???
    cursor.execute("INSERT INTO client (nom_client,age_client) VALUES(%s,%s)", (P_Nom, P_Age) )
    ... et bien, en fait, cela fonctionne sans crochet et sans les quotes ... j'ai pourtant essayé cette solution un "certain" nombre de fois et ça planté...... Gros Soupirs

    En tout cas, merci pour votre intervention.....

    Bonne fin de journée

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

Discussions similaires

  1. Pb avec un tableau, insert ne fonctionne pas mais requete OK.
    Par franco14 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 16/04/2010, 11h31
  2. les requetes INSERT ne fonctionnent pas
    Par Seb33300 dans le forum WebDev
    Réponses: 6
    Dernier message: 30/11/2007, 10h06
  3. Requete qui ne fonctionne pas chez l'hebergeur
    Par Derik dans le forum Requêtes
    Réponses: 4
    Dernier message: 05/06/2006, 02h35
  4. Réponses: 2
    Dernier message: 12/05/2006, 23h01
  5. Requete UPDATE ne fonctionnant pas
    Par Yanmeunier dans le forum Access
    Réponses: 3
    Dernier message: 12/04/2006, 17h19

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