web-dev-qa-db-fra.com

Lecture correcte du texte du fichier Windows-1252 (cp1252) dans python

donc d'accord, comme le titre le suggère, le problème que j'ai est de lire correctement l'entrée d'un fichier encodé windows-1252 dans python et d'insérer ladite entrée dans la table SQLAlchemy-MySql.

La configuration actuelle du système:
Windows 7 VM avec "Roger Access Control System" qui sort le fichier;
Ubuntu 12.04 LTS VM avec un dossier partagé sur le système Windows afin que je puisse accéder au fichier, en utilisant "Python 2.7.3".

Maintenant, pour le problème réel, pour le fichier d'entrée, j'ai un "dossier partagé VM" qui contient un fichier qui est généré sur un système Windows 7 via Roger Access Control System (roger.pl pour plus de détails), ce fichier est appelé " PREvents.csv "qui suggère à son contenu, un"; " liste séparée de données.

Un exemple de format des données:

2013-03-19;15:58:30;100;Jānis;Dumburs;1;Uznemums1;0;Ieeja;
2013-03-19;15:58:40;100;Jānis;Dumburs;1;Uznemums1;2;Izeja;

Le 4ème champ contient le nom du propriétaire de la carte et le 5ème contient le nom du propriétaire, le 6ème contient le groupe assigné aux propriétaires.

Le problème vient du fait que l'un des 3 champs mentionnés ci-dessus peut contenir des caractères spécifiques à la langue lettone, dans le fichier d'exemple le mot "Jānis" contient la lettre "à" qui en unicode est 257.

Comme d'habitude, j'ouvre le fichier comme tel:

try:
    f = codecs.open(file, 'rb', 'cp1252')
except IOError:
    f = codecs.open(file, 'wb', 'cp1252')

Jusqu'à présent, tout fonctionne - il ouvre le fichier et je passe donc à itérer sur chaque ligne du fichier (c'est un script en cours d'exécution, alors pardonnez la boucle):

while True:
    line = f.readline()

    if not line:
        # Pause loop for 1 second
        time.sleep(1)
    else:
        # Split the line into list
        date, timed, userid, firstname, lastname, groupid, groupname, typed, pointname, empty = line.split(';')

Et c'est là que les problèmes commencent, si je print repr(firstname) il imprime u'J\xe2nis' Qui est, autant que je comprends, pas correct - "\ xe2\ne représente pas le caractère letton" à " .
Plus loin dans la boucle en fonction du type d'événement, j'affecte les variables à l'objet SQLAlchemy et j'insère/mets à jour:

if typed == '0':  # Entry type
    event = Events(
        period,
        fullname,
        userid,
        groupname,
        timestamp,
        0,
        0
    )
    session.add(event)
else:  # Exit type
    event = session.query(Events).filter(
        Events.period == period,
        Events.exit == 0,
        Events.userid == userid
    ).first()
    if event is not None:
        event.exit = timestamp
        event.spent = timestamp - event.entry

# Commit changes to database
session.commit()

Dans ma recherche de réponses, j'ai trouvé comment définir l'encodage par défaut à utiliser:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

Ce qui ne m'a d'aucune façon aidé.

Fondamentalement, tout cela conduit à ce que le moi ne puisse pas insérer les propriétaires corrects Prénom/nom ainsi que les propriétaires affectés au nom de groupe s'ils contiennent l'un des caractères spécifiques à la Lettonie, par exemple:

Instead of the character "ā" it inserts "â"

Je voudrais également ajouter que je ne peux pas modifier l'encodage du fichier "PREvents.csv" et que le système "RACS" ne prend pas en charge l'insertion dans des fichiers UTF-8 ou Unicode - si vous essayez dans un sens ou dans l'autre, le système insère des symboles aléatoires pour le Caractères spécifiques au letton.

S'il vous plaît laissez-moi maintenant si d'autres informations sont nécessaires, je me ferai un plaisir de les fournir :)

Toute aide serait très appréciée.

24
Krisjanis Zvaigzne

CP1252 ne peut pas représenter â; votre entrée contient le caractère similaire â. repr affiche simplement une représentation ASCII d'une chaîne unicode dans Python 2.x:

>>> print(repr(b'J\xe2nis'.decode('cp1252')))
u'J\xe2nis'
>>> print(b'J\xe2nis'.decode('cp1252'))
Jânis
20
phihag

Je pense u'J\xe2nis' est correct, voir:

>>> print u'J\xe2nis'.encode('utf-8')
Jânis

Obtenez-vous des erreurs réelles de SQLAlchemy ou de la sortie de votre application?

2
djc