web-dev-qa-db-ja.com

SQLAlchemyの「create_engine」で「charset」と「encoding」を使用する方法(pandasデータフレームを作成するため)?

Charsetと encodingSQLAlchemyで機能する方法に非常に混乱しています。 charsetsとencodings の違いを理解しています(そして読みました)。そして encodingの履歴 をよく理解しています。

MySQLのテーブルをlatin1_swedish_ciWhy?thisのために可能です。 pandas dataframeに適切な文字(奇妙なシンボルではない)を取得する)を作成する必要があります。最初、これはコード内にありました:

_connect_engine = create_engine('mysql://user:[email protected]/db')
sql_query = "select * from table1"
df = pandas.read_sql(sql_query, connect_engine)
_

_Š_文字(_u'\u0160'_ユニコードに対応しますが、代わりに '\ x8a'を取得します)で問題が発生し始めました。私はこれがうまくいくと思っていました:

_connect_engine = create_engine('mysql://user:[email protected]/db', encoding='utf8') 
_

しかし、私は_'\x8a'_を引き続き取得します。これは、エンコーディングパラメータのデフォルトが_utf8_であることを考えると、理にかなっています。それで、私は_encoding='latin1'_を試して問題に取り組みました:

_connect_engine = create_engine('mysql://user:[email protected]/db', encoding='latin1')
_

しかし、私はまだ同じ「\ x8a」を取得します。明確にするために、どちらの場合でも(_encoding='utf8'_および_encoding='latin1'_)、mystring.decode('latin1')は実行できますが、mystring.decode('utf8')は実行できません。

次に、接続文字列のcharsetパラメータ、つまり_'mysql://user:[email protected]/db?charset=latin1'_を再発見しました。そして、文字セットとエンコーディングの可能なすべての組み合わせを試した後、私はこれがうまくいくことを発見しました:

_connect_engine = create_engine('mysql://user:[email protected]/db?charset=utf8')
_

接続文字列でcharsetを正しく使用する方法、および_create_engine_?encodingパラメータを正しく説明できると助かります

9
toto_tico

encoding は、エンコード/デコードに使用されるコーデックですSQLAlchemy内。ドキュメントから:

DBAPIがPython unicodeオブジェクトをサポートしていないことが検出されたシナリオでは、このエンコードを使用して、ソース/宛先のエンコードが決定されます。これは未使用DBAPIがユニコードを直接処理する場合。

[...]

Python unicodeオブジェクトに対応するようにシステムを適切に構成するには、Unicodeを適切に処理するようにDBAPIを構成する必要があります[...]

mysql-pythonはユニコードを直接処理するため、この設定を使用する必要はありません。

charsetは、mysql-pythonドライバーに固有の設定です。 ドキュメント から:

この文字セットは、接続用のクライアント文字セットです。

この設定は、サーバー上の つの変数 、具体的には character_set_results 、これは興味のあることです。設定すると、文字列はunicodeオブジェクトとして返されます。

これは、データベースにlatin1でエンコードされたデータがある場合にのみ適用されることに注意してください。 utf-8バイトをlatin1として保存している場合は、代わりにencodingを使用するほうがよいでしょう。

5
univerio

encodingパラメータが正しく機能しません。

したがって、@ doruが this link で述べたように、接続文字列の最後に?charset=utf8mb4を追加する必要があります。このような:

connect_string = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8mb4'.format(DB_USER, DB_PASS, DB_Host, DB_PORT, DATABASE)
8
IT man

私も同じ問題を抱えていました。 URLの最後に?charset = utf8mb4を追加しました。

これが私のものです:

変更前

SQL_ENGINE = sqlalchemy.create_engine('mysql+pymysql://'+MySQL.USER+':'+MySQL.PASSWORD+'@'+MySQL.Host+':'+str(MySQL.PORT)+'/'+MySQL.DB_NAME)

SQL_ENGINE = sqlalchemy.create_engine('mysql+pymysql://'+MySQL.USER+':'+MySQL.PASSWORD+'@'+MySQL.Host+':'+str(MySQL.PORT)+'/'+MySQL.DB_NAME + "?charset=utf8mb4")
4

これは私にとってはうまくいきます。

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

db_url = {
    'database': "dbname",
    'drivername': 'mysql',
    'username': 'myname',
    'password': 'mypassword',
    'Host': '127.0.0.1',
    'query': {'charset': 'utf8'},  # the key-point setting
}

engine = create_engine(URL(**db_url), encoding="utf8")
2
W.Perrin