Ruby 2.3 で「’」や「”」が含まれるCSVファイルをMySQLに入れる

概要

  • 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}

補足

  • \\\\\\に置換されて\に置換される所がややこしい。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です