エラーメッセージ
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2026'
in position 35: ordinal not in range(256)
一部のPython言語コードが文字\u2026
を変換しようとしていることを示しているようです Latin-1(ISO8859-1)文字列に変換すると、失敗します。当然のことながら、その文字は U + 2026 HORIZONTALELLIPSIS<です。 / code>
、ISO8859-1では同等の文字は1つもありません。
クエリ?charset =utf8
を追加して問題を修正しました SQLAlchemy接続呼び出しで:
import sqlalchemy
from sqlalchemy import create_engine, MetaData, Table
db = create_engine('mysql://user:[email protected]/db?charset=utf8')
セクション mysql
で始まるURLが示されています mysql-python
を使用してMySQL方言を示します ドライバー。
次のセクション、カスタムDBAPI connect()引数 、クエリ引数が基になるDBAPIに渡されることを示します。
では、 mysql-python
は何ですか?
パラメータのドライバmake{charset:'utf8'}
?セクションcharset
について述べています 属性「...存在する場合、接続文字セットは、等しくない場合、この文字セットに変更されます。」
接続文字セットの意味を確認するには、を参照してください。 10.1.4。接続文字セットと照合 MySQL5.6リファレンスマニュアルの。簡単に言うと、MySQLは、着信クエリをデータベースの文字セットとは異なるエンコーディングとして解釈し、返されたクエリ結果のエンコーディングとは異なるものとして解釈することができます。
報告されたエラーメッセージはSQLエラーメッセージではなくPythonのように見えるため、SQLAlchemyまたはmysql-pythonの何かがクエリをデフォルトの接続エンコーディングである latin-1
> 送信する前に。これがエラーのトリガーです。ただし、クエリ文字列?charset =utf8
connect()
で callは接続エンコーディングを変更し、 U + 2026 HORIZONTAL ELLIPSIS
通り抜けることができます。
更新: また、「charsetオプションを削除してから、.encode('cp1252')を使用して説明をエンコードすると、問題なく処理されます。省略記号はcp1252で処理できますが、ユニコードでは処理できませんか?」
エンコーディングcp1252
持っている
バイト値\x85
の水平方向の省略文字 。したがって、 U + 2026 HORIZONTAL ELLIPSIS
を含むUnicode文字列をエンコードすることができます。 エラーなしでcp1252に。
Pythonでは、Unicode文字列とバイト文字列が2つの異なるデータ型であることも忘れないでください。 MySQLdbには、SQL接続を介してバイト文字列のみを送信するポリシーがある可能性があると推測するのが妥当です。したがって、Unicode文字列として受信したクエリをバイト文字列にエンコードしますが、バイト文字列として受信したクエリはそのままにします。 (これは推測です。ソースコードは調べていません。)
投稿したトレースバックの最後の2行(エラーが発生した場所に最も近い)は、メソッド名literal
を示しています。 、続いて unicode_literal
。これは、MySQLdbが受け取ったクエリをUnicode文字列としてバイト文字列にエンコードしているという理論を支持する傾向があります。
クエリ文字列を自分でエンコードする場合、このエンコードを異なる方法で行うMySQLdbの部分をバイパスします。ただし、MySQL接続文字セットが要求するものとは異なる方法でクエリ文字列をエンコードすると、エンコードの不一致が発生し、テキストが間違って保存される可能性があることに注意してください。