Athenaをbqコマンドライクに操作できるgem aqを作った

AWS AthenaをBigQueryのbqコマンドライクに使えるaq というコマンドラインツールを作りました。

github.com

AthenaをCLIで操作しようとすると踏まないといけない手順*1が多かったので、もっと楽にするために作った次第です。

またBigQueryのスキーマファイルをそのままAthenaでも使えるようにしているので、スキーマの2重管理を避けることもできます。

まだ必要最小限な機能しかないので、Issueでリクエストしてもらった機能には順次対応していこうかなと思っています。もちろんPullRequestも歓迎です。

インストール

gemでインストールできます。

$ gem install aq

コマンド

Athenaの仕様としてクエリの実行にはクエリの結果を保存するバケットの指定が必要です。 バケットは --bucket オプションで指定するか、環境変数 AQ_DEFAULT_BUCKET で指定してください。

Webコンソールから実行したときは aws-athena-query-results-<アカウントID>-<リージョン名> となるようなので、それに合わせるのが良いかもしれません。

help

コマンド一覧やコマンドの引数・オプション等を表示します。

$ aq help
$ aq help [COMMAND]

ls

データベースまたはテーブルの一覧を取得します。

# データベースの一覧
$ aq ls
# テーブルの一覧
$ aq ls [my_database_name]

head

テーブルの先頭100レコードを表示します。

$ aq head [my_db.my_table]

-n オプションで件数を変更できます。

mk

データベースを作成します。

bqコマンドではスキーマを指定しないテーブルの作成もできますが、Athenaはスキーマを指定しないテーブルは作成できないようだったので、テーブル作成はloadで行うようにしています。

$ aq mk [my_database_name]

load

テーブルの作成とデータのロードを行います。

今のところjsonl形式のファイルにしか対応していません。

schema.jsonは BigQueryのLegacySQLのスキーマファイルと同じ形式です。

$ aq load [my_db.my_table] s3://[my_bucket]/[my_object_key]/ [test/resource/schema.json] --partitioning [dt:string]

rm

データベースまたはテーブルを削除します。

# データベースの削除
$ aq rm [my_db]
# テーブルの削除
$ aq rm [my_db.my_table]

--force オプションをつけると確認が省略されます。

query

指定したクエリを実行します。

$ aq query 'SELECT * FROM "test"."test_logs" limit 10;'

*1:クラスメソッドさんのブログ記事 新機能 AWSCLIから Amazon Athena のクエリを実行する | Developers.IO を参照

Mbedオンラインコンパイラでmicro:bitを使う(温度計編)

この記事はMbed Advent Calendar 2017の4日目の記事です。

Mbedオンラインコンパイラでmicro:bitの開発をやってみます。 初めての開発なので、作るのは単純な温度計です。

micro:bitにはLEDアレイが搭載されていて、そこに文字を表示できるようになっています。 なので、温度をLEDアレイに表示するようにしてみました。

f:id:mia_0032:20171205023045g:plain

用意したもの

f:id:mia_0032:20171205020943p:plain

micro:bit本体とベースボード、温度センサーです。これらを使って作成します。

Grove ShieldとTemperature SensorはP0/P14のポートに接続しました。

コード

#include "MicroBit.h"

MicroBit uBit;

const int B = 4275;               // B value of the thermistor
const int R0 = 100000;            // R0 = 100k

MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ANALOG); 

int main()
{
    uBit.init();
    
    while (1) {
        wait(1.0);

        float R = 1024.0 / P0.getAnalogValue() - 1.0; 
        R = R0*R;
        float temperature = 1.0/(log(R/R0)/B + 1.0/298.15) - 273.15;
        
        char fmt[6];
        sprintf(fmt, "%02.2fC", temperature);
        uBit.display.scroll(fmt);
    }
}

通常のMbedのコードと異なる点があるので説明していきます。

以上の2つの点が大きな違いです。

MicroBitPinは DigitalInAnalogIn とメソッドが異なるので注意が必要です。だいぶシンプルなメソッドになっている印象を受けました。

PIN_CAPABILITY_ANALOGhttps://lancaster-university.github.io/microbit-docs/ubit/io/#microbitpin-int-id-pinname-name-pincapability-capabilityに記載されている定数で、アナログピンとして使用する設定です。

        float R = 1024.0 / P0.getAnalogValue() - 1.0; 
        R = R0*R;
        float temperature = 1.0/(log(R/R0)/B + 1.0/298.15) - 273.15;

のあたりの計算式は Grove - Temperature Sensor V1.2 - Seeed Wiki からのコピペです。

最初コードを書いたときに 1024.0 / P0.getAnalogValue()の部分を1024 / P0.getAnalogValue()と書いてしまったがために、割り算の結果がintで丸められてしまい、出力される値が変化しなくなってしまっていました。

そのデバッグに結構時間を使ってしまったので、型には気をつけないといけないですね・・・

感想

コードのデバッグではまってしまったところはあったものの、電子回路の部分は挿すだけで良いので楽に作れます。 ピン定義の部分さえ理解すれば、それ以外のところは理解しやすいAPIになっているように感じました。

明日の記事は toyowataさんの「MAと私」です。

Digdag pluginのローカルでの動作確認方法

digdag-slack pluginにPullRequestを送ったときに、ローカルで動作確認する方法が最初わからなかったのでメモしておきます。

1. ビルドする

$ ./gradlew publish

2. digファイルのプラグインの読み込み設定を書き換える

_export:
  plugin:
    repositories:
      - file://${repos}
    dependencies:
      - io.digdag.plugin:digdag-slack:0.1.4-SNAPSHOT

repositoriesにローカルのファイルパスを指定し、dependenciesにpackageのclass pathを指定します。 上記の設定だと、reposが変数になっているので -p repos=`pwd`/build/repo と指定することが可能です。

3. pluginのキャッシュファイルを削除する

$ rm -rf .digdag/plugins

Digdagは実行時にプラグインをローカルディレクトリにキャッシュしているようで、プラグインのバージョンアップを行わない限り、そちらのファイルが使われてしまいます。 通常時は問題ないですが、動作確認をするときは古いファイルのままになってしまうことがあるため、キャッシュファイルを削除します。

4. digdag runする

$ digdag run sample.dig -p repos=`pwd`/build/repo

上記のコマンドでワークフロー(sample.dig)を実行し、動作確認できます。