CSVデータの読み込み

アプリを作る際に材料リストをGoogleスプレッドシートで作成しました。 データの数が多いので、自動で取り込む方法を検索し、ファイルをCSV変換してRubyでデータを取り込む方法を発見しました。 CSVデータを使おうと思ったのはGoogleスプレッドシートから簡単に変換できるからです。

CSV読み込みのメソッドについて調べると以下2つが見つかりました。

CSV.readメソッド

指定パスのCSVファイルの内容を変数の中に一気に読み込むメソッド

 https://docs.ruby-lang.org/ja/latest/class/CSV.html#S_READ

CSV.foreachメソッド

 CSVファイルから1ずつ行(データ)を読み込むため、大量のデータが格納されたCSVファイルを読み込む時に向いているメソッド

データの量が多かったのでCSV.foreachメソッドを使用することにしました。

実際の方法についてはこちらを参考にさせていただきました。

rake db:seedを使った初期データの投入 - Ruby on Rails入門

以下がコードとCSVデータの抜粋

require "csv"

CSV.foreach('db/menutable_app_food.csv', headers: true) do |row|
    Food.create(
    name: row['name'],
    ancestry: row['ancestry'],
    keyword: row['keyword'],
    unit: row['unit']
    )
end

https://scrapbox.io/files/6302e2c309c2a20020cdd64f.png

実行してみた結果

なぜか、200件あるうちのデータが9件のみしか取り込めていませんでした。

リトライ⑴

リトライする前に行ったこと

何したらいいのかわからなかったのでひとまず再度参考にした

rake db:seedを使った初期データの投入 - Ruby on Rails入門

を見ながらCodeを確認。

データベース上のカラム名にズレがないか、タイプミスないかを確認しました。

再度実行しましたが結果は変わらず。

リトライ⑵

リトライする前に行ったこと

⑴データベース上のテーブルの再設定

カラムの設定が合っていないかもしれないと考えて、一度データベース上のデータを全削除し、テーブルも削除。再度テーブルを作成しました。

⑵コード一度削除し、再度書き直す

自分の目で確認はしましたが、タイピングミスがあるのかもしれないと考え、念の為コードを再度書き直しました。

再度実行しましたが結果は変わらず。

その後もコードを少しずつ書き換えてリトライ②の工程を2〜3回繰り返しました。

リトライ⑶

リトライする前に行ったこと

⑴「ruby csv取り込み できない」で検索して対処法を探す

何らかのエラーメッセージが出てきてるパターンがほとんどで私と同じようなパターンは見つかりませんでした。 ただ、いろいろなサイトを見て、CSVデータはコンマでデータを区切ったものであり、エクセルからCSVデータに変換するときに文字化けするケースがあるとのことを発見しました。

CSVデータを確認

文字化けしていてデータが読み取れないのかと思いCSVデータを確認することにしました。取り込めたデータとそれ以外のデータを比較しましたが、コンマの数も同じ、文字化けもありませんでした。

CSVデータの再作成

一応やっておくのが無難かなと思いエクセルから再度CSV変換し、ファイルを作成。前のCSVデータと入れ替えました。

再度実行すると、成功!

全部データが取り込めました!

原因は何だったのか?

CSVデータを入れ替えたことで成功したので、成功したファイルと失敗したファイルを比較してみました。

比較

カラム名の部分、1つコンマが多い。 なぜ多くなってるのか、原因はわかりませんでした。 (全く同じスプレッドシートから作成したcsvファイルは問題なかったです。)

カラムの数が多くなるので、ひとつづつデータの値がずれる

ancestryのカラムに文字列のデータが送られたためエラーが発生、ancestryがnilとなっていたデータのみが取り込めた

結果 200件あるうちのデータが9件のみ取り込めた

しかし、取り込めたデータも確認するとancenstry:nilとなっていてカラムの内容もずれてましたので、1つとして成功はしてませんでした。

今回の学び

⑴エラーメッセージないと困ること

ここ変だよ!って教えてくれるエラーメッセージってありがたいものだったんだなと思いました。

調べたところ、create!を使用するとエラーメッセージが表示されるので、今後は活用していきたいと思います。

ちなみに今回のケースもcreate!を使用すると

ActiveRecord::RecordInvalid: Validation failed: Ancestry is invalid

とエラーメッセージが出ました。

トラブルシューティング

トラブルが起きた時に私は闇雲に全部見てみるとか書き換えるなどをしてしまいます。調べてみた所、巷には以下linkのような基本的なトラブルシューティングに向き合うときに使える考え方があるようです。

トラブルシューティングのための思考のヒント - Qiita

今回の場合は、問題の切り分けとして、

  • データが悪い
  • プログラムが悪い

の大きく2つの方向性で原因調査にあたれると考えられるので、今後はこうした切り分けを行った上で解決していけたらとおもいます。