2016年3月1日火曜日

JQueryのDataTablesプラグインを使って、データをテーブル形式で画面に表示してみる【Ajax連携①】

こんにちは、井下です。

いよいよ花粉が飛び交う季節になり、去年買った花粉用の眼鏡を使ってますが、効果あるんですかねコレ…?
結局目が痛いような痒いような感じになってます。


前回はJQueryのDataTablesプラグインについて紹介しました。
今回はAjax連携について、その手順を紹介していきます。

Ajax連携

DataTablesプラグインは元々Ajaxの利用が想定されているので、単純にファイル内のjson形式データを読み込むくらいであれば、簡単に実装できます。

例として、次のようなHTMLファイルを作成後、ブラウザで開いてみてください。
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/s/dt/dt-1.10.10/datatables.min.css"/>
      <script src="http://code.jquery.com/jquery-2.2.0.min.js"></script>
      <script type="text/javascript" src="https://cdn.datatables.net/s/dt/dt-1.10.10/datatables.min.js"></script>
  </head>
  <body>
    <table id="books_table">
      <thead>
        <tr>
          <th>Title</th>
          <th>Author</th>
          <th>Genre</th>
          <th>Page</th>
          <th>Publication</th>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>
  </body>
  <script>
    $(document).ready(function() {
      $('#books_table').DataTable({
        "ajax": {
          url: "data.json",
        }
      });
    });
  </script>
</html>


こんな感じの画面が開きました。


テーブルのデータ部分が"Loading..."となっているはずです。

上記のHTMLでは、DataTablesプラグインがAjax連携で利用している設定を黄色字にしています。
そのなかで「url: "data.json"」と書かれていますが、これは「"data.json"内のデータをAjax通信により取得して表示する」ことを示します。
まだ"data.json"を作成していないので、当然読み込みには失敗します。

では、HTMLファイルと同じディレクトリに"data.json"ファイルを作成してみます。
{
  "data": [
    [
      "異類婚姻譚",
      "本谷 有希子",
      "小説",
      168,
      "2016-01-21"
    ],
    [
      "パーフェクト Ruby on Rails",
      "すがわらまさ のり,前島真一,近藤宇智朗,橋立友宏",
      "技術書",
      432,
      "2014-06-06"
    ],
    [
      " すごい家事 人生の「掃除の時間」をグッ と縮める",
      "松橋 周太呂",
      "生活",
      207,
      "2015-12-04"
    ],
    [
      "おやすみ、ロジャー 魔法のぐっすり絵本",
      "カール=ヨ ハン・エリーン",
      "絵本",
      32,
      "2015-11-12"
    ],
    [
      "死んでいない者",
      "滝口 悠生",
      "小説",
      152,
      "2016-01-28"
    ],
    [
      "マネジメント 基本と原則",
      "P.F.ドラッカー",
      "経済・ビジネス",
      320,
      "2001-12-14"
    ]
  ]
}

作成後、ブラウザを更新してみると、"data.json"のデータがテーブル形式で表示されているはずです。




表示されていない場合、次のようなケースが考えられます。

  • "data.json"を作成しても、テーブルが"Loading..."のまま
    多くの場合、データの読み込み失敗が原因です。これまでの流れで起こりやすいのは、以下の2点かと思います。

    1."data.json"がHTMLファイルと同ディレクトリに存在しない
     読み込み対象を相対パスで指定しているので、"data.json"がHTMLファイルと同じディレクトリに存在しなければ、読み込みエラーとなります。

    2.ブラウザによるローカルリソースへのアクセス禁止
     一部のブラウザ(Chrome等)では、ローカルリソースへのアクセスを禁止しているようで、"data.json"がローカル環境にある場合、ブラウザが"data.json"の読み込みを阻害している可能性があります。ブラウザごとにアクセス禁止を緩和する設定がありますが、ブラウザにこだわりがなければ、別のブラウザで表示を確認してみましょう。(FireFoxは表示できました)
  • テーブルにデータは表示されたが、文字化けしている
    jsonはデフォルトでUTF-8でエンコードされているので、"data.json"ファイルの文字コードを"UTF-8"にしておけば、文字化けは解消するはずです。

2016年2月15日月曜日

JQueryのDataTablesプラグインを使って、データをテーブル形式で画面に表示してみる

こんにちは、井下です。


今回はDataTablesというプラグインを使い、データをテーブル形式で画面に表示してみます。
ちなみにデータを画面に表示するためにRailsを利用していますが、Rails自体の説明は省略しますので、あしからず。

DataTablesとは

DataTablesはjQueryのプラグインとして提供されるオープンソースで、画面上でデータをテーブルの形式として表示するものです。
Ajaxで動的にデータを取得することもでき、テーブル表示実装の手間を大いに軽減してくれます。

公式URL : https://www.datatables.net/




Railsでの一覧(indexアクション)の初期表示

Railsで表示するデータと画面を作成します。
今回は例として"library"アプリケーションを作成し、scaffoldジェネレータで"Books"モデルおよびコントローラ、ビュー等を自動生成しました。

