Подтвердить что ты не робот

Ошибка кодирования с помощью sqlalchemy и postgresql

Я использую пирамиду для веб-приложения с базой данных postgres, wtforms, sqlalchemy и jinja2, и у меня возникает эта ошибка, когда приложение пытается получить типы проблем из базы данных, чтобы заполнить поле выбора с помощью wtforms:

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

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 как кодировка по умолчанию в python

и я пробую что-то вроде этого, но это не сработало

gae python ascii canec decode byte

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

Ответ 1

Вам нужно настроить клиентскую кодировку Psycopg2. См. Документацию SQLAlchemy:

По умолчанию драйвер psycopg2 использует расширение psycopg2.extensions.UNICODE, так что DBAPI получает и возвращает все строки как объекты Unicode Python напрямую - SQLAlchemy передает эти значения без изменений. Psycopg2 здесь будет кодировать/декодировать строковые значения на основе текущей настройки "клиентского кодирования"; по умолчанию это значение в файле postgresql.conf, которое по умолчанию по умолчанию равно SQL_ASCII. Как правило, это можно изменить на utf-8, как более полезное значение по умолчанию:

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

Второй способ повлиять на кодировку клиента - установить его внутри Psycopg2 локально. SQLAlchemy вызовет метод psycopg2s set_client_encoding() (см. http://initd.org/psycopg/docs/connection.html#connection.set_client_encoding) для всех новых подключений на основе значения, переданного в create_engine(), с помощью client_encoding:

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

Это переопределяет кодировку, указанную в конфигурации клиента Postgresql.

Параметр client_encoding может быть указан как строка запроса в URL-адресе движка:

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