编码PostgreSQL,Python,Jinja2 [英] Encoding on PostgreSQL, Python, Jinja2
问题描述
这是场景:
-
具有UTF-8编码的PostgreSQL(
CREATE DATABASE xxxx WITH ENCODING'UTF8'
) -
Python逻辑也使用UTF-8编码(
# - * - 编码:utf-8 - * -
) -
Jinja2显示我的HTML页面。 Python和Jinja2用于Flask,这是我正在使用的微型薄膜。
我的页面的标题:< meta http-equiv =content-typecontent =text / html; charset = utf-8/>
嗯,使用psycopg2做一个简单的查询,并在Jinja2上打印,这是我得到的:
{%for company in list%}
< li>
{{company}}
< / li>
{%endfor%}
(1,'Casa das M\xc3\ xa1quinas','R. Tr\xc3\xaas,Mineiros - Goi\xc3\xa1s')
(2,'Ar do Z\xc3 \xa9','Av。S\xc3\xa9tima,Mineiros - Goi\xc3\xa1s')
如果我尝试更深入字段:
{%列表中的公司%}
< li>
{%for company in company%}
< li>
{{field}}
< / li>
{%endfor%}
< / li>
{%endfor%}
我收到以下错误:UnicodeDecodeError:'ascii'无法解码位置10中的0xc3字节:序号不在范围(128)
但是,如果在发送到Jinja2之前打印列表字段,我得到预期的结果(这也是如何在postgresql中呈现):
1
Casa dasMáquinas
R.Três,Mineiros - Goiás
2
Ar doZé
Av。 Sétima,Mineiros - Goiás
当我收到错误时,Flask提供了一个调试选项。这是代码断开的地方
文件/home/anonimou/Desktop/flask/lib/python2.7/site-packages/jinja2/_markupsafe/_native.py,第21行,在逃脱
返回标记(unicode)
我也可以这样做:
[控制台就绪]
>>>打印s
卡萨达斯马卡斯
>> s
'卡萨达$ s
UnicodeDecodeError:'ascii'编解码器无法解码位置10中的0xc3字节:序号不在范围内(128)
>>> s.decode('utf-8')
u'Casa das M\xe1quinas'
> > s.encode('utf-8')
UnicodeDecodeError:'ascii'编解码器无法解码位置10中的0xc3位数:不在范围(128)
> ;>> s.decode('utf-8')。encode('utf-8')
'Casa das M\xc3\xa1quinas'
>> ;> print s.decode('utf-8')。encode('utf-8')
Casa dasMáquinas
>>&打印s.decode('utf-8')
Casa dasMáquinas
I在将其发送到Jinja2之前,已经尝试打破列表,解码,编码,在python代码中。同样的错误。
Sooo,不知道我可以在这里做什么。 =(
提前感谢
问题是 psycopg2在Python 2中默认返回字符串 :
从数据库读取数据时,在Python 2中返回的字符串通常为8位
str
在数据库客户编码中编码的对象
所以你可以:
-
将所有数据手动解码为UTF-8:
#解码字节串
company = [company.decode(utf-8)for company in companies]
return render_template(companies .html,公司=公司)
或
-
根据笔记中的注释,首次导入psycopg2时,设置编码器手册的相同部分:
注意在Python 2中,如果要统一接收所有数据库输入Unicode,您可以在Psycopg导入后立即注册全局相关类型:
import psycopg2
import psycopg2.extensions
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
然后忘记这个故事。
I'm having a problem with encoding in my application and didn't find the solution anywhere on web.
Here is the scenario:
PostgreSQL with UTF-8 encoding (
CREATE DATABASE xxxx WITH ENCODING 'UTF8'
)Python logic also with UTF-8 encoding (
# -*- coding: utf-8 -*-
)Jinja2 to show my HTML pages. Python and Jinja2 are used on Flask, which is the microframework I'm using.
The header of my pages have: <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
Well, using psycopg2 to do a simple query and print it on Jinja2, this is what I get:
{% for company in list %}
<li>
{{ company }}
</li>
{% endfor %}
(1, 'Casa das M\xc3\xa1quinas', 'R. Tr\xc3\xaas, Mineiros - Goi\xc3\xa1s')
(2, 'Ar do Z\xc3\xa9', 'Av. S\xc3\xa9tima, Mineiros - Goi\xc3\xa1s')
If I try do get more deep into the fields:
{% for company in list %}
<li>
{% for field in company %}
<li>
{{ field }}
</li>
{% endfor %}
</li>
{% endfor %}
I get the following error: UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)
However, if I do a print of the list fields before sending them to Jinja2, I get the expected result (which is also how is presented in postgresql):
1 Casa das Máquinas R. Três, Mineiros - Goiás
2 Ar do Zé Av. Sétima, Mineiros - Goiás
When I get the error, Flask offers an option to "debug". This is where the code breaks File "/home/anonimou/Desktop/flask/lib/python2.7/site-packages/jinja2/_markupsafe/_native.py", line 21, in escape return Markup(unicode(s)
And I can also do:
[console ready]
>>> print s
Casa das Máquinas
>>> s
'Casa das M\xc3\xa1quinas'
>>> unicode(s)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)
>>> s.decode('utf-8')
u'Casa das M\xe1quinas'
>>> s.encode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)
>>> s.decode('utf-8').encode('utf-8')
'Casa das M\xc3\xa1quinas'
>>> print s.decode('utf-8').encode('utf-8')
Casa das Máquinas
>>> print s.decode('utf-8')
Casa das Máquinas
I've already tried to break the list, decode, encode, in python code before sending it to Jinja2. The same error.
Sooo, not sure what I can do here. =(
Thanks in advance!
The issue is that psycopg2 returns byte strings by default in Python 2:
When reading data from the database, in Python 2 the strings returned are usually 8 bit
str
objects encoded in the database client encoding
So you can either:
Manually decode all of the data to UTF-8:
# Decode the byte strings into Unicode objects using # the encoding you know that your database is using. companies = [company.decode("utf-8") for company in companies] return render_template("companies.html", companies=companies)
or
Set the encoders when you first import psycopg2 as per the note in the same section of the manual:
Note In Python 2, if you want to uniformly receive all your database input in Unicode, you can register the related typecasters globally as soon as Psycopg is imported:
import psycopg2 import psycopg2.extensions psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
and then forget about this story.
这篇关于编码PostgreSQL,Python,Jinja2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!