![[PyMySQL] ValueError : unsupported format character 'Y' (0x59)](https://itips.krsw.biz/wp-content/uploads/2019/11/programming_man_unsupport_char_en-640x582.png)
ValueError : unsupported format character 'Y' (0x59)
pymysqlライブラリを利用してSQLを実行する際に起こることがあるこのエラー。
今回はこの unsupported format character 'Y' の原因と対策について紹介する。
エラー現象
pd.read_sql メソッド実行時に DATE_FORMAT(column, '%Y-%m-%d') のような %Y-%m-%d を含むselect文を実行すると unsupported format character 'Y' (0x59) のエラーになってしまう。
print("Connect to DB")
conn = pymysql.connect(user="root", password="", host="localhost", database="test")
print("Select data")
sql = "SELECT DATE_FORMAT(col_datetime, '%Y-%m-%d') FROM test.table_datetime where col_date = %s"
df_datetime = pd.read_sql(sql, conn, params=["2019-11-18"])
print(df_datetime)
# unsupported format character 'Y' (0x59)
unsupported format character 'Y' を直訳すると「サポートされていないフォーマットの文字'Y'」となるので %Y-%m-%d の部分が怪しい。
エラー原因と対策

ではエラーの原因が何なのかというと、pymysqlが %Y-%m-%d を %s のような 後でパラメータ値で置換する部分 として認識してしまう為、「サポートされていないフォーマット」としてエラーになってしまう。
ターミナルやSQLを実行するためのアプリ上では DATE_FORMAT(column, '%Y-%m-%d') は問題無く実行できるので、この手の「PythonからSQLを実行する場合のお作法」に起因するエラーは気づきにくい。
エラーを回避する為にはSQL中の %Y-%m-%d を一旦 %s とし、後で代入するパラメータ側に%Y-%m-%d を指定する。
sql = "SELECT DATE_FORMAT(col_datetime, %s) FROM test.table_datetime where col_date = %s" df_datetime = pd.read_sql(sql, conn, params=["%Y-%m-%d","2019-11-18"]) print(df_datetime) # DATE_FORMAT(col_datetime, '%Y-%m-%d') # 0 2019-11-18 # 1 2019-11-18
ちなみにSQL中に %Y-%m-%d のみ存在する場合はエラーにはならない。
つまり %Y-%m-%d と %s が混在していると %Y をSQLではなくパラメータとして認識してしまうので処理できずにエラーになる。
sql = "SELECT DATE_FORMAT(col_datetime, '%Y-%m-%d') FROM test.table_datetime" df_datetime = pd.read_sql(sql, conn) print(df_datetime) # DATE_FORMAT(col_datetime, '%Y-%m-%d') # 0 2019-11-18 # 1 2019-11-18
まとめ
unsupported format character 'Y' (0x59)が発生する原因は、SQL中に%Yと%sが混在しているから- 回避方法はSQL中の 
%Yも一旦%sとし、pd.read_sql等のSQL実行時にparams=["%Y-%m-%d"]で指定する。 
   						               		 

