2016-10-19 6 views
1

Sorry für die millionste Frage dazu, aber ich habe so viel über das Thema gelesen und immer noch nicht diesen Fehler behoben (Neuling zu allem). Ich versuche, den Inhalt einer Postgres-Tabelle auf einer Website mit Kolben (Ubuntu 16.04/Python 2.7.12) anzuzeigen. Es gibt nicht-ASCII-Zeichen in der Tabelle ('ü' in diesem Fall) und das Ergebnis ist ein UnicodeDecodeError: 'Ascii' Codec kann Byte 0xc3 in Position 2 nicht dekodieren: Ordinal nicht im Bereich (128).Python/Flask: UnicodeDecodeError/UnicodeEncodeError: 'ASCII' Codec kann nicht dekodieren/encodieren

Dies ist, was mein init Py wie folgt aussieht:

 #-*- coding: utf-8 -*- 

from flask import Blueprint, render_template 
import psycopg2 
from .forms import Form 
from datetime import datetime 
from .table import Item, ItemTable 

test = Blueprint('test', __name__) 

def init_test(app): 
    app.register_blueprint(test) 

def createTable(cur): 
    cmd = "select * from table1 order by start desc;" 
    cur.execute(cmd) 
    queryResult = cur.fetchall() 
    items = [] 
    table = 'table could not be read' 
    if queryResult is not None:   
     for row in range(0, len(queryResult)): 
     items.append(Item(queryResult[row][0], queryResult[row][1].strftime("%d.%m.%Y"), queryResult[row][2].strftime("%d.%m.%Y"), \ 
          queryResult[row][1].strftime("%H:%M"), queryResult[row][2].strftime("%H:%M"), \ 
          queryResult[row][3], queryResult[row][4], queryResult[row][5], queryResult[row][6])) 
     table = ItemTable(items) 
    return table 


@test.route('/test') 
def index(): 
    dbcon = psycopg2.connect("dbname=testdb user=postgres host=localhost") 
    cur = dbcon.cursor() 
    table = createTable(cur) 
    cur.close() 
    return render_template('test_index.html', table=table) 

und ein Teil der HTML-Datei:

{% extends "layout.html" %} 
{% block head %}Title{% endblock %} 
{% block body %} 
<script type="text/javascript" src="{{ url_for('static', filename='js/bootstrap.js') }}"></script> 
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/custom.css') }}"> 
<div class="row" id="testid"> 
    {{table}} 
</div> 
{% endblock %}{# 
Local Variables: 
coding: utf-8 
End: #} 

Das Problem ist in queryresult [row] [6], die ist die einzige Zeile in der Tabelle mit Strings, der Rest ist Ganzzahlen. Die Kodierung der Postgres-Datenbank ist utf-8. Der Typ von queryResult [row] [6] gibt den Typ 'str' zurück. Was ich gelesen habe here ist, dass die Zeichenfolge in utf-8 codiert werden sollte, da dies die Codierung des Datenbankclients ist. Nun, das scheint nicht zu funktionieren !? Dann fügte ich die Linie

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) 

das Ergebnis zu zwingen Unicode (Art der queryresult [row] [6] zurück Typ 'Unicode') zu sein, denn als here wurde empfohlen, I überall in Unicode-Stick versucht . Nun, das führte zu einem UnicodeEncodeError: 'ascii' Codec kann das Zeichen u '\ xfc' nicht an Position 2 codieren: Ordnungszahl nicht im Bereich (128). Dann dachte ich, vielleicht etwas falsch ging vor zu bespannen (Bytes) mit der Umwandlung und ich versuchte es selbst dann

queryResult[row][6].encode('utf-8', 'replace') 

mit dem Schreiben zu tun, die zu einem UnicodeDecodeError führten: ‚ascii‘ Codec nicht Byte 0xC3 dekodieren kann in Position 2: Ordnungszahl nicht im Bereich (128). Habe nicht einmal mit "ignorieren" statt "ersetzen" gearbeitet. Was ist hier los? Ich habe überprüft, ob die render_template() ein Problem mit Unicode hat, indem ich eine Variable v = u'ü 'erstelle und überlasse, aber das war kein Problem und wurde korrekt angezeigt. Ja, las ich die übliche empfohlene Sachen wie nedbatchelder.com/text/unipain.html und Unicode Demystified, aber das hat mir helfen, mein Problem nicht lösen hier, ich bin etwas offensichtlich fehlt.

ist hier ein Rückverfolgungs des ersten UnicodeDecodeError:

