2013-02-09 73 views
12

我正在使用一个postgres数据库,wtforms,sqlalchemy和jinja2的Web应用程序金字塔和我遇到此错误时应用程序尝试从数据库中获取问题类型以填充选择场wtforms:使用sqlalchemy和postgresql编码错误

Error: 'ascii' codec can't decode byte 0xc3 in position 5: ordinal not in range(128) 

这是问题的类型表到model.py:

class Mixin(object): 
    id = Column(Integer, primary_key=True, autoincrement=True) 
    created = Column(DateTime()) 
    modified = Column(DateTime()) 

    __table_args__ = { 
     'mysql_engine': 'InnoDB', 
     'mysql_charset': 'utf8' 
    } 
    __mapper_args__ = {'extension': BaseExtension()} 

class IssueType(Mixin, Base): 
    __tablename__ = "ma_issue_types" 
    name = Column(Unicode(40), nullable=False) 

    def __init__(self, name): 
     self.name = name 

进入BD我有这样的:

# select name from ma_issue_types where id = 3; 
name  
------------ 
Teléfono 

这是发生错误

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

from issuemall.models import DBSession, IssueType 


class IssueTypeDao(object): 

    def getAll(self): 
     dbsession = DBSession() 
     return dbsession.query(IssueType).all() #HERE THROWS THE ERROR 

这是回溯

Traceback (most recent call last): 
    File "/issueMall/issuemall/controller/issueRegisterController.py", line 16, in issue_register 
    form = IssueRegisterForm(request.POST) 
    File "/env/lib/python2.7/site-packages/wtforms/form.py", line 178, in __call__ 
    return type.__call__(cls, *args, **kwargs) 
    File "/env/lib/python2.7/site-packages/wtforms/form.py", line 224, in __init__ 
    super(Form, self).__init__(self._unbound_fields, prefix=prefix) 
    File "/env/lib/python2.7/site-packages/wtforms/form.py", line 39, in __init__ 
    field = unbound_field.bind(form=self, name=name, prefix=prefix, translations=translations) 
    File "/env/lib/python2.7/site-packages/wtforms/fields/core.py", line 301, in bind 
    return self.field_class(_form=form, _prefix=prefix, _name=name, _translations=translations, *self.args, **dict(self.kwargs, **kwargs)) 
    File "/issueMall/issuemall/form/generalForm.py", line 11, in __init__ 
    types = issueTypeDao.getAll() 
    File "/issueMall/issuemall/dao/master/issueTypeDao.py", line 11, in getAll 
    return self.__dbsession.query(IssueType).all() 
    File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/query.py", line 2115, in all 
    return list(self) 
    File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/query.py", line 2341, in instances 
    fetch = cursor.fetchall() 
    File "build/bdist.linux-x86_64/egg/sqlalchemy/engine/base.py", line 3205, in fetchall 
    l = self.process_rows(self._fetchall_impl()) 
    File "build/bdist.linux-x86_64/egg/sqlalchemy/engine/base.py", line 3172, in _fetchall_impl 
    return self.cursor.fetchall() 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 5: ordinal not in range(128) 

我试试这个的一部分,但它没有工作 ascii as default encoding in python

,我尝试这样的事情,但它不起作用

gae python ascii codec cant decode byte

return dbsession.query(IssueType.id, IssueType.name.encode('utf-8')).all() #or decode('utf-8') 
+0

这是一大堆代码。你可以尝试更多的本地化你的问题,并编辑我们的问题,使其更容易处理? – millimoose 2013-02-09 00:30:10

+0

错误在这里返回dbsession.query(IssueType).all() – jdurango 2013-02-09 00:33:00

+1

不,这就是错误体现的地方。我的意思是尝试调试东西,看看最后调用什么,看看使用'ascii'解码什么,为什么? – millimoose 2013-02-09 00:38:34

回答

30

您需要配置Psycopg2的客户端编码。见SQLAlchemy documentation

默认情况下,psycopg2驱动程序使用psycopg2.extensions.UNICODE扩展,使得DBAPI接收并像Python的Unicode对象直接返回的所有字符串 - SQLAlchemy中通过不改变这些值传递。 Psycopg2将根据当前的“客户端编码”设置对字符串值进行编码/解码;默认情况下,这是postgresql.conf文件中的值,通常默认为SQL_ASCII。通常,这可以被改变为utf-8,作为更有用默认:

#client_encoding = sql_ascii # actually, defaults to database 
          # encoding 
client_encoding = utf8 

影响客户端编码的第二种方法是将内Psycopg2设置在本地。 SQLAlchemy的将调用psycopg2的set_client_encoding()方法(参见:http://initd.org/psycopg/docs/connection.html#connection.set_client_encoding)基于使用client_encoding参数传递给create_engine()值的所有新连接:

engine = create_engine("postgresql://user:[email protected]/dbname", client_encoding='utf8') 

这将覆盖在PostgreSQL客户端配置中指定的编码。

client_encoding参数可以被指定为引擎网址进行查询字符串:

postgresql://user:[email protected]/dbname?client_encoding=utf8 
+2

非常感谢您的解决方案是更改编码在postgresql.conf – jdurango 2013-02-09 14:04:47

+3

您还可以设置**的PostgreSQL://用户:通过@主机/ DBNAME CLIENT_ENCODING = utf8 ** – 2014-03-07 14:49:36

+0

谢谢,这有帮助 – Jake 2017-04-22 04:15:05

0

我用mysql,并设置这样的字符集。这个对我有用。

from sqlalchemy import create_engine 
from sqlalchemy.engine.url import URL 

db_url = { 
    'database': 'db_name', 
    'drivername': 'mysql', 
    'username': 'username', 
    'password': 'mypassword', 
    'host': '127.0.0.1', 
    'query': {'charset': 'utf8'}, 
} 

engine = create_engine(URL(**db_url), encoding="utf8")