web-dev-qa-db-ja.com

UnicodeEncodeError: 'latin-1'コーデックは位置0-1の文字をエンコードできません:序数が範囲内にありません(256)

私はPythonの初心者です。今日、検索関数を作成するとエラーが発生しました。これを行うには、sqlalchemy ormを使用します。関数では、中国語のWordをキーWordとして入力します。htmlページでUnicodeEncodeErrorが表示されます。/user/search: 'latin-1'コーデックは位置0-1の文字をエンコードできません:ordinalはrange(256)にありません。私のコードは次のようなものです:

def user_search(request):
    name = request.GET.get('name').strip()
    user_list = list()

    if name:
        user_list = User.get_by_name(name)

class User(object):
    @classmethod
    def get_by_name(cls, name):
        return DBSession.query(cls).filter(cls.name==name)

トレースバックはここにあります:

Traceback:
    File "/usr/local/lib/python2.6/dist-packages/Django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/home/jiankong/git/admin-server/lib/decorators.py" in wrapper
  75.                     return func(request, *args, **kwargs)
File "/home/jiankong/git/admin-server/lib/decorators.py" in wrapper
  39.             output = function(request, *args, **kwargs)
File "/home/jiankong/git/admin-server/apps/user/user_views.py" in user_search
  47.     users = jump_page(paginator, page)
File "/home/jiankong/git/admin-server/apps/user/utils.py" in jump_page
  92.         return paginator.page(1)
File "/usr/local/lib/python2.6/dist-packages/Django/core/paginator.py" in page
  37.         number = self.validate_number(number)
File "/usr/local/lib/python2.6/dist-packages/Django/core/paginator.py" in validate_number
  28.         if number > self.num_pages:
File "/usr/local/lib/python2.6/dist-packages/Django/core/paginator.py" in _get_num_pages
  60.             if self.count == 0 and not self.allow_empty_first_page:
File "/usr/local/lib/python2.6/dist-packages/Django/core/paginator.py" in _get_count
  48.                 self._count = self.object_list.count()
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.Egg/sqlalchemy/orm/query.py" in count
  2414.         return self.from_self(col).scalar()
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.Egg/sqlalchemy/orm/query.py" in scalar
  2240.             ret = self.one()
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.Egg/sqlalchemy/orm/query.py" in one
  2209.         ret = list(self)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.Egg/sqlalchemy/orm/query.py" in __iter__
  2252.         return self._execute_and_instances(context)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.Egg/sqlalchemy/orm/query.py" in _execute_and_instances
  2267.         result = conn.execute(querycontext.statement, self._params)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.Egg/sqlalchemy/engine/base.py" in execute
  664.                                                 params)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.Egg/sqlalchemy/engine/base.py" in _execute_clauseelement
  764.             compiled_sql, distilled_params
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.Egg/sqlalchemy/engine/base.py" in _execute_context
  871.                                     context)
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.8.1dev-py2.6-linux-i686.Egg/sqlalchemy/engine/default.py" in do_execute
  324.         cursor.execute(statement, parameters)
File "/usr/local/lib/python2.6/dist-packages/MySQL_python-1.2.4-py2.6-linux-i686.Egg/MySQLdb/cursors.py" in execute
  183.             query = query % db.literal(args)
File "/usr/local/lib/python2.6/dist-packages/MySQL_python-1.2.4-py2.6-linux-i686.Egg/MySQLdb/connections.py" in literal
  264.         return self.escape(o, self.encoders)
File "/usr/local/lib/python2.6/dist-packages/MySQL_python-1.2.4-py2.6-linux-i686.Egg/MySQLdb/connections.py" in unicode_literal
  202.                 return db.literal(u.encode(unicode_literal.charset))

Exception Type: UnicodeEncodeError at /user/search
Exception Value: 'latin-1' codec can't encode characters in position 0-1: ordinal not in range(256)`

エラーが発生したとき、python Shellでテストを行いました。うまく機能しました。コードは、次のとおりです。

from apps.user.models import User user = User.get_by_name( '某人')。first()print user printuser.name某人

それで、それを私のhtmlページで機能させるために私は何ができますか?

14
jiank

ここでは、MySQLdbドライバーでMySQLを使用していると想定しています。

MySQLdbドライバーで使用されるデフォルトのエンコードはlatin-1であり、文字セットをサポートしていません。 MySQLdbを介してデータベースと通信できるようにするには、UTF-8(またはその他ですが、UTF-8が最も一般的です)を使用する必要があります( http://docs.sqlalchemy.org/en/を参照) rel_0_8/dialects/mysql.html#unicode )。

このようなことを行うには、次の行でエンジンを作成します。

create_engine('mysql+mysqldb://USER:@SERVER:PORT/DB?charset=utf8', encoding='utf-8')

sqlalchemy.engine.url.URLクラスを使用してエンジンURLを作成し、それをcreate engine関数に送信することもできます。設定ファイルに設定があると便利だと思います。

import sqlalchemy.engine.url as url

engine_url = url.URL(
    drivername='mysql+' + cfg['MYSQL_PYTHON_DRIVER'],
    Host=cfg['MYSQL_Host'],
    port=cfg['MYSQL_PORT'],
    username=cfg['MYSQL_USER'],
    password=cfg['MYSQL_PWD'],
    database=cfg['MYSQL_DB'],
    query={'charset': 'utf8'}
)
db = create_engine(engine_url, encoding='utf-8')

お役に立てば幸いです。

36

スタックトレースに基づいて、MySQL Pythonを使用しており、Unicodeエンコーディングがオンになっています。これは、エンコードを実行しているためです。したがって、互換性のあるエンコーディングを指定する必要があります(これは、 MySQLdb DBAPI、SQLalhcemyはそれらを通過させるだけです):

create_engine('mysql+mysqldb:///mydb?charset=utf8&use_unicode=1')

http://docs.sqlalchemy.org/en/rel_0_8/dialects/mysql.html#unicode

3
zzzeek