※ Booksモデル作成時に、以下のカラムを設定しました。
カラム名 概要
title 本のタイトル string
author 本の著者 string
genre 本のジャンル string
page 本のページ数 integer
publication 本の発効日 date


その後画面を介して本の情報を入力した一覧画面(indexアクション)はこんな感じになります。



自動生成される画面なので、データが並べてあるだけの状態です。
この画面をDataTablesを使い、きちんとしたテーブル形式でデータを表示していきます。


2016年1月27日水曜日

AWSの触れ初めに手間取ったこと・疑問に感じたことのまとめ

こんにちは、井下です。

ここ最近の冷えとともに空気が乾燥してきたのか、ほぼ1日1回静電気にやられております。ドアノブに触れるのが怖いです…。

今回はAWSについてのお話になります。

ただし、堅牢なセキュリティ設計や、厳密な運用計画のように難しい話ではなく、私がAWSに触れ始めた頃に、手間取ったことや、疑問に感じたことについてのお話です。

なかでも特に手間取ったこと、疑問に感じたことを以下の4つに絞って説明していきます。

  • 「無料利用枠」ってあるけど、本当に無料で使えるの?
  • とりあえずAWSで仮想サーバを立てたいけど、サービスがたくさんあってどれを使えばいいのか分からない
  • 作った覚えがないリソースが作成されている
  • ファイアウォールの設定が効かない

「無料利用枠」ってあるけど、本当に無料で使えるの?


まずAWSの利用前に、料金はどれくらいか調べるうちに、「無料利用枠」があることに行き着く人は多いと思います。

このサービスがここまでの利用なら無料になりますよ、と提示してくれているのですが、AWSで提供しているサービス内の構成が分かっていない段階だと、理解することがかなり難しいです。

利用目的がとりあえず仮想サーバ欲しい! くらいであれば、気をつけるのは以下の点でしょう。
  • 固定IP(Elastic IP アドレス)を割り当てている仮想サーバが停止していると、停止している時間に応じて課金される
    ※ 固定IPを解放すれば課金されなくなりますが、一度解放した固定IPと同じIPアドレスを取得できるとは限りません
  • 稼動させるストレージの総容量が一定以上だと、容量に応じて課金される

利用目的によって、課金されるところが変わってくるので、分かる人がいればまず相談してみるのが一番良いです。

業務利用で予算がそこまでガチガチに定まっていないのであれば、まずは使ってみてからどれくらいかかったかを見てみるのも一つの手ではあります。
AWSではどのリソースのどこで課金されているのかが見えるようになっているので、コストを抑えるための判断材料は提供されています。





2016年1月13日水曜日

Embulkの設定ファイルをLiquidに対応させて、環境変数を参照させる

1月も中旬に入り、少し遅くなりましたが、明けましておめでとうございます。
私個人は新年早々、生もので当たるハメになりましたが、A-AUTO 50は元気ですので、今年もよろしくお願いいたします。


2016年の1回目は、前年末から引き続きEmbulkの話になります。
ただし、以前とは少し毛色が違い、特定のプラグインではなく、設定ファイル自体について書いていきます。

Embulkに限らず、システムを利用・運用するうえで、"環境の違い"という問題に遭遇することは少なくないと思います。
OSやアーキテクチャのように決められているものから、意図して設定している環境設定など、その種類はさまざまですが、多くの場合、問題が発生するたび、その環境に対応させるためにシステムの設定を変更することになります。

Embulkの場合も、読み込むデータの場所や、データの形式、またデータによってはアクセスの情報などを設定ファイル内に記載するため、基本的に環境が変われば、その都度設定ファイルの情報を更新することになります。

この問題の解決方法の1つとして、Embulkのバージョン0.7から設定ファイルに"Liquid"が使えるようになりました。
今回、"Liquid"の詳細は記載しませんが、重要なのは"環境変数が設定ファイル内で参照できる"ことです。


なお、今回も基となるデータはexampleコマンド⇒guessコマンドによって生成されるデータ(sample_01.csv.gz)・ymlファイル(confing.yml)です。

使用データ
id,account,time,purchase,comment
1,32864,2015-01-27 19:23:49,20150127,embulk
2,14824,2015-01-27 19:01:23,20150127,embulk jruby
3,27559,2015-01-28 02:20:02,20150128,"Embulk ""csv"" parser plugin"
4,11270,2015-01-29 11:54:36,20150129,NULL


設定ファイル内で環境変数を使うための手順


①設定ファイルの拡張子を".yml"から".yml.liquid"に変更する
まず、設定ファイルの拡張子を変更します。拡張子を変更に伴って、設定ファイル内を編集する必要はないので、単純に設定ファイルをリネーム or コピーすればいいだけです。

previewコマンド実行結果(拡張子変更前)
+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                       NULL |
+---------+--------------+-------------------------+-------------------------+----------------------------+

拡張子変更(コピー)
[ec2-user@ip-172-31-9-9 lib]$ cp config.yml config.yml.liquid

