Cakephp3でCSVのデータをSeedで利用する
最近、巨大なCSVをSeedとして利用することがあり、そのさい行ったことをメモ程度にまとめていきます。
環境は以下です。
- PHP7.1
- CakePHP 3.4
最初のプログラム
1番最初に作成したプログラムでは、CSVをfopen関数で呼び出し、内容をループで取得しながらインサートしていました。
<?php use Migrations\AbstractSeed; class TestSeed extends AbstractSeed { public function run() { $table = $this->table('test'); $fp = fopen("seedファイルのパス", "rb"); while(($line = fgetcsv($fp)) !== false) { $insertData = [ 'data1' => (int)$data[1], 'data2' => (string)$data[2], ]; $table->insert($insertData)->save(); } } } ?>
Seedに使用するCSVファイルが複数ある場合に同じ処理を複数回書いていました。 関数化することで他のクラスでも使用できるようにしたかったため、Generatorを使用してCSVの読み込み処理を関数化しました。 Generatorを使用しようと思ったのは、メモリ効率が良さそうなのと、使ってみたかったからです。
Generatorを使った処理。
<?php use Migrations\AbstractSeed; class TestSeed extends AbstractSeed { public function run() { $table = $this->table('test'); foreach ($this->fileGetLines("seedファイルのパス") as $data) { $insertData = [ 'data1' => (int)$data[1], 'data2' => (string)$data[2], ]; $table->insert($insertData)->save(); } } public function fileGetLines($filepath) { $lines = []; $fp = fopen($filepath, "rb"); while(($line = fgets($fp)) !== false) { yield $line; } fclose($fp); } } ?>
Generatorを使用することで、処理がスッキリし読みやすくなりました。 また、変更後処理時間を測定した結果、Generatorを使用したほうが、若干処理が早くなりました。
バルクインサートする
先程までの処理は1行ずつ保存していたため、処理が遅かったです。 そのため、バルクインサートにすることで処理を早くしました。 バルクインサートにした結果2分かかっていた処理が、40秒ほどになりました。
<?php use Migrations\AbstractSeed; class TestSeed extends AbstractSeed { public function run() { $table = $this->table('test'); foreach ($this->fileGetLines("seedファイルのパス") as $data) { $insertData = [ 'data1' => (int)$data[1], 'data2' => (string)$data[2], ]; if (count($insertData) >= 1000) { $this->insert('test', $insertData); $insertData = []; } } $this->insert('test', $insertData); } public function fileGetLines($filepath) { $lines = []; $fp = fopen($filepath, "rb"); while(($line = fgets($fp)) !== false) { yield $line; } fclose($fp); } } ?>
参考にしたサイト
【t_wadaさんの講演】技術の学び方
2017/09/23にサポーターズコラボの和田さんの「【和田卓人氏特別講演】若手エンジニアに送る、"心構え"と"キャリア観"」の講演会に参加していました。
参加した経緯としては、友人からすすめられたのもあるのですが、最近テストを書くことが多くあり、調べた際にT和田さんの話が多く出ていたので興味を持ち参加することにしました。
講演を聞き和田さんがプログラマーとして生き続けるために必要なこととして「技術を学ぶことよりも、技術の学びかたを学ぶこと」がこの先プログラマーとして生きていく上で大切だと思ったのでまとめたいと思います。
今回の講演ではないですが、資料があったので参考までに以下に貼っておきます。
技術の学び方を学ぶとは
プログラミングの技術は小さなことから大きなことまで、毎日のように新しい技術が出て来る。そのため、出てきた技術をすべて学ぼうとすると、時間が足りなくなり、学習し続けることが難しくなるそうです。そうならないためには、技術の中で必要なものや必要でないものをしっかりと取捨選択していく必要があり、そのためには学び方自体を学ぶことで効率よく学ぶことができるそうです。
また、最新の技術を学ぶことは大切であるが、最新の技術を学ぶためにも過去に出された書籍から、捨てられた技術となぜ捨てられたかを知ることも大切だそうです。
技術の学び方とは
講演の中で技術の学び方として、以下の5つを上げていました。
- 技術書の読み方
- 手を動かして学ぶ
- 毎年1つの言語を学ぶ
- 身の回りをプログラムする
- アウトプットを行う
それぞれについて、不足している情報はありますが以下にまとめていきます。
技術書の読み方
和田さんが「技術書の内容をすべて読むのではなく、その本の中で必要な情報だけを学ぶようする。」とおっしゃられていました。また、本は個別に存在するのではなく、参照があり、それぞれが過去の本を参照していることを意識して読むことで、捨てられた技術がなぜ捨てられたのかを考える切っ掛けにもなり良いとおっしゃられていました。脳内にインデックスを貼るように、内容をすべて覚えるのではなく関連付けることで情報を引き出しやすくなるそうです。
手を動かして学ぶ
デールの円錐から、何かを学ぶときに、読んだだけの人は、90%の人が2週間後には内容を忘れてしまうが、実際に手を動かしてアウトプットした人は90%の人が内容を覚えている。そのため、本をただ読むだけでなく、写経するなど、学んだことをアウトプットにして、残すといいとおっしゃられていました。本を読んだときには、写経をするや、疑問に思ったことでもいいので、感想などもコメントとして書き込みながら読むとあとで見返したときに学びが多くなるとおっしゃられていました。
写経のやり方は和田さんのTwitterにあるので参考にすると良いそうです。
技術書の「写経」の方法。 1.ローカルで使える SCM を用意 2.「ほんたった」などで対象の本を固定 3.ひたすらサンプルコードを写して実行 4.実行するたびにコミット(コミットログにページ番号を含める) 5.疑問点があったらコミットログや本に書き込む 6.章ごとにタグを打つ
— Takuto Wada (@t_wada) February 12, 2010
毎年1つの言語を学ぶ
仕事で使っている以外の言語を学ぶことで、他の言語の考え方を知ることができ、仕事で使っている言語を書く際に良い影響を与えるとおっしゃられていました。
例えば副作用の多い言語を書いている人が、副作用をなくそうとする言語を学ぶと、副作用の多い言語を書くとに、副作用を少なくする書き方を意識してできるようになるなどです。
学習する言語を選ぶ基準としては、オブジェクト指向、動的型付け言語を使っていた人であれば、関数型、動的型付け言語を学ぶなど、今まで使っていた言語よりも少しだけ変化をつけると学習コストが下がりいいとおっしゃられていました。
1つの言語を学び終えたと思えるときは、APIやドキュメントを調べなくてもその言語で何かものが作れるレベルになれば学びの終着点だそうです。1年で1つここまで学ぶのは難しそうですが・・・
身の回りをプログラムする(うまくまとめられなかった)
身の回りで不便だと感じていることを技術を使用して便利にしていくといいそうです。アウトプットや効率化にもつながるのでいいそうです。
和田さんは今は子育てをハックするなどを行っているそうです。
感想になってしまうのですが、自分の好きなようにすることでモチベーションが保てると感じました。
アウトプットを行う
インプットしてアウトプットを繰り返す正のループを繰り返すことで情報が蓄積されていく。質よりも量を大切にし、量は質を量が凌駕するので量をこなすことが大切だと仰られていました。
アウトプットする場は、Twitterやブログ、github、1人で何か手を動かして作る。などなど、なんでもいいので始め習慣化ることが大切だそうです。
まとめ
今回の講演を聞いて、自分に1番足らないのはアウトプットを出すことだと感じました。今後は少しでもアウトプットを出すことを習慣づけられるようにしていきたいです。まずはブログを書くやTwitterでつぶやくなど小さなことからコツコツと習慣にしていく。
蛇足ですが、英語を学ぶことが大切だと仰られていた。技術が出てきたときに、1番最初に目にするのは英語で書かれた文章なので。学ぶことで得することしかないそうです。
英語が苦手なので逃げないようにしたい(小並感)。
和田さん最初はネット上の情報を見ると怖い印象でしたが、そんなことはなく優しい印象でした。スタンドが怖いだけでした。
我が家のペットの話
我が家のペット
うちの我が家には猫(拾った)が一匹います。
下のふてぶてしい顔をしてるやつです。
飼うようになった経緯は私が小学校の頃に、家に帰ったときに、妹とその友達が猫を拾ってきていました。
妹に拾ってきた場所を聞くと、
車庫の中の段ボールに入っていたそうです。
人の家の車庫に勝手に入って拾われるとは...なかなか運のいいやつです。
その後10数年がたち、色々なことがありました。
ときには首輪に首を閉められ首を縫ったり、1ヶ月行方不明になったり、肝臓を悪くして入院したり。
行方不明になった話が、特に大きなことだったので紹介できればと思います。
猫が行方不明になった話
猫が失踪したのは、春だったと思います。いつもならご飯の時間に帰ってくるのに、その日は帰って来ませんでした。
3日位して、張り紙を作り配って探したのですが、見つかる気配がありませんでした。
ふと考えて見ると、猫が失踪した日に宅配便が来ており、そのトラックに乗ったのでは...と考えた妹が電話したところ、35キロくらい離れた場所でトラックの荷台を開けたときに猫が飛び出して行ったと運転手さんが話してくれました。
それを聞いてその場所に探しに行ったのですが、見つからず...
何度か訪れたときに、そこにはやせ細った体で、元気に子供を追いかける猫の姿が!
その場で拘束し家に連れ帰りました。
見つかってよかった反面、はじめからトラックに乗らないでほしいと思いました。
だいたい死んでると言われるで
最近だいたい死んでる
社会人になってから、よく目が死んでいると言われるようになりました。
自分では明るく!楽しく!元気よく!を意識していたつもりになっていたのですが、目は死んでいたようです。
目が死んでいる人を見たことがなかったので、始めた会う目が死んだ人が自分だったと驚きました。
個性があるっていいことですね。
少しでも生き生きとしたい
だいたい死んでいると言われるので、少しでも生き生きするためにブログを始めてみました。
このブログを通して目が生き生きした人になることができたらいいのかと思っています。
何を書くかは未定、いつ書くかも未定。
程々にやったことなどを書いていけるといいと思います。