IDEA Note

  • rbenvのインストール

    rbenvのインストール

    はじめに

    rubyを自由にversion切り替えられるrbenvはとても便利。

    しかし、インストールは少しめんどくさい。

    よく使う手順なのでとりあえず晒す

    手順

    以下、コピペでOK。

    インストールしたいversionは適宜変更すること

    yum -y install openssl-devel readline-devel zlib-devel libcurl-devel git
    cd /usr/local
    git clone https://github.com/sstephenson/rbenv.git rbenv
    mkdir rbenv/shims rbenv/versions rbenv/plugins
    groupadd rbenv
    chgrp -R rbenv rbenv
    chmod -R g+rwxXs rbenv
    cd /usr/local/rbenv/plugins
    git clone https://github.com/sstephenson/ruby-build.git ruby-build
    chgrp -R rbenv ruby-build
    chmod -R g+rwxs ruby-build
    git clone https://github.com/sstephenson/rbenv-default-gems.git rbenv-default-gems
    chgrp -R rbenv rbenv-default-gems
    chmod -R g+rwxs rbenv-default-gems
    
    cat << EOF > /etc/profile.d/rbenv.sh
    export RBENV_ROOT="/usr/local/rbenv" 
    export PATH="\$RBENV_ROOT/bin:\$PATH" 
    eval "\$(rbenv init -)" 
    EOF
    
    cat /etc/profile.d/rbenv.sh
    
    cat << EOF > /usr/local/rbenv/default-gems
    bundler
    rbenv-rehash
    EOF
    
    cat /usr/local/rbenv/default-gems
    source /etc/profile.d/rbenv.sh
    rbenv install -l
    
    yum install gcc bzip2
    rbenv install 2.2.5
    rbenv global 2.2.5
    ruby -v
    
    yum install rubygems -y

    Good ruby life!

  • redashでALL Queriesを選択すると “Loading…” のままで変わらない

    redashでALL Queriesを選択すると “Loading…” のままで変わらない

    問題発生

    QueriesがLoadingのままで、Query一覧が表示されない

    redash_serverコンテナには以下のログが吐かれていた

    [2018-10-10 12:48:45,419][PID:14][ERROR][redash] Exception on /api/queries [GET]
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1639, in full_dispatch_request
        rv = self.dispatch_request()
      File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1625, in dispatch_request
        return self.view_functions[rule.endpoint](**req.view_args)
      File "/usr/local/lib/python2.7/dist-packages/flask_restful/__init__.py", line 477, in wrapper
        resp = resource(*args, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/flask_login/utils.py", line 228, in decorated_view
        return func(*args, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/flask/views.py", line 84, in view
        return self.dispatch_request(*args, **kwargs)
      File "/app/redash/handlers/base.py", line 31, in dispatch_request
        return super(BaseResource, self).dispatch_request(*args, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/flask_restful/__init__.py", line 587, in dispatch_request
        resp = meth(*args, **kwargs)
      File "/app/redash/permissions.py", line 48, in decorated
        return fn(*args, **kwargs)
      File "/app/redash/handlers/queries.py", line 197, in get
        with_last_modified_by=False
      File "/app/redash/handlers/base.py", line 106, in paginate
        items = serializer(results.items, **kwargs).serialize()
      File "/app/redash/serializers.py", line 75, in serialize
        result = [serialize_query(query, **self.options) for query in self.object_or_list]
      File "/app/redash/serializers.py", line 105, in serialize_query
        d['user'] = query.user.to_dict()
    AttributeError: 'NoneType' object has no attribute 'to_dict'

    解決へのアプローチ

    とりあえずググる。前例が見つからない。

    twitterで騒ぐ。知ってる人いるかも。

    すぐに見つからない。

    redashのフォーラムに聞いた。

    https://discuss.redash.io/t/when-open-queries-all-queries-always-loading/2449

    redashの生みの親、arikfr がコメントをくれた

    https://discuss.redash.io/t/when-open-queries-all-queries-always-loading/2449/2?u=gitsumito

    あ!確かに消しました。

    そういえばやったこと

    この画面にたどり着く前、redashユーザーの作成を行なった。

    docker exec -it redash_server_1 ./manage.py users create taro@sumito.jp taro

    manage.pyを使い、ユーザーの追加した。

    ちなみにこのmanage.pyを使い、ユーザの追加・削除することは随分前のversionから利用可能で、このコマンドを用いた管理方法は @kakakakakku 氏のブログが非常にわかりやすい 

    ただ、redash version 5.0でredashユーザーの作成を行うと(昔のバージョンもかも)、既に登録されているユーザでも新しく登録できてしまう。

    つまりデータベースに二重に登録されてしまう状態だった。

    この状態で作成したユーザでloginしようとすると、Internal Server Errorになりログインできなくなる。

    仕方なくユーザーを削除することにした

    docker exec -it redash_server_1 ./manage.py users delete taro@sumito.jp

    Successfully。削除できた。

    再度ユーザの作成を行なうと、無事作成したユーザでredashにログインできるようになった。

    めでたし、めでたし。と思ったが、今回の問題

    redashでALL Queriesを選択すると “Loading…” のままで変わらない

    という問題に繋がったようだ。

    解決方法

    postgresのコンテナにログインし、userid周りを調整

    docker exec -it redash_postgres_1 /bin/bash
    psql -U postgres postgres

    redashのユーザ情報が格納されているusersテーブルでidを確認する

    postgres=# select * from users order by id desc;
    updated_at | created_at | id | org_id | name | email | password_hash | groups | api_key | profile_image_url | disabled_at 
    -------------------------------+-------------------------------+----+--------+--------------------+-----------------------------------------+--------------------------------------------------------------------------------------------------------------------------+-----------+------------------------------------------+-------------------+-------------------------------
    (skip)
    2018-08-30 06:48:30.812508+00 | 2018-08-30 06:40:15.029328+00 | 51 | 1 | *** | gomes@sumito.jp | *** | {2,5} | *** | | 
    2018-10-09 08:18:34.331088+00 | 2018-10-09 08:17:20.97545+00 | 55 | 1 | taro | taro@sumito.jp | *** | {2,5} | *** | | 
    2018-10-09 08:18:37.220691+00 | 2018-10-09 08:18:00.078037+00 | 56 | 1 | jiro | jiro@sumito.jp | *** | {2,5} | *** | 

    id 52~54 が欠番していることがわかる。

    これが自分が削除したユーザのID。

    まずはid 52~56のeventテーブルから全ての履歴を削除した

    SELECT * FROM events WHERE user_id = 52;
    DELETE FROM events WHERE user_id = 52;
    
    SELECT * FROM events WHERE user_id = 53;
    DELETE FROM events WHERE user_id = 53;
    
    SELECT * FROM events WHERE user_id = 54;
    DELETE FROM events WHERE user_id = 54;
    
    SELECT * FROM events WHERE user_id = 55;
    DELETE FROM events WHERE user_id = 55;
    
    SELECT * FROM events WHERE user_id = 56;
    DELETE FROM events WHERE user_id = 56;

    これでイベントが全て削除された。

    usersテーブルのid 55,56 を 52,53 に変更した

    update users set id = 52 where email = 'taro@sumito.jp';
    update users set id = 53 where email = 'jiro@sumito.jp';

    その後、user idのインクリメント部分を管理しているusers_id_seq

    を56 から 53に変更した。

    ALTER SEQUENCE users_id_seq RESTART WITH 53;

    対応はこれだけ、

    無事問題が解決した。

    最後に

    CLIを見直すことを示唆してくれた。

    今後のversion upが楽しみ。

  • ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (2 “No such file or directory”)

    ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (2 “No such file or directory”)

    はじめに

    以下のようなエラーが発生する事がある

    ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2 "No such file or directory")

     

    原因

    mysqlが立ち上がっていない事が多い。

    CentOS7の場合は起動する

    systemctl start mysql

     

  • DQLで手の届きにくいところをredashでなんとかする

    DQLで手の届きにくいところをredashでなんとかする

    はじめに

    DynamoDBを操作するとき、DQLの操作が難しかったり、GroupByができなかったり。SQLでできないところができなかったりすることが多い。redashを使えばそれもなんとかなったりします。

    Query Resultsを活用

    redashにはQeury Resultsという機能があります(2018/10現在、ベータ版)。これは取得したクエリに対し、SQLを用いてデータを結合させたり、編集することができる機能です。

    一度DQLの結果をredashのQuery Resultsを経由させることで細かいところに手が届くようになります。

    Query Resultを指定し、redashで以下のようなクエリを書きます

    select *, sum(price)
    from query_123
    group by userID

    もちろんDQLのみならず、他の言語も似たようにQuery Resultをかえすことで編集可能です。

     

     

     

     

     

  • mauticをDockerで試したが…

    mauticをDockerで試したが…

    はじめに

    OSS版のMarketoのようなマーケティングツールを使いたいとマーケティングチームから話が上がってきたが、Dockerでインストールを試みたが一筋縄に行かなかった。

    問題

    https://qiita.com/kooooooooooooooooohe/items/43f9452acc539dbd3083

    を参考にdocker-composeで立ち上げ、ブラウザでinstallしようとする。

     

    するとこの画面でSQL Syntaxエラーが発生。

    An error occurred while attempting to install the data: An exception occurred while executing 'CREATE TABLE reports (id INT AUTO_INCREMENT NOT NULL, is_published TINYINT(1) NOT NULL, date_added DATETIME DEFAULT NULL, created_by INT DEFAULT NULL, created_by_user VARCHAR(255) DEFAULT NULL, date_modified DATETIME DEFAULT NULL, modified_by INT DEFAULT NULL, modified_by_user VARCHAR(255) DEFAULT NULL, checked_out DATETIME DEFAULT NULL, checked_out_by INT DEFAULT NULL, checked_out_by_user VARCHAR(255) DEFAULT NULL, name VARCHAR(255) NOT NULL, description LONGTEXT DEFAULT NULL, system TINYINT(1) NOT NULL, source VARCHAR(255) NOT NULL, columns LONGTEXT DEFAULT NULL COMMENT '(DC2Type:array)', filters LONGTEXT DEFAULT NULL COMMENT '(DC2Type:array)', table_order LONGTEXT DEFAULT NULL COMMENT '(DC2Type:array)', graphs LONGTEXT DEFAULT NULL COMMENT '(DC2Type:array)', group_by LONGTEXT DEFAULT NULL COMMENT '(DC2Type:array)', aggregators LONGTEXT DEFAULT NULL COMMENT '(DC2Type:array)', settings LONGTEXT DEFAULT NULL COMMENT '(DC2Type:json_array)', is_scheduled TINYINT(1) NOT NULL, schedule_unit VARCHAR(255) DEFAULT NULL, to_address VARCHAR(255) DEFAULT NULL, schedule_day VARCHAR(255) DEFAULT NULL, schedule_month_frequency VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB': SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'system TINYINT(1) NOT NULL, source VARCHAR(255) NOT NULL, columns LONGTEXT DEFAU' at line 1

    ソースを読んで直そうと試みたが、実運用ではなくちょっと試したいという温度感のようだったので、Dockerを諦め、とりあえず最短で使える方法を選んだ。

    解決方法

    Dockerを諦めた。以下のQiitaの記事のコピペでinstallができる。

    https://qiita.com/bezeklik/items/3cd61156367909e31421

     

    https://jp.mautic.org/
  • CloudWatch Logsで任意の文字列を監視し、メールで通知する

    CloudWatch Logsで任意の文字列を監視し、メールで通知する

    はじめに

    CloudWatch Logsで集めたログの中で任意の文字列(例えば、Errorとか、Criticalとか)が記載されていた場合、メールなどで通知させたい事がある。

    Node.jsをLambdaで動かす事で文字列監視を実装した。

    通知先の作成

    まずはSNSでメールの宛先から作成しARNを控え、エンドポイントとなるメールアドレスを設定する。 

    node.js(lambda)

    関数コードを編集

     

    ERROR、CRITICALという文字列があったら監視するスクリプト

    var zlib = require('zlib');
    var aws = require('aws-sdk');
    var sns = new aws.SNS({ region: 'ap-northeast-1' });
    exports.handler = function(input, context, callback) {
      var data = new Buffer(input.awslogs.data, 'base64');
      zlib.gunzip(data, function(e, rst) {
        if (e) {
          callback(e);
        } else {
          rst = JSON.parse(rst.toString('utf-8'));
          var errL = rst['logEvents']
              .filter(function(evt) { return evt['message'].match(/ERROR/i) ;})
              .filter(function(evt) { return !evt['message'].match(/$^/) ;})
              .map(function(evt) { return evt['message'] });
          console.log('processing[Error]' + errL.length + '/' + rst['logEvents'].length + ' events.');
          var critL = rst['logEvents']
              .filter(function(evt) { return evt['message'].match(/CRITICAL/i) ;})
              .filter(function(evt) { return !evt['message'].match(/$^/) ;})
              .map(function(evt) { return evt['message'] });
          console.log('processing[Crit]' + critL.length + '/' + rst['logEvents'].length + ' events.');
          if (errL.length === 0 && critL.length === 0) { callback(); return; }
          var date = new Date();
          date.setTime(date.getTime() + 1000*60*60*9);
          var dateTime = date.getFullYear() + '/' + ("0" + (date.getMonth() + 1)).slice(-2) + '/' + ("0" + date.getDate()).slice(-2) +
               ' ' + ("0" + date.getHours()).slice(-2) + ':' + ("0" + date.getMinutes()).slice(-2) + ':' + ("0" + date.getSeconds()).slice(-2);
          if (0 < errL.length) {
            // has error log
            var sjct = '[Error] Notify From CloudWatch Logs';
            var pl = { default: '' };
            pl['default'] += 'NotifyAt: ' + dateTime.valueOf() + '\n';
            pl['default'] += 'Log: ' + rst['logGroup'] + ' - ' + rst['logStream'] + '\n';
            pl['default'] += 'Filter: ' + rst['subscriptionFilters'] + '\n';
            pl['default'] += 'Messages:\n';
            pl['default'] += errL.join('\n---\n');
            sns.publish({
              Subject: sjct,
              Message: JSON.stringify(pl),
              MessageStructure: 'json',
              TargetArn: 'arn:aws:sns:ap-northeast-1:1234567890(your no):(your arn)'
            }, function(err, data) {
              if (err) {
                callback(err);
              } else if (0 < critL.length) {
                // has waring too
                var sjct = '[Critical] Notify From CloudWatch Logs';
                var pl = { default: '' };
                pl['default'] += 'NotifyAt: ' + dateTime.valueOf() + '\n';
                pl['default'] += 'Log: ' + rst['logGroup'] + ' - ' + rst['logStream'] + '\n';
                pl['default'] += 'Filter: ' + rst['subscriptionFilters'] + '\n';
                pl['default'] += 'Messages:\n';
                pl['default'] += critL.join('\n---\n');
                sns.publish({
                  Subject: sjct,
                  Message: JSON.stringify(pl),
                  MessageStructure: 'json',
                  TargetArn: 'arn:aws:sns:ap-northeast-1:1234567890(your no):(your arn)'
                }, function(err, data) {
                  if (err) callback(err);
                  else callback(null, data);
                });
              } else {
                callback(null, data);
              }
            });
          } else {
            // has NOT error log == criticaling only
            var sjct = '[Critical] Notify From CloudWatch Logs';
            var pl = { default: '' };
            pl['default'] += 'NotifyAt: ' + dateTime.valueOf() + '\n';
            pl['default'] += 'Log: ' + rst['logGroup'] + ' - ' + rst['logStream'] + '\n';
            pl['default'] += 'Filter: ' + rst['subscriptionFilters'] + '\n';
            pl['default'] += 'Messages:\n';
            pl['default'] += critL.join('\n---\n');
            sns.publish({
              Subject: sjct,
              Message: JSON.stringify(pl),
              MessageStructure: 'json',
              TargetArn: 'arn:aws:sns:ap-northeast-1:1234567890(your no):(your arn)'
            }, function(err, data) {
              if (err) callback(err);
              else callback(null, data);
            });
          }
        }
      });
    };
    

     

    トリガーを設定

    今回はCloudWatch Logsがトリガーとなるので、CloudWatch Logsを選択し、その後対象のログを選択する。

     

    通知先の設定

    Amazon SNSのARNを選択する(予めSNSでトピックを作っておく必要がある)

    以上

  • Error running query: No index found for query. Please use a SCAN query, or set allow_select_scan=True opt allow_select_scan true

    Error running query: No index found for query. Please use a SCAN query, or set allow_select_scan=True opt allow_select_scan true

    はじめに

    DynamoDBは言わずと知れたKVSだが、それを忘れてredashで実行しようとすると、当然ながらエラーになる。

    redashでDynamoDBのデータを見ようとした際、以下のようなエラーが出た

     
     

    原因

    RDSのように普通のSQLで書いていた。
    たとえば上のように
     
    “` select * from xxxx “`
    と書いていたのが原因
     

    対応

     
    “` scan * from xxxx “`
    という書き方に修正し再度実行
     
    無事データを取得できた
     
  • unsubscribeされてしまったcloudwatch (SNS)通知を検知する

    unsubscribeされてしまったcloudwatch (SNS)通知を検知する

    はじめに

    AWSでcloudwatchで監視し、異常があったらSNSで通知する事はあるが、SNSではデフォルトで「配信停止(unsubscribe)する場合は、ここクリックしてね」とありがたいことに(?)記載されてある。

    チーム開発しているとSNSの通知先がメーリングリストにしていると、誤って押されてしまうと、その後のメールが来なくなってしまう。

    配信停止(unsubscribe)を押された場合検知はさっくり作れたのでそれをまとめる

    手順

    awsコマンドとjqコマンドをうまく組み合わせる

    aws sns list-subscriptions | jq -r '.Subscriptions[] | select(.SubscriptionArn == "Deleted") '

    結果

    aws sns list-subscriptions | jq -r '.Subscriptions[] | select(.SubscriptionArn == "Deleted") '
    {
      "SubscriptionArn": "Deleted",
      "Owner": "xxxxxxxxxx",
      "Protocol": "email",
      "Endpoint": "sute@sumito.jp",
      "TopicArn": "arn:aws:sns:ap-northeast-1:xxxxxxx:xxxxxxxxx"
    }
    

    unsubscribeされたメールドレスや、TopicArn情報などを確認することができる。

    ちなみにチャットワークに通知する場合は以下の通りシェルでラップする

    #!/bin/bash
    aws --profile=$1 sns list-subscriptions | jq -r '.Subscriptions[] | select(.SubscriptionArn == "Deleted") ' > /tmp/check-unsubscribe.$1
    
    # 文字を整形する
    # headder
    cat << _EOT_ > /tmp/check-unsubscribe.$1.txt
    [info]
    [title]Someone clicked unsubscribe link
    [/title]
    _EOT_
    
    # contents
    cat  /tmp/check-unsubscribe.$1 >> /tmp/check-unsubscribe.$1.txt
    echo "[/info]"  >> /tmp/check-unsubscribe.$1.txt
    
    _roomid=xxxxxxxxxxxxx # (your chatroom id)
    _body=`cat /tmp/check-unsubscribe.$1.txt`
    
    # 1件以上あれば通知する
    if [ `wc -l /tmp/check-unsubscribe.$1 | awk '{print $1}'` -gt 0 ] ; then
        curl -X POST -H "X-ChatWorkToken: 123456789" -d "body=${_body}" "https://api.chatwork.com/v2/rooms/${_roomid}/messages"
    fi
    
    exit 0

     

  • ZipFile length cannot exceed 4096 characters. For larger source use S3Bucket/S3Key properties instead.

    ZipFile length cannot exceed 4096 characters. For larger source use S3Bucket/S3Key properties instead.

    はじめに

    ymlファイルをCloudFormationでデプロイした時、というエラーが出た。

    When yml file is deployed with CloudFormation, bellow error was happened.

    ZipFile length cannot exceed 4096 characters. For larger source use S3Bucket/S3Key properties instead.

     

    原因 reason

    zip化する際に含まれるコードが4096文字を越えると本エラーに陥る。

    This error occurs when the code included in zipping exceeds 4096 characters.

    対処 deal

    いらないところを削除するなどして、コードをコンパクトにする。

    Make the code more compact by deleting unnecessary parts.

  • mysqlのデータをembulkでBigQueryへ入れredashで確認する

    mysqlのデータをembulkでBigQueryへ入れredashで確認する

    はじめに

    データ解析するにあたり、BigQueryを使いたい事がある。mysqlからデータを取得するところをembulkを使う。embulkのインストール方法から簡単な使い方までまとめた。

    embulkのインストール

    embulkはJavaで作られており、一からinstallしようとすると、割と面倒。今回はDockerを使うこととする。

    BigQueryの設定

    APIs & Servicesでcredentialを作成する。

    jsonファイルダウンロードできるので、適宜保存する。

    Dockerfileを作成

    GCPにプロジェクトを作り、bigqueryに権限を付与。APIで操作できるようjsonファイルを取得する。

    FROM java:7
    MAINTAINER sumito.tsukada "tsukada@sumito.jp"
    
    ENV EMBULK_VERSION 0.8.39
    
    RUN curl -L https://bintray.com/artifact/download/embulk/maven/embulk-${EMBULK_VERSION}.jar -o /opt/embulk.jar
    RUN java -jar /opt/embulk.jar gem install embulk-input-mysql
    RUN java -jar /opt/embulk.jar gem install embulk-output-bigquery
    
    WORKDIR /work
    ENTRYPOINT ["java", "-jar", "/opt/embulk.jar"]
    CMD ["--help"]

    build

    # docker build -t tsukada/embulk .
    Sending build context to Docker daemon  2.048kB
    Step 1/9 : FROM java:7
     ---> 5dc48a6b75af
    Step 2/9 : MAINTAINER sumito.tsukada "tsukada@sumito.jp"
     ---> Using cache
     ---> bc78ed50d614
    Step 3/9 : ENV EMBULK_VERSION 0.8.39
     ---> Using cache
     ---> 266476a95a55
    Step 4/9 : RUN curl -L https://bintray.com/artifact/download/embulk/maven/embulk-${EMBULK_VERSION}.jar -o /opt/embulk.jar
     ---> Using cache
     ---> b21e71d6ce44
    Step 5/9 : RUN java -jar /opt/embulk.jar gem install embulk-input-mysql
     ---> Using cache
     ---> 2fb224b24c49
    Step 6/9 : RUN java -jar /opt/embulk.jar gem install embulk-output-bigquery
     ---> Running in b27f12583137
    2018-09-18 02:50:32.526 +0000: Embulk v0.8.39
    
    ********************************** INFORMATION **********************************
      Join us! Embulk-announce mailing list is up for IMPORTANT annoucement such as
        compatibility-breaking changes and key feature updates.
      https://groups.google.com/forum/#!forum/embulk-announce
    *********************************************************************************
    Gem plugin path is: /root/.embulk/jruby/2.3.0
    
    Successfully installed uber-0.1.0
    Successfully installed declarative-0.0.10
    Successfully installed declarative-option-0.1.0
    Successfully installed representable-3.0.4
    Successfully installed retriable-3.1.2
    Successfully installed public_suffix-3.0.3
    Successfully installed addressable-2.5.2
    Successfully installed mime-types-data-3.2018.0812
    Successfully installed mime-types-3.2.2
    Successfully installed multipart-post-2.0.0
    Successfully installed faraday-0.15.2
    Successfully installed multi_json-1.13.1
    Successfully installed jwt-2.1.0
    Successfully installed signet-0.9.2
    Successfully installed memoist-0.16.0
    Successfully installed os-1.0.0
    Successfully installed googleauth-0.6.6
    Successfully installed httpclient-2.8.3
    Successfully installed google-api-client-0.24.0
    Successfully installed thread_safe-0.3.6-java
    Successfully installed tzinfo-1.2.5
    Successfully installed time_with_zone-0.3.1
    Successfully installed embulk-output-bigquery-0.4.9
    23 gems installed
     ---> 74e55d0084d6
    Removing intermediate container b27f12583137
    Step 7/9 : WORKDIR /work
     ---> 19d9c56bf738
    Removing intermediate container c73ef21e7b6c
    Step 8/9 : ENTRYPOINT java -jar /opt/embulk.jar
     ---> Running in 4bca2f2ed68e
     ---> b4458584af6f
    Removing intermediate container 4bca2f2ed68e
    Step 9/9 : CMD --help
     ---> Running in 7fdbd68d5021
     ---> 0bfdab6b8d24
    Removing intermediate container 7fdbd68d5021
    Successfully built 0bfdab6b8d24
    Successfully tagged tsukada/embulk:latest

    embulkの設定

    今回はmysqlからデータを抜き、BigQueryに入れるとする。

    in:
      type: mysql
      user: redash
      password: passwd
      database: sample
      host: 127.0.0.1
      query: "select date, user from sampletable"
    out:
      type: bigquery
      auth_method: json_key
      json_keyfile: tsukada-bigquery.json
      path_prefix: /tmp/
      file_ext: .csv.gz
      source_format: CSV
      project: 12345679
      dataset: table123
      auto_create_table: true
      table: user_data
      formatter: {type: csv, charset: UTF-8, delimiter: ',', header_line: false}
      encoders:
      - {type: gzip}

    実行

    docker run -t -v ${PWD}:/work tsukada/embulk run sample.yml

    以下のようい表示されればOK

    [INFO] (main): Committed.

    BigQueryで確認

    データが入ったという事がわかった。
    また、

    #standardSQL

    と書いてあるが、これはコメントではなく、BigQueryが判断する重要な宣言になるので削除するとうまく動かないので注意。

     

    redashでBigQueryに接続

    先ほど使ったjsonファイルと接続先のプロジェクトIDを入力すると、redashからbigqueryへ接続する事ができる。