previewコマンド実行結果(拡張子変更後)
+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                       NULL |
+---------+--------------+-------------------------+-------------------------+----------------------------+

念のため、previewコマンドで実行結果を確認しましたが、特に問題なく、同じ結果となりました。


②環境変数を使いたい箇所を書き換える
ここで設定ファイル内を書き換えて、環境変数を参照するように設定します。
例として、読み込むデータを指定する"path_prefix"の値を、環境変数"embulk_source_path"を参照させてみます。

まずは環境変数"embulk_source_path"に元々"path_prefix"で設定されている値と同じ値で設定します。

環境変数設定&確認
[ec2-user@ip-172-31-9-9 lib]$ export embulk_source_path=/opt/embulk/lib/try1/csv/sample_
[ec2-user@ip-172-31-9-9 lib]$ echo $embulk_source_path

/opt/embulk/lib/try1/csv/sample_


後は設定ファイル内で"{{ env.環境変数名 }}"と指定すれば、設定されている環境変数を参照するようになります。
"embulk_source_path"を設定したので、"path_prefix"の値を"{{ env.embulk_source_path }}"と指定します。

config.yml.liquid(緑字を変更)
in:
  type: file
  path_prefix: {{ env.embulk_source_path }}
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    quote: '"'
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
out: {type: stdout}

previewコマンド実行結果
+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                       NULL |
+---------+--------------+-------------------------+-------------------------+----------------------------+


環境変数を参照するようになりましたが、読み込むデータ自体は以前と変わらないので、実行結果も以前と変わりません。

では、今度は環境変数を書き換えて、違うデータを読み込むように設定してみます。

[ec2-user@ip-172-31-9-9 lib]$ export embulk_source_path=/opt/embulk/lib/sample_
[ec2-user@ip-172-31-9-9 lib]$ echo $embulk_source_path

/opt/embulk/lib/sample_

読み込むデータ(/opt/embulk/lib/sample_01.csv.gz)
id,account,time,purchase,comment
11,11111,2015-01-01 19:23:49,20150101,embulk
12,22222,2015-01-02 19:01:23,20150102,embulk jruby
13,33333,2015-01-03 02:20:02,20150103,"Embulk ""csv"" parser plugin"
14,44444,2015-01-04 11:54:36,20150104,NULL

previewコマンド実行結果
+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|      11 |       11,111 | 2015-01-01 19:23:49 UTC | 2015-01-01 00:00:00 UTC |                     embulk |
|      12 |       22,222 | 2015-01-02 19:01:23 UTC | 2015-01-02 00:00:00 UTC |               embulk jruby |
|      13 |       33,333 | 2015-01-03 02:20:02 UTC | 2015-01-03 00:00:00 UTC | Embulk "csv" parser plugin |
|      14 |       44,444 | 2015-01-04 11:54:36 UTC | 2015-01-04 00:00:00 UTC |                       NULL |
+---------+--------------+-------------------------+-------------------------+----------------------------+


以前の実行結果とは異なり、書き換えた環境変数のファイルを読み込んでいます。

これで環境ごとに必要な環境変数を設定するだけで、読み込むデータを指定できるようにできました。


プラグインで環境変数を参照させる

基本設定の"path_prefix"で環境変数を参照させられましたが、同様にプラグインにおいても環境変数を参照させることができます。

例として前回ご紹介した"embulk-filter-insert"プラグインを利用して、環境変数の値を新しいカラムとして追加してみます。

まずは環境変数"embulk_insert_env"に固定文字列"env"を設定します。

環境変数設定&確認
[ec2-user@ip-172-31-9-9 lib]$ export embulk_insert_env=env
[ec2-user@ip-172-31-9-9 lib]$ echo $embulk_insert_env

env


後は"path_prefix"を環境変数で参照させたときと同様に、追加するカラムの値に"{{ env.embulk_insert_env }}"と指定します。

config.yml.liquid(緑字を変更)
in:
  type: file
  path_prefix: /opt/embulk/lib/try1/csv/sample_
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    quote: '"'
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
filters:
  - { type: insert, column: { env: {{ env.embulk_insert_env }} }, at: top }
out: {type: stdout}

previewコマンド実行結果
+------------+---------+--------------+-------------------------+-------------------------+----------------------------+
| env:string | id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+------------+---------+--------------+-------------------------+-------------------------+----------------------------+
|        env |       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|        env |       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|        env |       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|        env |       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                       NULL |
+------------+---------+--------------+-------------------------+-------------------------+----------------------------+

しっかり環境変数で設定した後が、新しいカラムとして追加されています。


なお、embulkコマンドをsudoで実行している場合、通常のsudoでは環境変数は引き継がないため、オプションにより環境変数を引き継いで実行する必要があります。

previewコマンドを例にすると、次のようになります。

通常のsudo(環境変数を引き継がない)
[ec2-user@ip-172-31-9-9 lib]$ sudo embulk preview 設定ファイル

+------------+---------+--------------+-------------------------+-------------------------+----------------------------+
| env:string | id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+------------+---------+--------------+-------------------------+-------------------------+----------------------------+
|            |       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|            |       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|            |       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|            |       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                       NULL |

