简体   繁体   English

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

[英]Python/Flask: UnicodeDecodeError/ UnicodeEncodeError: 'ascii' codec can't decode/encode

Sorry for the millionth question about this, but I've read so much about the topic and still don't get this error fixed (newbie to all of this). 对于关于这个的第一百万个问题,我很抱歉,但我已经阅读了很多关于这个主题的内容,但仍然没有修复这个错误(所有这一切的新手)。 I'm trying to display the content of a postgres table on a website with flask (using Ubuntu 16.04/python 2.7.12). 我试图在带有烧瓶的网站上显示postgres表的内容(使用Ubuntu 16.04 / python 2.7.12)。 There are non-ascii characters in the table ('ü' in this case) and the result is a UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2: ordinal not in range(128). 表中有非ascii字符(在这种情况下为'ü'),结果是UnicodeDecodeError:'ascii'编解码器无法解码位置2中的字节0xc3:序数不在范围内(128)。

This is what my init .py looks like: 这就是我的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)

And part of the html-file: 和部分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: #}

The problem is in queryResult[row][6] which is the only row in the table with strings, the rest is integers. 问题出在queryResult [row] [6]中,这是表中唯一带有字符串的行,其余的是整数。 The encoding of the postgres database is utf-8. postgres数据库的编码是utf-8。 The type of queryResult[row][6] returns type 'str'. queryResult [row] [6]的类型返回类型'str'。 What I read here is that the string should be encoded in utf-8, as that is the encoding of the database client. 在这里读到的是字符串应该用utf-8编码,因为这是数据库客户端的编码。 Well, that doesn't seem to work!? 嗯,这似乎不起作用!? Then I added the line 然后我添加了这条线

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

to force the result to be unicode (type of queryResult[row][6] returned type 'unicode'), because as was recommended here , I tried to stick to unicode everywhere. 强制结果为unicode(queryResult类型[row] [6]返回类型'unicode'),因为在这里推荐,我试图坚持到处都是unicode。 Well that resulted in a UnicodeEncodeError: 'ascii' codec can't encode character u'\\xfc' in position 2: ordinal not in range(128). 那导致了一个UnicodeEncodeError:'ascii'编解码器无法编码位置2中的字符u'\\ xfc':序号不在范围内(128)。 Then I thought, maybe something went wrong with converting to string (bytes) before and I tried to do it myself then with writing 然后我想,也许在转换为字符串(字节)之前出现了问题,我尝试自己做,然后写作

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

which led to an UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2: ordinal not in range(128). 导致UnicodeDecodeError:'ascii'编解码器无法解码位置2中的字节0xc3:序数不在范围内(128)。 Didn't even work with 'ignore' instead of 'replace'. 甚至没有使用'忽略'而不是'替换'。 What is going on here? 这里发生了什么? I checked if the render_template() has a problem with unicode by creating and passing a variable v=u'ü', but that was no problem and was displayed correctly. 我通过创建并传递变量v =u'ü'检查了render_template()是否存在unicode问题,但这没有问题并且显示正确。 Yeah, I read the usual recommended stuff like nedbatchelder.com/text/unipain.html and Unicode Demystified, but that didn't help me solve my problem here, I'm obviously missing something. 是的,我读过nedbatchelder.com/text/unipain.html和Unicode Demystified等常用的推荐内容,但这并没有帮助我解决我的问题,我显然错过了一些东西。

Here is a traceback of the first UnicodeDecodeError: 这是第一个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)

Any help is greatly appreciated... 任何帮助是极大的赞赏...

since in Python 2 bytecode is not enforced, one can get confused with them. 因为在Python 2中没有强制执行字节码,所以人们可能会对它们感到困惑。 Encoding and Decoding works as far as i know from string to bytecode and reverse. 就字符串到字节码和反向而言,编码和解码工作。 So if your resultset is a string, there should be no need to encode it again. 因此,如果您的结果集是一个字符串,则不需要再次对其进行编码。 If you get wrong representations for special characters like "§", i would try something like this: 如果您对“§”这样的特殊字符有错误的表示,我会尝试这样的事情:

repr(queryResult[row][6])). 再版(QueryResult中[行] [6]))。

Does that work? 那样有用吗?

