概要
- Ruby2.3で「
'
」や「"
」が含まれるCSVファイルをCSVモジュールを使ってMySQLに入れる場合、以下の2点の注意が必要。
- CSVファイルに「”」が入っていると、ファイル読み込み時に「
"
」が入っていると Illegal Quoting
エラーになるので、quote_char: "\x00"
を指定する
- Ruby 2.4 からは、CSVモジュールに
liberal_parsing
オプションが使えるが、2.3以前では使えない
- 普通はファイル内に存在しないはずの
"\x00"
を指定するのがミソ
- 「
'
」はMySQLに入れる時に「\\'
」にエスケープ処理をする必要があるので、gsubで置換する
環境
- ruby 2.3.8p459 (2018-10-18 revision 65136) [x86_64-linux]
サンプルコード(TSVファイル用)
require "csv"
summary = {}
CSV.foreach("myfile.tsv", col_sep: "\t", quote_char: "\x00", encoding: "UTF-8", headers: :first_row) do |row|
summary = {
:col1 => row[0].to_s,
:col2 => row[1].to_s.gsub("'", "\\\\'"),
:col3 => row[2].to_f,
}
puts summary
# MyModel.replace(summary)
end
テストデータ(TSV形式)
col1 col2 col3
homemade cookies Aunt Stella's cookies 123
nickname Louis "Satchmo" Armstrong 456
yard-pound system 4' 10" 147.32
yard-pound system 2 4′ 10″ 147.32
実行して表示を確認
{:col1=>"homemade cookies", :col2=>"Aunt Stella\\'s cookies", :col3=>123.0}
{:col1=>"nickname", :col2=>"Louis \"Satchmo\" Armstrong", :col3=>456.0}
{:col1=>"yard-pound system", :col2=>"4\\' 10\"", :col3=>147.32}
{:col1=>"yard-pound system 2", :col2=>"4′ 10″", :col3=>147.32}
補足
-
\\\\
が\\
に置換されて\
に置換される所がややこしい。