+------------+---------+--------------+-------------------------+-------------------------+----------------------------+

-Eオプション付きsudo(環境変数を引き継ぐ)
[ec2-user@ip-172-31-9-9 lib]$ sudo -E embulk preview 設定ファイル

+------------+---------+--------------+-------------------------+-------------------------+----------------------------+
| env:string | id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+------------+---------+--------------+-------------------------+-------------------------+----------------------------+
|        env |       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|        env |       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|        env |       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|        env |       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                       NULL |

+------------+---------+--------------+-------------------------+-------------------------+----------------------------+


このように環境変数を上手く利用することで、異なる環境においても設定ファイルを直接更新せずに実行させられようになり、Embulkの汎用性を高めることができます。

2015年12月15日火曜日

EmbulkのFILTER系プラグインを使ってみた(embulk-filter-insert,embulk-filter-split)

こんにちは、井下です。

前回に引き続き、EmbulkのFILTER系プラグインを使ってみるということで、"embulk-filter-insert"と"embulk-filter-split"を使ってみます。

なお、今回も基となるデータはexampleコマンド⇒guessコマンドによって生成されるデータ・ymlファイルです。

使用データ
id,account,time,purchase,comment
1,32864,2015-01-27 19:23:49,20150127,embulk
2,14824,2015-01-27 19:01:23,20150127,embulk jruby
3,27559,2015-01-28 02:20:02,20150128,"Embulk ""csv"" parser plugin"
4,11270,2015-01-29 11:54:36,20150129,NULL

デフォルトでのpreviewコマンド実行結果
+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                       NULL |
+---------+--------------+-------------------------+-------------------------+----------------------------+


1.embulk-filter-insert

"insert"とありますが、このプラグインはカラムのインサートを行います。
単純にカラムをインサートするだけではなく、"どこ"にインサートするのか、"どの型"でインサートするのかを設定することができます。
特に"どこ"にインサートするのかの設定方法は多く用意されており、最初のカラムや最後のカラムといった指定から、何カラム目かの指定、◯◯カラムの前or後の指定ができるようになっています。

GitHub上のExampleの通り、最初のカラムとして"host_name"カラムを追加してみます。

Embulkの読み込み用ymlファイル(緑字を追記)
in:
  type: file
  path_prefix: ~/lib/try1/csv/sample_
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    quote: '"'
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
filters:
  - { type: insert, column: { host_name: host01 }, at: top }
out: {type: stdout}

デフォルトでのpreviewコマンド実行結果
+------------------+---------+--------------+-------------------------+-------------------------+----------------------------+
| host_name:string | id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+------------------+---------+--------------+-------------------------+-------------------------+----------------------------+
|           host01 |       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|           host01 |       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|           host01 |       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|           host01 |       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                       NULL |
+------------------+---------+--------------+-------------------------+-------------------------+----------------------------+

最初のカラムにhost_nameカラムが追加されました。同様に"at"パラメータに"bottom"を指定すれば、最後のカラムとして追加されるようになりますし、数値を指定すれば、指定したカラムとして追加されるようになります。("2"を指定すれば、2カラム目として追加)
※なお、"at"パラメータには他に"head"、"tail"も指定できますが、実行してみた限りでは、"head"は"top"と同じ、"tail"は"bottom"と同じ動作をしていました。

また、"at"パラメータの代わりに"before"もしくは"after"パラメータの設定でカラム名を指定すると、指定したカラムの"前"or"後"にカラムをインサートすることができます。

2015年12月3日木曜日

EmbulkのFILTER系プラグインを使ってみた(embulk-filter-column,embulk-filter-row)

こんにちは、井下です。

しばらく触れられていませんでしたが、久しぶりにEmbulkについて書いていきます。
タイトル通り、2つのFILTER系プラグインを使ってみて、どのようにデータをいじれるのかを検証してみます。
なお、検証のために使うデータ・ymlファイルのベースは、Embulkのexampleコマンド⇒guessコマンドによって生成されるデータ・ymlファイルです。


ちなみに以前書いたEmbulkの内容は以下の通りです。

1.embulk-filter-column

2015年12月現在、FILTER系では一番ダウンロードされている(GitHubから)プラグイン、embulk-filter-columnです。
主にできることは"カラムの絞り込み"と"カラムの追加"です。

GitHub上のREADMEではExampleとして"columns"、"add_columns"、"drop_columns"の説明があります。
"add_columns"は"カラムの追加"、"drop_columns"は"カラムの絞り込み"、"columns"は"カラムの絞り込みとカラムの追加の両方"に対応しています。

1-1.add_columnsの例

add_columnsでは2通りのカラムの追加方法があります。

1つ目は、追加するカラムのデフォルト値を用意する方法。
2つ目は、元々存在しているカラムの値をコピーし、新しいカラムとする方法。

例として、1つ目の方法として"add_time"カラムを追加し、2つ目の方法として"copy_id"カラムを追加します。

