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 :

Caractères spéciaux dans table SQL


Sujet :

Python

  1. #1
    Membre expérimenté Avatar de stigma
    Homme Profil pro
    Créateur jeux vidéo
    Inscrit en
    Octobre 2003
    Messages
    1 111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Créateur jeux vidéo
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 111
    Points : 1 612
    Points
    1 612
    Par défaut Caractères spéciaux dans table SQL
    Bonjour,
    Je débute en Python.
    Je récupère des enregistrements avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    db=adodbapi.connect("\
        Provider=SQLOLEDB.1;...... etc
     
    c = db.cursor()
    c.execute("select * from dbo.Aciers")
    ça marche très bien sauf que j'ai une erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UnicodeEncodeError: 'ascii' codec can't encode character u'\xb5' in position 10: ordinal not in range(128)
    quand le code rencontre le caractère µ présent dans certains enregistrements.(épaisseur d'un acier en micron)
    J'ai bien mis la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #-*- coding: windows-1252 -*-
    en entête mais ça ne suffit pas pour afficher correctement un enregistrement.
    Merci d'avance

  2. #2
    Membre confirmé

    Profil pro
    Développeur Java
    Inscrit en
    Mars 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 87
    Points : 537
    Points
    537
    Par défaut
    Bonjour stigma,
    tu touches à la partie la plus drôle/torturée de python à savoir la gestion de l'encoding. Histoire de ne pas te causer des maux de têtes jusqu'à demain matin, une première distinction :
    La définition d'en-tête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #-*- coding: windows-1252 -*-
    est une très bonne idée !! mais elle ne sert qu'à une seule chose, c'est précisé l'encodage de ton fichier source (le .py). Il est donc utile si tu veux commencé à rajouter des accents dans tes commentaires ou tes strings.

    Connais-tu l'encodage de ta base de données, ou plutôt des données dans ta base de données ? Es-tu en python 3.x ou 2.x ?

    Pour te faire profiter de mes heures de prises de tête, pourrais-tu poster la suite de ton code jusqu'au point d'erreur ?

    Cordialement,

    Olivier.

  3. #3
    Membre expérimenté Avatar de stigma
    Homme Profil pro
    Créateur jeux vidéo
    Inscrit en
    Octobre 2003
    Messages
    1 111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Créateur jeux vidéo
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 111
    Points : 1 612
    Points
    1 612
    Par défaut
    Bonjour Olivier,
    voici mon 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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #-*- coding: windows-1252 -*-
     
    import adodbapi #Bases SQL
    from os import getcwd #répertoire courant
     
    # paramètres fichier ini
    rep_cour=getcwd()
     
    F=open("Feuillard.ini","r")
    source=F.readline()
    base=F.readline()
    login=F.readline()
    password=F.readline()
    F.close()
     
    db=adodbapi.connect("\
        Provider=SQLOLEDB.1;\
        Password=" + password + ";\
        Persist Security Info=True;\
        User ID=" + login +";\
        Initial Catalog=" + base +";\
        Data Source=" + source)
     
    c = db.cursor()
    c.execute("select * from dbo.Aciers")
     
    for ligne in c.fetchall():
        print ligne # ça bloque au moment où le µ est présent
     
    c.close()
    db.close
    je suis en Python 2.7.1 et la base est sur SQL Server 2005

  4. #4
    Membre confirmé

    Profil pro
    Développeur Java
    Inscrit en
    Mars 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 87
    Points : 537
    Points
    537
    Par défaut
    Bonjour stigma,
    Pour faire simple il faut découvrir comment ta string line est gérée (en string "string" ou en string "unicode") pour gérer l'encoding correctement.
    Il me semble vu le message d'erreur que ta string line est gérée en unicode, car l'erreur vient plus de la manière dont print gère la variable line que comment line est créé.

    Je ne suis pas un expert, mais tu possède trois armes pour te défendre dans ce genre de situation :
    • encoder en unicode la string - connaissant l'encodage de base : unicode(value, encoding)
    • décoder une string unicode dans un encoding précis : ma_string.encode('iso-8859-1')
    • L'interpréteur pour tester à la volée

    Essaye de voir en remplaçant line par "line.encode("iso-8859-1")" (autrement dit l'encodage latin1) ou par "unicode(line, "iso-8859-1") (ou "utf-8").

    Désolé de pas avoir toutes les clés pour te répondre, pour avoir le manuel global tu peux te reporter à la page unicode de python 2.7 (la gestion de l'unicode étant totalement différente en python 3.x) : http://docs.python.org/howto/unicode.html

    Olivier.

  5. #5
    Membre expérimenté Avatar de stigma
    Homme Profil pro
    Créateur jeux vidéo
    Inscrit en
    Octobre 2003
    Messages
    1 111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Créateur jeux vidéo
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 111
    Points : 1 612
    Points
    1 612
    Par défaut
    Après quelques heures passées sur le net, j'ai fini par dénicher une solution

    Créer le fichier : C:\Python27\Lib\site-packages\ sitecustomize.py

    import sys
    sys.setdefaultencoding('iso-8859-1')

    Entête du fichier de travail, ajouter ces 4 lignes.

    import codecs
    import sys
    streamWriter = codecs.lookup('utf-8')[-1]
    sys.stdout = streamWriter(sys.stdout)
    Il ne me reste plus qu'à trouver quelque chose qui remplace l'affichage
    par
    par exemple. Si vous avez une piste, je prends

  6. #6
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Ce n'est en général ni utile ni souhaitable de modifier l'encodage par défaut de l'interpréteur Python.

    Ton problème est uniquement un problème d'affichage.

    Il y a 2 aspects différents:

    1- Conversion d'encodage

    si l'encodage de la chaine à afficher n'est pas le même que l'encodage de la console d'affichage, il faut faire une conversion d'encodage.

    Par exemple, si la chaine est en 'cp1252' et la console d'affichage est en 'utf-8', il faudra faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print chaine.decode('cp1252').encode('utf-8')
    A noter que l'encodage de la console d'affichage s'obtient par: sys.stdout.encoding (sauf dans certains outils de développement qui retournent None), ce qui donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import sys
    print chaine.decode('cp1252').encode(sys.stdout.encoding)

    2- Affichage d'une liste

    Même si le problème précédent a été résolu, l'affichage d'une chaine située à l'intérieur d'une liste peut être incorrect:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    x = "76µ"  # supposé dans le même encodage que la console
     
    print x
    76µ
     
    print [x]
    ['76\xb5']
    Pour afficher correctement les caractères non ascii situés dans une liste, on transforme la liste en chaine de caractères.

    Par exemple avec la fonction suivante fabriquée "sur les genoux":

    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
    def printx(*args):
        def _printx(x):
            if isinstance(x,list):
                ch = "["
                if len(x) != 0:
                    for elem in x:
                        ch += _printx(elem) + ", "
                    ch = ch[:-2]
                ch += "]"
            else:
                ch = "%s" % x
            return ch
        ch = ""
        if len(args)!=0:
            for x in args:
                ch += _printx(x) + ", "
            ch = ch[:-2]
        print ch
    application:

    Et comme la fonction est récursive, elle affichera correctement, même si la chaine x se trouve dans une 'sous-sous-sous-liste':

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    x = "abcéèçàù"  # supposé dans le même encodage que la console
     
    printx([x], 5, [[1,2],[[[[x]]]],8])
    [abcéèçàù], 5, [[1, 2], [[[[abcéèçàù]]]], 8]
    Tyrtamos
    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

Discussions similaires

  1. Caractères spéciaux dans le nom des tables
    Par xx_FiFty_xx dans le forum Requêtes
    Réponses: 4
    Dernier message: 25/06/2008, 12h30
  2. Caractère spéciaux dans les requêtes SQL
    Par Thundara dans le forum SGBD
    Réponses: 3
    Dernier message: 17/04/2008, 11h15
  3. caractères spéciaux dans Access et requête SQL
    Par csszzen dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 14/03/2007, 16h20
  4. Réponses: 3
    Dernier message: 26/11/2006, 21h05
  5. [SQL] Problème d'affichage de caractère spéciaux dans une variable chaîne
    Par Kryptonaute dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 18/08/2006, 08h40

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