See: https://wiki.python.org/moin/UnicodeEncodeError 请参阅: https//wiki.python.org/moin/UnicodeEncodeError

The encoding of the postgres database is utf-8. postgres数据库的编码是utf-8。 The type of queryResult[row][6] returns type 'str'. queryResult [row] [6]的类型返回类型'str'。

You've got it right so far. 到目前为止你已经做对了。 Remember, in Python 2.7, a str is a string of bytes. 请记住,在Python 2.7中, str是一个字节串。 So you've got a string of bytes from the database, that probably looks like 'gl\\xc3\\xbce' ( 'glüe' ). 所以你从数据库中得到一串字节,可能看起来像'gl\\xc3\\xbce''glüe' )。

What happens next is that some part of the program is calling .decode on your string, but using the default 'ascii' codec. 接下来会发生的是,程序的某些部分在字符串上调用.decode ,但使用默认的“ascii”编解码器。 It's probably some part of the Item() API that needs the string as a unicode object, or maybe Flask itself. 它可能是Item()API的一部分,需要将字符串作为unicode对象,或者可能是Flask本身。 Either way, you need to call .decode yourself on your string, since you know that it's actually in utf-8: 无论哪种方式,你需要在你的字符串上调用.decode ,因为你知道它实际上是在utf-8中:

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

Then you will provide all the downstream APIs with a unicode which is apparently what they want. 然后,您将为所有下游API提供一个显然是他们想要的unicode

The way I remember it is this: Unicode is a an abstraction, where everything is represented as "code points". 我记得它的方式是:Unicode是一种抽象,其中所有东西都表示为“代码点”。 If we want to create real bytes that we can print on a screen or send as an HTML file, we need to ENcode to bytes. 如果我们想要创建可以在屏幕上打印或作为HTML文件发送的实际字节,我们需要将EN编码为字节。 If you have some bytes, they could mean any letters, who knows? 如果你有一些字节,它们可能意味着任何字母,谁知道? You need to DEcode the mysterious bytes in order to get Unicode. 您需要对神秘字节进行DE代码才能获得Unicode。

Hope this helps. 希望这可以帮助。

So I finally found a solution after sticking to unicode everywhere with the help of 所以我终于找到了一个解决方案,在帮助下坚持到处都是unicode

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

The error led me then to my own class customCol(Col) that I had written: 错误导致我然后到我自己编写的类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)))

The problem here was the .format() call, and after reading this , I just turned the string in front of .format to unicode and the problem was solved, 这里的问题是.format()调用,看完之后这个 ,我只是把字符串中.format面前Unicode和问题解决了,

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

Works with passing strings to Item(), too, but then I had to put 也可以将字符串传递给Item(),但是我必须放入

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

in the Item() call. 在Item()调用中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 UnicodeDecodeError:“ ascii”编解码器无法解码-Python - UnicodeDecodeError: 'ascii' codec can't decode - Python Flask-Admin:UnicodeDecodeError:&#39;ascii&#39;编解码器无法解码字节 - Flask-Admin: UnicodeDecodeError: 'ascii' codec can't decode byte 收到UnicodeEncodeError的Python脚本:“ ascii”编解码器无法编码字符 - Python script receiving a UnicodeEncodeError: 'ascii' codec can't encode character Python错误:UnicodeEncodeError:&#39;ascii&#39;编解码器无法编码字符 - Python error : UnicodeEncodeError: 'ascii' codec can't encode character Python3中的“ UnicodeEncodeError:&#39;ascii&#39;编解码器无法编码字符” - “UnicodeEncodeError: 'ascii' codec can't encode character” in Python3 Python UnicodeEncodeError:&#39;ascii&#39;编解码器无法编码字符 - Python UnicodeEncodeError: 'ascii' codec can't encode characters 再次:UnicodeEncodeError:ascii编解码器无法编码 - Again: UnicodeEncodeError: ascii codec can't encode UnicodeEncodeError:&#39;ascii&#39;编解码器无法编码字符 - UnicodeEncodeError: 'ascii' codec can't encode characters UnicodeEncodeError:“ ascii”编解码器无法编码 - UnicodeEncodeError: 'ascii' codec can't encode UnicodeEncodeError:&#39;ascii&#39;编解码器不能编码字符[...] - UnicodeEncodeError: 'ascii' codec can't encode character […]
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM