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 :

Requète SQL et encodage


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    237
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 237
    Par défaut Requète SQL et encodage
    Bonjour à tous,

    Je sollicite votre aide pour m'aider à résoudre un problème de caractères spéciaux lors de l'exécution d'un requête SQL dans une base ORACLE.

    La base est encodée en cp1251

    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    '''connection base oracle ''
     
    import cx_Oracle
     
    connection = cx_Oracle.connect('xxxx')
    print connection.version
    cursor = connection.cursor()
    cursor.execute("""
                      SELECT MAINTENANCE_MAIN_PK,
                      MAINTENANCE_CARAC,
                      STATUS_STATUS_PK,
                      CLIENT_NAME,
                      CATEGORY_CATEGORY_PK,
                      EQUIPMENT_NAME,
                      TO_CHAR(MAINTENANCE_ATT_DATE,'YYYY-MM-DD'),
                      MAINTENANCE_TIME FROM VQG_MAINTENANCE
                      """)
     
    rows = cursor.fetchall()
    connection.close()
     
    for item in rows:
        print item
     
    print len (rows)
    et le résultat est le suivant :
    ...
    ('25957', 'B', 'Termin\xe9e', None, 'Pr\xe9ventif', 'H\xf4tel de Police de Bordeaux', '2011-03-24', 6.0)
    ...
    Comment faire pour supprimer ces caractères spéciaux ???

    Merci de votre aide.

  2. #2
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Ah les joies de l’encodage…

    Tu peux récupérer un unicode à partir d’un str encodé dans une locale quelconque avec str.decode('ma_locale')*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    string = 'Termin\xe9e'
    uni = string.decode('cp1251')
    PS*: Édite donc ton premier post, manque un ' au début, ça gâche tout le code…

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

    A mon avis, il s'agit uniquement d'un problème d'affichage.

    En effet, "\xe9", par exemple, est bien la valeur numérique représentant le caractère 'é' dans l'encodage de Windows ('cp1252': voir http://fr.wikipedia.org/wiki/Windows-1252).

    Il y a en effet dans Python un problème d'affichage des str inclus dans des listes ou des tuples. Par exemple, prenons un str encodé cp1252, à afficher dans une console elle aussi en cp1252:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    x = u"abcéèçà".encode('cp1252') # x est encodé 'cp1252'
    print x
    abcéèçà
    print (12.52, x, 56)
    (12.52, 'abc\xe9\xe8\xe7\xe0', 56)
    print [12.52, x, 56]
    [12.52, 'abc\xe9\xe8\xe7\xe0', 56]
    Ce qui n'est pas très beau...

    Une solution est de créer une fonction qui transforme cette liste ou ce tuple en chaine de caractère, en provoquant les conversions nécessaires. Par exemple, la fonction suivante formatx(x, codin, codout), avec:
    x = l'objet à afficher
    codin = l'encodage des str
    codout = l'encodage objectif de la chaine finale (celui de la console d'affichage)

    A noter que l'encodage de la console d'affichage peut être trouvé par sys.stdout.encoding, mais cette instruction peut renvoyer None avec certains outils de développement (pyscripter par exemple).

    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
    # Python 2.7
     
    def formatx(x, codin='cp1252', codout='cp1252'):
        if isinstance(x,tuple):
            ch = "("
            if len(x) != 0:
                for elem in x:
                    ch += formatx(elem, codin, codout) + ", "
                ch = ch[:-2] # on retire la dernière virgule
            ch += ")"
        elif isinstance(x,list):
            ch = "["
            if len(x) != 0:
                for elem in x:
                    ch += formatx(elem, codin, codout) + ", "
                ch = ch[:-2] # on retire la dernière virgule
            ch += "]"
        else:
            # conversion de x en unicode s'il n'y est pas déjà
            if not isinstance(x,unicode):
                if isinstance(x,str):
                    x = x.decode(codin)
                else:
                    x = u"%s" % x
            # conversion si nécessaire dans l'encodage de sortie codout
            if codout == 'unicode':
                ch = x
            else:
                ch = x.encode(codout)
        return ch
    Exemples:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    x = u"abcéèçà".encode('cp1252') # x est encodé 'cp1252'
    print formatx(x)
    abcéèçà
    print formatx((12.52, x, 56))
    (12.52, abcéèçà, 56)
    print formatx([12.52, x, 56])
    [12.52, abcéèçà, 56]
    Comme cette fonction est récursive, on peut traiter des listes ou des tuples imbriqués dans des listes ou des tuples. Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    print formatx((x,123,[5,x,(8.2,x,6)],5.654))
    (abcéèçà, 123, [5, abcéèçà, (8.2, abcéèçà, 6)], 5.654)
    En cas de besoin, on peut bien sûr compléter la fonction en lui faisant traiter d'autres objets Python: dict, set, etc...

    Et on peut aussi prévoir de lui faire formater les nombres flottants quand il y en a!

    Tyrtamos

  4. #4
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    237
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 237
    Par défaut
    Merci je vais tester

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 743
    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 743
    Par défaut
    Salut,

    Normalement vous devriez pouvoir échanger de l'Unicode avec cx_oracle sans avoir à effectuer l'encoding vous même. Reste à trouver les incantations magiques à effectuer (voir la doc autour de NS_LANG).

    Personnellement, j'utilise SQLAlchemy qui se pose "au dessus" de cx_orale et permet d'avoir une API "uniforme" quelque soit le SGDB qui est dessous.
    voir l'interface entre SQLA et CX à l'URL

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

Discussions similaires

  1. Requête SQL
    Par Leludo dans le forum Langage SQL
    Réponses: 3
    Dernier message: 12/07/2024, 15h41
  2. Encodage des données issus d'une requête SQL
    Par Chipss dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 08/02/2013, 16h04
  3. [ DB2 ] [ AS400] requête sql
    Par zinaif dans le forum DB2
    Réponses: 6
    Dernier message: 23/08/2008, 19h42
  4. Utilisation de MAX dans une requête SQL
    Par Evil onE dans le forum Langage SQL
    Réponses: 7
    Dernier message: 15/06/2004, 18h38
  5. PB requète SQL avec Interbase
    Par missllyss dans le forum InterBase
    Réponses: 2
    Dernier message: 15/07/2003, 11h37

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