首页 文章

Python / Flask:UnicodeDecodeError / UnicodeEncodeError:'ascii' codec无法解码/编码

提问于
浏览
1

对于关于这个的第一百万个问题,我很抱歉,但我已经阅读了很多关于这个主题的内容,但仍然没有修复这个错误(所有这一切的新手) . 我试图在带有烧瓶的网站上显示postgres表的内容(使用Ubuntu 16.04 / python 2.7.12) . 表中有非ascii字符(在这种情况下为'ü'),结果是UnicodeDecodeError:'ascii'编解码器无法解码位置2中的字节0xc3:序数不在范围内(128) .

这就是我的 init .py看起来像:

#-*- 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)

和部分html文件:

{% 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: #}

问题出在queryResult [row] [6]中,这是表中唯一带有字符串的行,其余的是整数 . postgres数据库的编码是utf-8 . queryResult [row] [6]的类型返回'str'类型 . 我读的here是字符串应该用utf-8编码,因为这是数据库客户端的编码 . 嗯,这似乎不起作用!?然后我添加了这条线

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

强制结果为unicode(queryResult [row] [6]的类型返回类型'unicode'),因为建议here,我试图坚持到处都是unicode . 那导致了一个UnicodeEncodeError:'ascii'编解码器在位置2中可以't encode character u' \ xfc':序数不在范围内(128) . 然后我想,也许在转换为字符串(字节)之前出现问题,然后我尝试自己编写

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

导致UnicodeDecodeError:'ascii'编解码器无法解码位置2中的字节0xc3:序数不在范围内(128) . 甚至没有使用'忽略'而不是'替换' . 这里发生了什么?我通过创建并传递变量v =u'ü'检查了render_template()是否存在unicode问题,但这没有问题并且显示正确 . 是的,我读过nedbatchelder.com/text/unipain.html和Unicode Demystified等常用的推荐内容,但这并没有帮助我解决我的问题,我显然错过了一些东西 .

这是第一个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)

任何帮助是极大的赞赏...

3 回答

  • 0

    因为在Python 2中没有强制执行字节码,所以人们可能会对它们感到困惑 . 就字符串到字节码和反向而言,编码和解码工作 . 因此,如果您的结果集是一个字符串,则不需要再次对其进行编码 . 如果您对“§”这样的特殊字符有错误的表示,我会尝试这样的事情:

    再版(QueryResult中[行] [6])) .

    那样有用吗?

  • 0

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

    postgres数据库的编码是utf-8 . queryResult [row] [6]的类型返回类型'str' .

    到目前为止你已经做对了 . 请记住,在Python 2.7中, str 是一个字节字符串 . 所以你有一个来自数据库的字符串,可能看起来像 'gl\xc3\xbce''glüe' ) .

    接下来发生的是程序的某些部分在字符串上调用 .decode ,但使用默认的'ascii'编解码器 . 它可能是Item()API的一部分,需要将字符串作为unicode对象,或者可能是Flask本身 . 无论哪种方式,你需要在你的字符串上自己调用 .decode ,因为你知道它实际上是在utf-8中:

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

    然后,您将为所有下游API提供 unicode ,这显然是他们想要的 .

    我记得它的方式是:Unicode是一种抽象,其中所有东西都表示为“代码点” . 如果我们想要创建可以在屏幕上打印或作为HTML文件发送的实际字节,我们需要将EN编码为字节 . 如果你有一些字节,它们可能意味着任何字母,谁知道?您需要对神秘字节进行DE代码才能获得Unicode .

    希望这可以帮助 .

  • 0

    所以我终于找到了一个解决方案,在帮助下坚持到处都是unicode

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

    错误导致我然后到我自己编写的类customCol(Col):

    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)))
    

    这里的问题是.format()调用,在读完this后,我只是将.format前面的字符串转为unicode,问题解决了,

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

    也可以将字符串传递给Item(),但是我必须放入

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

    在Item()调用中 .

相关问题