データ(guessコマンドの自動生成のまま。特筆しない限り以降も同じデータです)
id,account,time,purchase,comment
1,32864,2015-01-27 19:23:49,20150127,embulk
2,14824,2015-01-27 19:01:23,20150127,embulk jruby
3,27559,2015-01-28 02:20:02,20150128,"Embulk ""csv"" parser plugin"
4,11270,2015-01-29 11:54:36,20150129,NULL

Embulkの読み込み用ymlファイル(緑字を追記)
in:
  type: file
  path_prefix: ~/lib/try1/csv/sample_
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    quote: '"'
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
filters:
  - type: column
    add_columns:
      - {name: add_time, type: timestamp, default: '20151201', format: "%Y%m%d" }
      - {name: copy_id, src: id}
out: {type: stdout}

なお、デフォルト値は"default"キーに指定します。上記のymlファイルでは"20151201"を指定しました。
コピー元のカラムは"src"キーに指定します。上記のymlファイルでは"id"を指定しました。

実行結果(preview)
+---------+--------------+-------------------------+-------------------------+----------------------------+-------------------------+--------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |      add_time:timestamp | copy_id:long |
+---------+--------------+-------------------------+-------------------------+----------------------------+-------------------------+--------------+
|       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk | 2015-12-01 00:00:00 UTC |            1 |
|       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby | 2015-12-01 00:00:00 UTC |            2 |
|       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin | 2015-12-01 00:00:00 UTC |            3 |
|       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                       NULL | 2015-12-01 00:00:00 UTC |            4 |
+---------+--------------+-------------------------+-------------------------+----------------------------+-------------------------+--------------+

実行結果を見ると、ymlファイル内で定義した通りの値で、"add_time"カラムと"copy_id"カラムが追加されていることが分かります。
※カラム名を分かりやすくするため、previewの実行結果を表示しています。timestamp型のデータにタイムゾーンが表示されているのはそのためです。
 なお、runの場合、"add_time"の値は"2015-12-01 00:00:00.000000 +0000"と表示されていました


2015年11月11日水曜日

AWS無料利用枠のインスタンスで、Ruby on Railsの環境を作成してみる③

こんにちは、井下です。

前々回前回と「AWS無料利用枠のインスタンスで、Ruby on Railsの環境を作成してみる」ことをテーマとしていましたが、今回は「デフォルトで入っているサーバの差し替え」について書いていきます。

ちなみにWebサーバは"Nginx"、アプリケーションサーバは"Unicorn"を導入する手順としています。

1.デフォルトのサーバ設定

サーバの差し替えを行う前の前提知識として、Railsでは"Webrick"というWebサーバが設定を行うことなく起動させることができ、RailsのWebアプリケーションの動作を確認することができます。

"Webrick"の起動はWebアプリケーションのルートディレクトリで"rails server"もしくは"rails s"コマンドで行えます。
※外部からブラウザでアクセスするには、さらにオプションとして"-b 0.0.0.0"を追加します。このオプションがないと、起動したマシンのlocalhostのURLでしかアクセスできません

試しに前回DBをSQLiteからPostgreSQLに差し替えたRailsのWebアプリケーション、"sample"で"Webrick"を起動してみます。
[ec2-user@ip-xxx ~]$ sudo service postgresql start

Redirecting to /bin/systemctl start  postgresql.service
[ec2-user@ip-xxx ~]$ cd sample/
[ec2-user@ip-xxx sample]$ rails s -b 0.0.0.0
=> Booting WEBrick
=> Rails 4.2.4 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2015-11-08 19:48:46] INFO  WEBrick 1.3.1
[2015-11-08 19:48:46] INFO  ruby 2.2.3 (2015-08-18) [x86_64-linux]
[2015-11-08 19:48:46] INFO  WEBrick::HTTPServer#start: pid=1954 port=3000

これでブラウザからアクセス、する前に、EC2インスタンスのセキュリティグループを編集し、ポート3000へのアクセスを許可します。

ブラウザからのアクセス準備が整ったので、"http://EC2インスタンスのIPアドレス:3000/"へアクセスします。

Railsではおなじみの画面が開きます。
この画面はブラウザからのリクエストを処理するWebサーバと、Rails自体を動作させるアプリケーションサーバが連携して開くことができます。
"Webrick"はWebサーバに分類されますが、Railsではアプリケーションサーバの役割も与えられています。

"Webrick"は特に設定を行うことなく、手早くWebアプリケーションの動作させられるメリットがありますが、レスポンスや起動の所要時間はあまり早くないため、本番用としてはWebサーバ・アプリケーションサーバを別途用意するのが一般的です。

それでは、ここからWebサーバ"Nginx"、アプリケーションサーバ"Unicorn"を導入していきます。

2015年10月29日木曜日

AWS無料利用枠のインスタンスで、Ruby on Railsの環境を作成してみる②

こんにちは、井下です。

前回はAWS無料利用枠のインスタンスを使って、とりあえずRailsがコンソール起動できるところまでの環境を構築しました。

