Python3+MySQLのWindowsでの使い方。Unicodeエラー・日本語文字化け対策。
Python3+MySQLをWindowsで使ったらハマった。Unicodeエラー・日本語文字化け・・・。
インターネットからスクレイピングしてきたデータをMySQLに保存して別のプログラム等で使うことを検討していたのですが、Windows環境+Python3+MySQLで実装しようとしたところ、日本語の文字化けやUnicodeエラーで躓きました。
主に以下のような問題やエラーです。
- Insert処理で「UnicodeEncodeError:latin-1 codec can’t encode characters in position」のエラーが発生
- MySQLのテーブルにデータを保存することは出来たが、中身を覗いたら日本語が文字化け
Python3をWindowsで使っている人は同じ問題で悩んだことがあるかもしれません。また、本記事を読んでいる方は、現在進行形で悩んでいるかもしれません。
昨今はLinux環境を使うことも増えネット上はLinux前提のTIPSが溢れており、Windows環境下でのトラブル解決情報を探すのに苦労するようになりました。そこでWindows利用者で同じように悩んでいる方のために、今回ハマった点と対応方法を本記事に整理しました。
環境
- Windows 10 Pro
- MySQL Server 5.7
- Python 3.6.4
- (ライブラリ) mysqlclient 1.3.12
MySQLの設定を確認。Windows環境では「my.ini」を修正して日本語文字化けに対策する。
Windows環境でMySQLをインストールすると、「my.ini」のデフォルトの設定では、default-character-setの文字コードが「utf8」となっている。これを「cp932」に修正しておく。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # CLIENT SECTION # ---------------------------------------------------------------------- # # The following options will be read by MySQL client applications. # Note that only client applications shipped by MySQL are guaranteed # to read this section. If you want your own MySQL client program to # honor these values, you need to specify it as an option during the # MySQL client library initialization. # [client] # pipe # socket=0.0 port=3306 [mysql] no-beep default-character-set=cp932 |
ここを修正していないと何を入れても文字化けになってしまいます。MySQLをインストールしたら、すぐに設定を修正しましょう。
Windows環境で「my.ini」の設定ファイルは「C:\ProgramData\MySQL\MySQL Server XX」のフォルダにインストールされている。「C:\Program Files\MySQL」を探し回っても見つからないので注意。
ライブラリmysqlclientのインストール(既にインストール済の方はスキップ)。
今回は「mysqlclient」というライブラリを使います。Python用のMySQLインターフェイスのライブラリになります。詳細は以下を参照ください。
https://pypi.python.org/pypi/mysqlclient
コマンドプロンプトからpip installで簡単にインストールすることができます。
1 | pip install mysqlclient |
SELECT/INSERT/UPDATEのサンプルコード。UnicodeEncodeErrorエラーへの対処ポイント。
注意点とSELECT/INSERT/UPDATEのサンプルコードを記載します。
ポイントはMySQLdb.connectの際に、以下のオプションを設定しておくことです。
- charset=’utf8′
- use_unicode=True
ここで「charset=’utf8’」を指定しておくことで、わざわざデータベース自体の文字コードを変更しなくても、データを登録することができます。むしろ、DBはutf8のままでOKでしょう。
後者の「use_unicode=True」の設定は、スクレイピングしてきたデータを登録する場合等、Unicodeのデータを扱う際には重要になります。環境の設定をキチンとしているにもかかわらず、「UnicodeEncodeError: 'latin-1’~」エラーが出る場合は、こちらを試してみてください。
私の場合はこの2つのオプションを設定することで、スクレイピング⇒DB登録⇒DB取得⇒文字出力まで、エラーも文字化けもすることなく実装することができました。
SELECT/INSERT/UPDATEのサンプルコードは以下のとおりです。
※事前にsampledbというデータベースに、sampletableテーブルというシンプルなテーブル(Id
, data
の2カラムのみ)を作成しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import MySQLdb # 接続とカーソル取得 con=MySQLdb.connect( user='XXXXX', passwd='XXXXX', host='localhost', db='sampledb', charset='utf8', use_unicode=True) cur=con.cursor() # insert文サンプル sql="insert into sampletable (`Id`, `data`) VALUES (%s, %s);" cur.execute(sql,(2,'サンプルデータ',)) con.commit() # update文サンプル sql="update sampletable SET `data`='サンプルデータ更新済' WHERE `Id`=%s;" cur.execute(sql,(2,)) con.commit() # select文サンプル sql="select Id, data from sampletable" cur.execute(sql) rows=cur.fetchall() forrow inrows: print(row) # 切断・終了 cur.close con.close |
mysqlclientはプレースホルダを使って、引数を指定可能ですので、こちらを使いましょう。なお、executeで値を指定する際に、末尾に「,」がないとエラーになりますので注意してください。
また、実際に使用する際には例外処理を忘れずに実装ください。