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

PyQt Python Discussion :

De QTextEdit à une base PostgreSQL : problème d'encodage [QtSql]


Sujet :

PyQt Python

  1. #1
    Candidat au Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mars 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Mars 2011
    Messages : 3
    Points : 3
    Points
    3
    Par défaut De QTextEdit à une base PostgreSQL : problème d'encodage
    Bonjour à tous,

    Je produis un plugin pour QGIS, un logiciel de système d'information géographique basé sur Qt, dont les plugins sont écrits en Python.
    Depuis que QGIS 1.9 est doté de sa nouvelle API (ce mois-ci), les méthodes ".toString()" ne fonctionnent plus.
    J'utilise donc maintenant la méthode ".toPlainText()" pour récupérer les textes de deux QTextEdit (contrôles de texte sur plusieurs lignes), et les intégrer dans 2 champs d'une table PostGreSQL.

    Extrait de mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def sauverInfos(self):
            query_save = QtSql.QSqlQuery(self.db)
            query = """insert into bdtravaux.sortie (jours_chan, sortcom) values ('{zr_jours_chantier}', '{zr_sort_com}')""".format (zr_jours_chantier=self.ui.jours_chan.toPlainText().encode('UTF-8'),\
            zr_sort_com=self.ui.comm.toPlainText().encode('UTF-8'))
    Lorsque je lance cette fonction, les textes saisi par l'utilisateur sont bien intégrés en base. Mais, dans les champs "zr_jours_chantiers" et "zr_sort_com", les caractères accentués sont remplacés par d'autres (exemple : é => é, à => Ã).
    J'imagine que cela doit être dû au fait que toPlainText() extrait de mon objet QTextEdit une chaîne de caractère codée en ASCII, que je transforme ensuite en UTF8 avec ".encode('UTF-8')"...
    Entre temps, les caractères spéciaux sont donc perdus.
    Partagez-vous cette analyse?
    Comment transformer mon QTextEdit en chaîne de caractères sans perdre les caractères "spéciaux"?
    Enfin, je me demandais pourquoi je n'avais pas ces problèmes d'encodage quand j'utilisais les méthode ".toString()"...
    D'avance merci pour toute information sur ce sujet.
    Vince

    PS : je précise que ma base postgresql est en UTF8, et que j'ai ajouté
    # -*- coding: utf-8 -*-
    au début de mon module Python.

  2. #2
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 476
    Points : 831
    Points
    831
    Par défaut
    bonjour,
    je n'utilise pas qt mais lorsque j'exporte ou importe des données dans postgres je fais toujours préceder ma commande sql par la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    set client_encoding to 'win1252' ;
    (dans mon exemple win1252 correspond à l'encodage de windows, il suffit de changer l'encodage par ascii si le client est en ascii)

  3. #3
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je travaille surtout avec Python 2.7, PyQt4 et sqlite3. Je suppose que tu travailles aussi en Python 2.x.

    Il faudrait voir comment est configuré PostGreSQL: quel encodage doit-il recevoir? L'erreur signalée ressemble à un encodage en "utf-8" qui n'est pas adapté. Par exemple, avec sqlite3, on peut le configurer pour lui faire accepter soit de l'utf-8, soit de l'unicode: j'ai choisi l'unicode.

    De toute façon, avec Python 2.x et PyQt4, le plus facile est de travailler en unicode interne. Cela nécessite que tout ce qui rentre est encodé unicode le plus tôt possible (.decode()), et tout ce qui sort est encodé le plus tard possible (.encode()).

    De plus travailler en interne en encodage "utf-8" sous Python 2.x est une source de bugs difficiles à détecter: par exemple, si x="é" est encodée en "utf-8", len(x) sera égal à 2 alors qu'il n'y a qu'un seul caractère. Cette erreur n'existe pas en unicode, même si le "é" est aussi codée en 2 octets dans la mémoire de l'ordinateur.

    Attention aussi à l'affichage: quand on affiche une chaine de caractères, elle doit être encodée correctement par rapport au périphérique d'affichage. Par exemple sous Windows, une chaine correcte comme "é" encodée en "utf-8", sera affichée comme "é" dans PyScripter, qui attend un encodage Windows ("cp1252") ou unicode.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  4. #4
    Candidat au Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mars 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Mars 2011
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Bonjour à tous les deux et merci beaucoup pour vos réponses,

    Tout d'abord, je travaille effectivement sur Python 2.X. (c'est vrai que j'aurais pu le préciser..)
    Les pistes que vous me suggérez me laissent à penser que le problème ne vient peut-être pas de mon code, mais de la configuration du serveur / de la base de données / du client d'affichage.

    En effet, lorsque j'inclus un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "print self.ui.comm.toPlainText().encode('UTF-8')
    à la fin de ma fonction, les caractères accentués s'affichent correctement dans mon terminal.

    Comme le proposait tyrtamos, j'ai donc cherché du côté de l'affichage sous PGAdminIII. Je n'ai toutefois pas trouvé d'information comme quoi il ne pouvait pas afficher de l'UTF8. De plus, psql et QGIS affichent les mêmes erreurs.

    En relisant vos deux posts, j'ai eu l'idée d'aller vérifier dans le postgresql.conf les paramètres d'encodage. Et là, j'ai trouvé...

    "client-encoding =sql_ascii"

    Ce pourrait-il que le problème vienne de là? (que ce soit du côté de l'intégration des données, ou de l'affichage).

    Sinon,...
    Mon code envoie bien de l'UTF8, la base est en UTF8 (vérification avec psql -l)... psql et PGadminIII devraient lire de l'UTF8...

    Enfin, merci tyrtamos pour le conseil de passer par de l'unicode interne. Mon formateur m'ayant conseillé l'UTF8, j'ai démarré mon plugin Python avec cet encodage. Je vais essayer de faire afficher correctement mes caractères spéciaux en UTF8, puis je verrai comment je peux changer toute la chaîne (j'imagine que si tout marche en UTF8, ça marchera aussi en unicode).

    En tout cas, je tenterai ce soir de passer la valeur de "client_encoding" à utf8 (si je le fais tout de suite, je vais avoir une horde d'utilisateurs féroces sur le dos au redémarrage du serveur ).
    Je vous tiens au courant en tout cas.
    Encore merci.
    Vincent

  5. #5
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par vince5962 Voir le message
    Mon formateur m'ayant conseillé l'UTF8
    Pour être complet, c'est bien d'encoder le SCRIPT Python en utf-8 avec une ligne comme: "# -*- coding: utf-8 -*-"! Cela ne veut pas dire que Python travaillera en utf-8, mais que les chaines litérales (=codées en 'dur') figurant dans le script seront considérées comme encodée en utf-8. Encore faut-il que ce soit vrai, c'est à dire que l'éditeur de texte ait édité et enregistré le script en utf-8. Il suffit alors de faire précéder le 1er guillemet de chaque chaine litérale par 'u', et Python transformera ces chaines de utf-8 en unicode tout seul.

    [On est toujours ici dans Python 2]
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  6. #6
    Candidat au Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Mars 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Mars 2011
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Ah oui.
    Quand je lis ton dernier post, je me rends-compte que c'est texto ce que me disait mon formateur, mais je ne l'avais pas bien intégré à l'époque.

    Et effectivement, la réponse était là :
    Cela ne veut pas dire que Python travaillera en utf-8, mais que les chaines litérales (=codées en 'dur') figurant dans le script seront considérées comme encodée en utf-8. Encore faut-il que ce soit vrai, c'est à dire que l'éditeur de texte ait édité et enregistré le script en utf-8. Il suffit alors de faire précéder le 1er guillemet de chaque chaine litérale par 'u', et Python transformera ces chaines de utf-8 en unicode tout seul.
    Ma requête n'était visiblement pas encodée en Unicode (sûrement en ascii), car en rajoutant u'ma requête ', tout est réglé. Je retrouve avec joie mes caractères accentués dans ma base.

    La requête donne donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    query = u'INSERT INTO bdtravaux.sortie (jours_chan, sortcom) VALUES (\'{zr_jours_chantier}\', \'{zr_sort_com}\')'.format(\
            zr_jours_chantier=self.ui.jours_chan.toPlainText(),\
            zr_sort_com=self.ui.comm.toPlainText())
    Merci beaucoup!
    Bonne journée.
    Vince

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 05/03/2013, 09h46
  2. [PostgreSQL] problème de requête sur une base postgresql
    Par DiverSIG dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 01/12/2009, 08h18
  3. problème de connexion à une base postgresql
    Par QAYS dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 16/10/2008, 11h26
  4. [amc designer] création d'une base postgresql
    Par david42 dans le forum PostgreSQL
    Réponses: 9
    Dernier message: 12/03/2004, 11h08
  5. Localisation d'une base Postgresql sur mdk 9.1
    Par Gregco dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 10/06/2003, 18h46

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