今回はデフォルトで入ってるツール・ソフトウェア群を、よりスペックの良いものに差し替える工程を説明していきます。
なお、差し替え対象は下記の3つです。
  • JavaScriptランタイム
  • データベース
  • アプリケーションサーバ・Webサーバ
今回はJavaScriptランタイムと、データベースの差し替えを行います。
アプリケーションサーバおよびWebサーバは、次回差し替えを行っていきます。

1.JavaScriptランタイムの差し替え

前回も触れましたが、気軽に利用できるJavaScriptランタイムとして、「therubyracer」がありますが、bundle installに失敗するケースが出てきたり、メモリ消費量が多めな問題があります。

そこでよく利用されるJavaScriptランタイムの、「node.js」を導入してみます。

まずはGit Hubに掲載されているnode.jsのインストール手順に従って、node.jsをインストールしてみます。

[ec2-user@ip-xxx ~]$ curl --silent --location https://rpm.nodesource.com/setup | bash -

## Inspecting system...

+ rpm -q --whatprovides redhat-release || rpm -q --whatprovides centos-release || rpm -q --whatprovides cloudlinux-release
+ uname -m

## Confirming "el7-x86_64" is supported...

+ curl -sLf -o /dev/null 'https://rpm.nodesource.com/pub/el/7/x86_64/nodesource-release-el7-1.noarch.rpm'

## Downloading release setup RPM...

+ mktemp
+ curl -sL -o '/tmp/tmp.s0QxNR3NXV' 'https://rpm.nodesource.com/pub/el/7/x86_64/nodesource-release-el7-1.noarch.rpm'

## Installing release setup RPM...

+ rpm -i --nosignature --force '/tmp/tmp.s0QxNR3NXV'
error: can't create transaction lock on /var/lib/rpm/.rpm.lock (No such file or directory)

Error executing command, exiting

…が、ダメでした。権限の問題らしいので、sudoしてみても結果は変わらず。
仕方がないので、ソースを入手してインストールする方法を試してみたところ、こちらはインストールができました。

まずは、最新(2015年10月時点)のバージョン、0.12.7のソースコードを入手します。
[ec2-user@ip-xxx ~]$ mkdir work
[ec2-user@ip-xxx ~]$ cd work/
[ec2-user@ip-xxx work]$ wget http://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz
-bash: wget: command not found

…その前に、wgetがインストールされていなかったので、yumを使ってインストールします。

[ec2-user@ip-xxx work]$ sudo yum install wget
~略~
Complete!

今度こそ、0.12.7のソースコードを入手します。
[ec2-user@ip-xxx work]$ wget http://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz
--2015-10-25 21:00:46--  http://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz
Resolving nodejs.org (nodejs.org)... 104.20.23.46, 104.20.22.46, 2400:cb00:2048:1::6814:162e, ...
Connecting to nodejs.org (nodejs.org)|104.20.23.46|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 20063992 (19M) [application/gzip]
Saving to: ‘node-v0.12.7.tar.gz’

100%[=====================================================================================>] 20,063,992  7.49MB/s   in 2.6s

2015-10-25 21:00:49 (7.49 MB/s) - ‘node-v0.12.7.tar.gz’ saved [20063992/20063992]
[ec2-user@ip-xxx work]$ ls
node-v0.12.7.tar.gz

lsコマンドでソースコードを確認できたので、解凍した後、お決まりの「./configure」⇒「make」⇒「make install」でインストールします。

[ec2-user@ip-xxx work]$ tar xvf node-v0.12.7.tar.gz
[ec2-user@ip-xxx work]$ ls
node-v0.12.7  node-v0.12.7.tar.gz
[ec2-user@ip-xxx work]$ cd node-v0.12.7
[ec2-user@ip-xxx node-v0.12.7]$ ./configure
creating  ./icu_config.gypi
~略~
creating  ./config.gypi
creating  ./config.mk


[ec2-user@ip-xxx node-v0.12.7]$ make
~略~
[ec2-user@ip-xxx node-v0.12.7]$ sudo make install
~略~
[ec2-user@ip-xxx node-v0.12.7]$ node -v
v0.12.7

バージョン確認コマンドによって、node.jsがインストールできたことが確認できました。
これでtherubyracerは不要になったので、アンインストールしてしまいます。

[ec2-user@ip-xxx node-v0.12.7]$ cd ~/sample
[ec2-user@ip-xxx sample]$ gem list therubyracer

*** LOCAL GEMS ***

therubyracer (0.12.2)
[ec2-user@ip-xxx sample]$ gem uninstall therubyracer
[ec2-user@ip-xxx sample]$ gem list therubyracer

*** LOCAL GEMS ***

therubyracerがアンインストールされたので、Railsをコンソール起動して、JavaScriptランタイムが見つからないエラーが発生しないことを確認します。

[ec2-user@ip-xxx sample]$ rails c
Loading development environment (Rails 4.2.4)
irb(main):001:0>exit
[ec2-user@ip-xxx sample]$

特に問題はなさそうです。最後にGemfileを編集して、therubyracerを再度コメントアウトの状態にし、bundle installした際にインストールされないようにします。

