sql >> データベース >  >> RDS >> Mysql

SQLAlchemyでUnicode省略記号をmySQLテーブルに正しく挿入するにはどうすればよいですか?

    エラーメッセージ

    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')
    

    セクションデータベースURL SQLAlchemyのドキュメントの中で、 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接続文字セットが要求するものとは異なる方法でクエリ文字列をエンコードすると、エンコードの不一致が発生し、テキストが間違って保存される可能性があることに注意してください。



    1. MySQLに重複レコードを挿入しないようにする方法

    2. MicrosoftSQLServerエラー18456のトラブルシューティング

    3. MySQLをDoctrineQueryBuilderに変換します。 IFおよびCONCATに関する問題。または選択時のサブクエリの別のアプローチ

    4. 1日を日時フィールドに一致させるにはどうすればよいですか?