ValueError: unsupported format character ‘Y’ (0x59) at index 51

MySQL+Pythonのエラー

ValueError: unsupported format character 'Y' (0x59) at index 51

このようなエラーが出るときの対応。


import MySQLdb
ymd="2017-05-19"

con=MySQLdb.connect(user="root",password="",host="localhost",db="test")
cur=con.cursor()
cur.execute("set names utf8")   # 文字化け対応
cur.execute("select * from test_table where date_format(ymd,'%%Y-%%m-%%d')=%s",(ymd,))
for row in cur.fetchall():
  print(row[0])

これだと上記エラーが発生します。

ここに解決策が載っていました。

ポイントはsql文の文字列をformat()するだけ


import MySQLdb
ymd="2017-05-19"

con=MySQLdb.connect(user="root",password="",host="localhost",db="test")
cur=con.cursor()
cur.execute("set names utf8")   # 文字化け対応
cur.execute("select * from test_table where date_format(ymd,'%%Y-%%m-%%d')=%s".format(),(ymd,))
for row in cur.fetchall():
  print(row[0])

load data local infile で文字化け対応

MySQLのload data local infileの際に文字化けする対策
ポイントはcharacter_set_databaseパラメタを確認することでした

環境

  • MySQL 5.5.43
  • 文字コード utf8

テーブル作成

まずはUTF8でテーブルを作成します。なおデータベースエンジンにはInnodbを使用します

create table TEST(
  id integer not null,
  name varchar(32) null,
  kana varchar(32) null
)engine=innodb default charset=utf8
;

ファイルの確認

インポートするファイルの文字コードをUTF8にします

$ head TEST.txt |nkf --guess
UTF-8 (LF)

UTF8でない場合には以下のコマンドで変換します

$ cat TEST.txt |nkf -w > TEST.txt.utf8
$ mv TEST.txt.utf8 TEST.txt

データベースの設定

データベースの設定を確認します。なおmysqlコマンド起動時に –local-infile をつけないとload data local infileコマンドがエラーになります。5.5あたりからの仕様変更でしたっけ?

$ mysql -uroot -hlocalhost -ppassword --local-infile=1
mysql> show global variables like "character%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)


mysql> set global  character_set_database=utf8;

一時的に変更したい場合にはこちらのコマンドです。このセッションのみで有効です

mysql> set character_set_database=utf8;

インポート

それではインポートします

mysq>load data local infile "/path/to/file/TEST.txt" into table TEST;

これで文字化けせずインポートできます

load data local infile時にMySQLで文字化けしてしまう

ちょっとハマったのでメモ

  • MySQL5.1.71
  • CentOS 5.2

MySQLでSjisファイルをロードするときに文字化けしてしまう

$ export LANG=ja_JP.sjis	# 効かない
$ mysql -uroot -hhost -ppass --local-infile=1 --default-character-set=sjis << Eof
use mysql
;
set names sjis	# 効かない
;
load data local infile "sjis.txt" into table table
;
Eof

悩みました

$ mysql -uroot -hhost -ppass --local-infile=1 --default-character-set=sjis << Eof
use mysql
;
set character_set_database=sjis	 # これでOK
;
load data local infile "sjis.txt" into table table
;
Eof

どうやらDBの設定がおかしかったようです

mysql> show global variables like "%charac%";
+--------------------------+--------------------------------------------------------------+
| Variable_name						| Value																												|
+--------------------------+--------------------------------------------------------------+
| character_set_client		 | latin1																											 |
| character_set_connection | latin1																											 |
| character_set_database	 | latin1																											 |
| character_set_filesystem | binary																											 |
| character_set_results		| latin1																											 |
| character_set_server		 | latin1																											 |
| character_set_system		 | utf8																												 |

これを変更するにはmy.cnfに設定し再起動すればOKです

$ vi my.cnf
[mysql]
default_character_set = sjis
[mysqld]
character-set-server=sjis

グローバル変数もこうなります

mysql> show global variables like "%charac%";
+--------------------------+----------------------------+
| Variable_name						| Value											|
+--------------------------+----------------------------+
| character_set_client		 | sjis											 |
| character_set_connection | sjis											 |
| character_set_database	 | sjis											 |
| character_set_filesystem | binary										 |
| character_set_results		| sjis											 |
| character_set_server		 | sjis											 |
| character_set_system		 | utf8											 |

ruby-mysqlで文字コード指定

rubyでMYSQLにつなぐ際にMySQL/Rubyを使っていたのですが、どうやら開発が止まってしまったらしくruby1.9には非対応とのこと

https://github.com/tmtm/ruby-mysql

こちらからruby-mysqlなるものをダウンロード。

ちなみにプロキシ越しのgemではうまくいきませんでした

# gem install ruby-mysql
WARNING:	Error fetching data: too many connection resets (http://rubygems.org/latest_specs.4.8.gz)
ERROR:	Could not find a valid gem 'ruby-mysql' (>= 0) in any repository
ERROR:	Possible alternatives: ruby-mysql

とりあえずインストール

# ruby setup.rb
  • 日本語

mysqlにはSjisでデータが入っており、クライアントがutf-8の場合には以下のように書く必要があります

#/bin/env ruby -w -Ku
# -*- coding=utf-8 -*-
client=Mysql.connect("localhost","root","pass","dbname")
client.charset="utf8"
res=client.query("select id,name from IdTable")
res.each{|r|
p r
}