File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask/app.py", line 2000, in __call__ 
return self.wsgi_app(environ, start_response) 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask/app.py", line 1991, in wsgi_app 
response = self.make_response(self.handle_exception(e)) 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask/app.py", line 1567, in handle_exception 
reraise(exc_type, exc_value, tb) 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask/app.py", line 1988, in wsgi_app 
response = self.full_dispatch_request() 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask/app.py", line 1641, in full_dispatch_request 
rv = self.handle_user_exception(e) 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask/app.py", line 1544, in handle_user_exception 
reraise(exc_type, exc_value, tb) 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask/app.py", line 1639, in full_dispatch_request 
rv = self.dispatch_request() 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask/app.py", line 1625, in dispatch_request 
return self.view_functions[rule.endpoint](**req.view_args) 
File "/home/name/Desktop/testFlask/app/test/__init__.py", line 95, in index 
return render_template('test_index.html', table=table) #, var=var 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask/templating.py", line 134, in render_template 
context, ctx.app) 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask/templating.py", line 116, in _render 
rv = template.render(context) 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/jinja2/environment.py", line 989, in render 
return self.environment.handle_exception(exc_info, True) 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/jinja2/environment.py", line 754, in handle_exception 
reraise(exc_type, exc_value, tb) 
File "/home/name/Desktop/testFlask/app/templates/test_index.html", line 1, in top-level template code 
{% extends "layout.html" %} 
File "/home/name/Desktop/testFlask/app/templates/layout.html", line 40, in top-level template code 
{% block body %}{% endblock %} 
File "/home/name/Desktop/testFlask/app/templates/test_index.html", line 7, in block "body" 
{{table}} 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask_table/table.py", line 86, in __html__ 
tbody = self.tbody() 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask_table/table.py", line 103, in tbody 
out = [self.tr(item) for item in self.items] 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask_table/table.py", line 120, in tr 
''.join(c.td(item, attr) for attr, c in self._cols.items() 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask_table/table.py", line 121, in <genexpr> 
if c.show)) 
File "/home/name/Desktop/testFlask/app/test/table.py", line 7, in td 
self.td_contents(item, self.get_attr_list(attr))) 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask_table/columns.py", line 99, in td_contents 
return self.td_format(self.from_attr_list(item, attr_list)) 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/flask_table/columns.py", line 114, in td_format 
return Markup.escape(content) 
File "/home/name/Desktop/testFlask/venv/lib/python2.7/site-packages/markupsafe/__init__.py", line 165, in escape 
rv = escape(s) 

Jede Hilfe wird sehr geschätzt ...

Antwort

0

So fand ich endlich eine Lösung nach überall mit Hilfe von

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) 

Der Fehler führte mich dann zu meiner eigenen Klasse customCol zu Unicode kleben (Kol), die ich geschrieben hatte:

class customCol(Col): 
def td(self, item, attr): 
    return '<td><div id="beschrCol">{}</div></td>'.format(
     self.td_contents(item, self.get_attr_list(attr))) 

Das Problem hier war der .format() Aufruf, und nach dem Lesen this, drehte ich gerade die Zeichenfolge vor .format auf Unicode und das Problem wurde gelöst,

def td(self, item, attr): 
    return u'<td><div id="beschrCol">{}</div></td>'.format... 

Arbeiten mit Strings Artikeln() über auch, aber dann hatte ich

queryResult[row][6].decode('utf-8') 

im Item() Aufruf zu setzen.

0

da in Python 2 Bytecode nicht erzwungen wird, kann man mit ihnen verwirrt. Codierung und Decodierung funktioniert so weit ich weiß von String zu Bytecode und umgekehrt. Wenn also Ihr Resultset eine Zeichenfolge ist, sollte es nicht notwendig sein, sie erneut zu codieren. Wenn Sie falsche Darstellungen für Sonderzeichen wie "§" erhalten, würde ich etwas wie das versuchen:

repr (queryResult [Zeile] [6])).

Funktioniert das?

+0

Wenn ich 'repr (queryResult [row] [6]))' zu Item() übergebe, verschwindet der Fehler tatsächlich. Aber jetzt wird der Umlaut in der Tabelle als '\ xc3 \ xbc' angezeigt, was nicht lesbar ist. Wenn ich zusätzlich 'psycopg2.extensions.register_type (psycopg2.extensions.UNICODE)' setze, dann habe ich u '\ xfc', was auch nicht lesbar ist. – Rena

+0

Hinzufügen eines .decode ('utf-8') oder .encodes ('utf-8') resp. in repr() wird auch nichts ändern. Irgendeine Idee, wie man einen Umlaut auf diese Weise darstellt? Vielen Dank! – Rena

0

See: https://wiki.python.org/moin/UnicodeEncodeError

The encoding of the postgres database is utf-8. The type of queryResult[row][6] returns type 'str'.

Sie es richtig haben bisher. Denken Sie daran, dass in Python 2.7 eine str eine Bytefolge ist.Sie haben also eine Bytefolge aus der Datenbank, die wahrscheinlich aussieht wie 'gl\xc3\xbce' ('glüe').

Was als nächstes passiert ist, dass ein Teil des Programms .decode auf Ihrer Zeichenfolge aufruft, aber den Standardcode "ASCII" verwendet. Es ist wahrscheinlich ein Teil der Item() API, die die Zeichenfolge als ein Unicode-Objekt oder vielleicht Flask selbst benötigt. So oder so, müssen Sie .decode sich auf die Zeichenfolge nennen, da Sie wissen, dass es tatsächlich in utf-8:

col_6 = queryResult[row][6].decode('utf-8') 
Item(..., ..., col_6, ...) 

Dann wird Ihnen alle Downstream-APIs mit einem unicode die offenbar ist, was sie wollen.

So erinnere ich mich daran: Unicode ist eine Abstraktion, bei der alles als "Codepunkte" dargestellt wird. Wenn wir echte Bytes erstellen möchten, die wir auf einem Bildschirm drucken oder als HTML-Datei senden können, müssen wir ENCODIEREN in Byte. Wenn Sie einige Bytes haben, könnten sie irgendwelche Buchstaben bedeuten, wer weiß? Sie müssen die mysteriösen Bytes dekodieren, um Unicode zu erhalten.

Hoffe, das hilft.

+0

Dies führt leider immernoch zu einem – Rena

+0

UnicodeEncodeError: 'ascii' Codec kann das Zeichen u '\ xfc' nicht an Position 2 codieren: Ordinal nicht im Bereich (128). Irgendwelche Ideen warum? (Hinweis für mich: Drücken Sie nicht Enter für einen Zeilenumbruch ...) – Rena

Verwandte Themen