[ec2-user@ip-xxx sample]$ vi Gemfile

「Gemgile」(緑字の部分を追記)

~略~
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
~略~

これでJavaScriptランタイムの差し替えが完了しました!

2015年10月14日水曜日

AWS無料利用枠のインスタンスで、Ruby on Railsの環境を作成してみる①

こんにちは、井下です。

休日に犬と遊んでいるはずみで、セロテープを切るあのギザギザで出血する羽目になりました。身近な凶器ですよね、あれ…。

さて、今回はRuby on Railsの「環境構築」がテーマです。

Webアプリケーションを開発するうえで、Ruby on Railsは選択肢の1つとして挙げられるようになっていますが、実際に開発を行おうとすると、Ruby on Railsの稼動にこぎつけるまで、様々な障害が出てきます。
幸いそれなりに問題を解決するための情報は出回っているので、完全に手詰まりになることはありませんが、バージョンや環境の違いによって、情報が適切でないことも少なくありません。

そこで、AWS無料利用枠のインスタンスを利用して、1からRuby on Railsの環境構築を行ってみようと思います。

なお、後でも改めて記述しますが、インスタンスやRubyのバージョンなどは下記の通りです。

インスタンス⇒Red Hat Enterprise Linux 7.1(t2.micro) ※2015/10時点の無料利用枠インスタンス
Ruby⇒2.2.3
Ruby on Rails⇒4.2.4

1.インスタンス作成

まずはRuby on Railsをインストールするインスタンスを作成します。
選択するインスタンスは、現時点で無料利用枠となっている「Red Hat Enterprise Linux 7.1」、インストールタイプは同じく無料利用枠の「t2.micro」です。

今回はRuby on Railsを動かすことが目的なので、それ以降の設定はデフォルトのまま、インスタンスを作成します。

2.Rubyインストール

Rubyをインストールする方法は、ソースコードから直接ビルドする方法と、ツールを利用する方法に大別されますが、今回はRubyのインストールによく利用される「rbenv」というツールを利用します。

また、rbenvをインストールするためには、「git」というバージョン管理ツールが必要になります。
順序としてまとめると、次のようになります。

(1).gitをインストールするために必要なライブラリをインストールする
(2).gitをインストールする
(3).gitを利用してrbenvをインストールする
(4).rbenvを利用してRubyをインストールする

(1).gitをインストールするために必要なライブラリをインストールする

下記のライブラリをインストールします。記載しているコマンドそのままで通るはずです。
[ec2-user@ip-xxx ~]$ sudo yum install zlib zlib-devel openssl-devel sqlite-devel gcc-c++ glibc-headers libyaml-devel readline readline-devel zlib-devel libffi-devel

色々とコンソールに表示されますが、最終的に「Complete!」と出てくればライブラリの導入は完了です。
Installed:
  gcc-c++.x86_64 0:4.8.3-9.el7              glibc-headers.x86_64 0:2.17-78.el7  libffi-devel.x86_64 0:3.0.13-11.el7
  openssl-devel.x86_64 1:1.0.1e-42.el7_1.9  readline-devel.x86_64 0:6.2-9.el7   sqlite-devel.x86_64 0:3.7.17-6.el7_1.1
  zlib-devel.x86_64 0:1.2.7-13.el7

Dependency Installed:
  cpp.x86_64 0:4.8.3-9.el7                                 gcc.x86_64 0:4.8.3-9.el7
  glibc-devel.x86_64 0:2.17-78.el7                         kernel-headers.x86_64 0:3.10.0-229.14.1.el7
  keyutils-libs-devel.x86_64 0:1.5.8-3.el7                 krb5-devel.x86_64 0:1.12.2-15.el7_1
  libcom_err-devel.x86_64 0:1.42.9-7.el7                   libmpc.x86_64 0:1.0.1-3.el7
  libselinux-devel.x86_64 0:2.2.2-6.el7                    libsepol-devel.x86_64 0:2.1.9-3.el7
  libstdc++-devel.x86_64 0:4.8.3-9.el7                     libverto-devel.x86_64 0:0.2.5-4.el7
  mpfr.x86_64 0:3.1.1-4.el7                                ncurses-devel.x86_64 0:5.9-13.20130511.el7
  pcre-devel.x86_64 0:8.32-14.el7

Dependency Updated:
  krb5-libs.x86_64 0:1.12.2-15.el7_1   openssl.x86_64 1:1.0.1e-42.el7_1.9   openssl-libs.x86_64 1:1.0.1e-42.el7_1.9
  sqlite.x86_64 0:3.7.17-6.el7_1.1

Complete!

(2).gitをインストールする

gitをインストールします。やること自体は前の手順とほぼ変わりありません。
[ec2-user@ip-xxx ~]$ sudo yum install git

次のように表示されていれば、gitのインストールも完了です。
Installed:
  git.x86_64 0:1.8.3.1-4.el7

Dependency Installed:
  libgnome-keyring.x86_64 0:3.8.0-3.el7                   perl.x86_64 4:5.16.3-285.el7
  perl-Carp.noarch 0:1.26-244.el7                         perl-Encode.x86_64 0:2.51-7.el7
  perl-Error.noarch 1:0.17020-2.el7                       perl-Exporter.noarch 0:5.68-3.el7
  perl-File-Path.noarch 0:2.09-2.el7                      perl-File-Temp.noarch 0:0.23.01-3.el7
  perl-Filter.x86_64 0:1.49-3.el7                         perl-Getopt-Long.noarch 0:2.40-2.el7
  perl-Git.noarch 0:1.8.3.1-4.el7                         perl-HTTP-Tiny.noarch 0:0.033-3.el7
  perl-PathTools.x86_64 0:3.40-5.el7                      perl-Pod-Escapes.noarch 1:1.04-285.el7
  perl-Pod-Perldoc.noarch 0:3.20-4.el7                    perl-Pod-Simple.noarch 1:3.28-4.el7
  perl-Pod-Usage.noarch 0:1.63-3.el7                      perl-Scalar-List-Utils.x86_64 0:1.27-248.el7
  perl-Socket.x86_64 0:2.010-3.el7                        perl-Storable.x86_64 0:2.45-3.el7
  perl-TermReadKey.x86_64 0:2.30-20.el7                   perl-Text-ParseWords.noarch 0:3.29-4.el7
  perl-Time-HiRes.x86_64 4:1.9725-3.el7                   perl-Time-Local.noarch 0:1.2300-2.el7
  perl-constant.noarch 0:1.27-2.el7                       perl-libs.x86_64 4:5.16.3-285.el7
  perl-macros.x86_64 4:5.16.3-285.el7                     perl-parent.noarch 1:0.225-244.el7
  perl-podlators.noarch 0:2.5.1-3.el7                     perl-threads.x86_64 0:1.87-4.el7
  perl-threads-shared.x86_64 0:1.43-6.el7

Complete!

(3).gitを利用してrbenvをインストールする

先ほどの手順でインストールしたgitを利用して、rbenvをインストールします。
[ec2-user@ip-xxx ~]$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv

下記のような表示がされれば、rbenvのインストールは完了です。
Cloning into '/home/ec2-user/.rbenv'...
remote: Counting objects: 2162, done.
remote: Compressing objects: 100% (63/63), done.
remote: Total 2162 (delta 34), reused 0 (delta 0), pack-reused 2094
Receiving objects: 100% (2162/2162), 371.13 KiB | 175.00 KiB/s, done.
Resolving deltas: 100% (1312/1312), done.

rbenvでRubyをインストールするために必要なプラグインも、gitを利用してインストールします。
[ec2-user@ip-xxx ~]$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

下記のような表示がされれば、Rubyのプラグインのインストールは完了です。
Cloning into '/home/ec2-user/.rbenv/plugins/ruby-build'...
remote: Counting objects: 5056, done.
remote: Total 5056 (delta 0), reused 0 (delta 0), pack-reused 5056
Receiving objects: 100% (5056/5056), 944.89 KiB | 318.00 KiB/s, done.
Resolving deltas: 100% (2734/2734), done.

これでrbenvをインストールできましたが、rbenvを利用するためにパスを通す必要があります。
「.bash_profile」にrbenvのパスが通るように設定を追加し、以降のログインでrbenvのパスが通っている状態にします。
[ec2-user@ip-xxx ~]$ vi ~/.bash_profile

「.bash_profile」ファイル(緑字の部分を追記)
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH
export PATH=$PATH:$HOME/.rbenv/bin:$HOME/.rbenv/shims

ここでログインし直すか、「source .bash_profile」コマンドで「.bash_profile」を読み直すと、rbenvにパスが通り、rbenvコマンドを認識するようになります。
[ec2-user@ip-xxx ~]$ source .bash_profile
[ec2-user@ip-xxx ~]$ rbenv -v
rbenv 0.4.0-169-g0f44c57

(4).rbenvを利用してRubyをインストールする

ここでようやくRubyをインストールします。バージョンは2015年10月時点での安定版、2.2.3を選択しました。
[ec2-user@ip-xxx ~]$ rbenv install 2.2.3

3~4分かかりましたが、無事Rubyがインストールできました。
Downloading ruby-2.2.3.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/df795f2f99860745a416092a4004b016ccf77e8b82dec956b120f18bdc71edce
Installing ruby-2.2.3...
Installed ruby-2.2.3 to /home/ec2-user/.rbenv/versions/2.2.3

ただし、rbenvでRubyをインストールした場合、どのバージョンを利用するのか設定する必要があります(rbenvはRubyのバージョン管理を行っているため)

下記のコマンドによって、Rubyの2.2.3を利用する設定を行います。
[ec2-user@ip-xxx ~]$ rbenv rehash
[ec2-user@ip-xxx ~]$ rbenv global 2.2.3

最後にRubyのバージョン確認コマンドで、Ruby 2.2.3が確認できれば、Rubyのインストールおよび利用準備は完了です。
[ec2-user@ip-xxx ~]$ ruby -v
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]