last update: 2014/09/03

2014/09/03

golangのpqドライバでRedShiftにつないでちょっとハマった話

YAPCが終わり、夏も終わり、みなさんいかがお過ごしでしょうか。れもんです。季節感を先取りしてデザインを冬っぽい感じにしました。

さて、最近仕事でRedshiftをつかっておりまして、ご存じのない方に簡単に説明するとAWSで使えるマネージドで列指向でシェアードナッシングな分散データベースっていう説明でいいんでしょうか。あんまり定義の分野に明るくないのでとりあえずぼくはそんな認識で使っております。MPP! MPP! みたいな感じです。

で、「Goで行こう」というダジャレなのかどうかよくわからないことをぶち上げたというのと、BIツール的なところは比較的言語の作りに依存してどうこうみたいなハマリかたをしなさそうで新しい言語を投入するには無難だなというところで、Redshiftを叩くのをgolangでやっております。

RedshiftはPostgreSQLのドライバで接続可能なので、golangに限らずPostgreSQL用のデータベースドライバを使ってプログラムを書けば良いです。ホントかよと思ってPerlで最初に実験したときはDBD::Pgでいけましたし、chefレシピで冪等にテーブルが存在するようにCREATE TABLEするレシピを書いたときはRubyのpgを使ってクエリを送って大丈夫だねーという確認をしていました。

ということで! 実際にRedshiftを叩いてWebUIでグラフとか出すところをgolangとpqドライバで書き始めて、最初は順調だったんですが、db.Query("SELECT 〜", date) みたいなところでconnection refusedのエラーがでて必ず死ぬ問題に直面しました。クエリは仮ですが、ざっくりこんなコードです。db.Queryでいきなり死んで仕事にならん感じでした。

today := time.Now().Format("2006-01-02")
rows, err := db.Query(
    `SELECT user_id, access_at FROM access_log WHERE access_at = $1`,
     today,
)
if err != nil {
    fmt.Println("error: ", err)
    return nil, err
}
defer rows.Close()

result := []interface{}
for rows.Next() {
    var days_count, count int
    if err = rows.Scan(&days_count, &count); err != nil {
        fmt.Println(err)
    } else {
        // write something cool business logic here...

    }
}
return result, nil

とりあえず社内IRCの #go で「ふぇーRedshiftがエラーになるーたすけてー」みたいな感じで呟いてみたところ、fujiwaraさんが出てきてどれどれみたいな感じになり、2人でソース読んだりRedshiftじゃなくてPostgreSQLの挙動を確認した結果、Redshiftは無名PREPAREステートメントに対応してないっぽいというところまでわかりました。ちなみにfujiwaraさんは前職でPostgreSQLをずっと使ってたそうで、とりあえずPostgreSQLでわかんないことあったらfujiwaraさんに聞くとなんとかなるのでいつもお世話になっています。

で、pqドライバのソースを読んで確認した結果はこんな感じでした。

まず、pqドライバはPrepared Statementをサーバ側で処理させるようになっていて、db.Queryでコネクションから直接args付きでPrepared Statementを投げると無名Prepared Statement(stmt.nameが空文字のPrepared Statement)でクエリを投げます。

このときPostgreSQLなら普通に無名Prepared Statementが使えるらしいのですが、どうやらRedshiftは無名Prepared Statementに対応していないようで、コネクションが切られてしまいます。

じゃあどうすればよいかというと、普通にdb.Prepareでstmtを取得すればOKです。pqドライバはdb.PrepareでStmtオブジェクトを生成してクエリを飛ばす場合はコネクションIDから一意のStatement名を生成します。名前付きでPrepared Statementを実行するのでエラーになりません。

today := time.Now().Format("2006-01-02")
stmt, err := db.Prepare(`SELECT user_id, access_at FROM access_log WHERE access_at = $1`)
if err != nil {
    fmt.Println("prepare error: ", err)
    return nil, err
}
defer stmt.Close()

var rows *sql.Rows
rows, err = stmt.Query(today)
if err != nil {
    fmt.Println("query error: ", err)
    return nil, err
}
defer rows.Close()

result := []interface{}
for rows.Next() {
    var days_count, count int
    if err = rows.Scan(&days_count, &count); err != nil {
        fmt.Println(err)
    } else {
        // write something cool business logic here...

    }
}
return result, nil

とまぁそんな感じで、golangでdb.Queryでargs付きのクエリをRedshiftに投げようとして撃沈してしまった方は、普通にdb.Prepareでstmtを作って回避する方法をお試しください。

Comment

2014/09/01

島流しの旅2014

職業は旅人ですが、それでは食っていけないので普段は副業でWeb系のプログラマーをやっているれもんです。そんなわけでちょっと前の話になりますが今年も旅に出ることにしました。

まぁそういう適当な話はさておいて、2年前に関東に移住してからは「1年に最低でも1回はどっかの島へ旅行に行こう」と決めておりまして、(ここのサイトに書かなかったけど)2012年はうさぎの島として一部のうさぎ狂には有名な瀬戸内海の大久野島、2013年は噴火しすぎてもはや九州と地続きになった鹿児島県の桜島に行っていました。

さぁ! 今年はどこに行こうかな! ということでぼくの頭の中には長崎県の五島列島(福江)に行こうというイメージが出来ていたんですが、会社の九州出身の同僚に福江の話を聞こうとおもったら「あー島ならあそこいいですよ、直島」と先手を打たれてしまい、話を聞くことに。ちゃんと聞いたらどうやら島全体がアートの島みたいな打ち出し方をしているとかいう話なので、面白そうだなーということで予定を変えてそっちに行ってみることにしました。だって旅なんだもの。

ということで、8月上旬に直島に行ってきました。たまったマイルで香川まで行くので飛行機だけ4日前にギリギリで予約して、前日にググって行き先のことを調べたらどうやらART SETOUCHIみたいなコンセプトで3年に1回国際芸術祭をやったり、いろんな島に常設のアート作品があるらしいので急遽近くの島にも行ってみようみたいな感じになりました。

直島

土曜の朝、良い天気に恵まれて朝一の便で羽田を飛び立ったんですが、香川に着いたらめっちゃ雨降っててテンションが下がりました…。が、天気予報みても晴れる気配もないしテンション下げててもしかたがないということで直島へ。高松港から直島に行くのはフェリーと高速船があったんですが、値段が倍くらい違うのでとりあえずゆっくりフェリーで行きました。

のんきだな

島からは日帰りで宿は高松だったんですが、この時点では帰りの船の時間を見てなかったという無計画さでした。都会生活が長くなると電車なんて数分待てばすぐ来るみたいな感じで感覚がマヒしますが、その感覚で地方に行くと大変な目に遭うわけです。高校時代まではバスが1時間に2本程度の片田舎に住んでいたのに、その感覚すっかり忘れておりました。

そんなわけで、11時すぎに直島に到着。鎌倉の自宅を出たのは朝5時半なので大体5時間半で到着という感じです。島内の移動は基本的に自転車かバスか徒歩ですが、この日は雨でなるべくバスで楽したい感じです。通常のバスルートだと一番奥になるベネッセアートサイト直島の一番奥の地中美術館というのがあるのですが、今回は貴重な滞在時間をなるべく移動に使いたくないので1日1回お昼の12時過ぎに港から地中美術館直通のバスを狙いました。

とりあえず腹ごしらえを…ということで港から適当に歩いてたら見つけたCafe Little Plumというところでお昼ごはんにドライカレーを食べて、地中美術館へ向かいました。

地中美術館は3人のアーティストの作品+建物自体が作品という感じでそれぞれ個性があるのですが、やっぱり個人的に一番よかったのはジェームズ・タレルの光と空間で表現された作品です。空間を切り取ってそこに光をおいたみたいな感じのやつ、何回みても不思議体験で、たぶん一生忘れないレベルで心に焼き付きました。ちなみにホントに心が動いたので「アフラム、ペール・ブルー」は2回並んで見ました。タレルに限らず基本的に半地下で入ってくる自然光で見え方がかわる作品が多かったので、もっかい天気が良い日に行きたいなぁという感じでした。

その後はシャトルバスを使って李禹煥美術館、ベネッセハウスミュージアムと巡り、家プロジェクトへ。その時点でもう15時すぎになっており、帰りの船とバスの時間の関係で家プロジェクトを全部まわれるほどの時間はなかったのですが、地中美術館でタレルの作品がすごくよかったのでタレルの作品がみれる南寺を優先して近くのところも見るという感じで回りました。

まーそんなわけであっというまに帰りのフェリーの時間。直島はベネッセハウスしか泊まるところがないのかと思ってましたが、どうやら宮浦港付近には普通に旅館や民宿とかもあるっぽいので、次は天気のいいときに島に泊まったほうがいいなーという感じでした。今回は1回目なので広く浅くという感じでしたが、やっぱ地中美術館のナイトプログラムとかも行ってみたいですしね。

あと、晩ご飯は歓楽街に出かけてふらっと入ったお店で珍しく一人でビール飲みながらおいしくいただきました。

豊島・犬島

2日目の日曜日は直島のそばにある豊島、犬島に行きました。

お目当ては犬島の精錬所なんですが、犬島は島自体が小さくて2時間ちょっとで大体見て回れるらしいのと、高松港から行くには豊島を経由しなければならないということで豊島もついでに回る感じです。が、寝坊しました。寝坊したというか、前日に船の時間を調べてなかったので好きなだけ寝て、起きてから船の時間調べたら「かーっ、あと1時間早く起きてれば朝イチの船に乗れたわーっ、かーっ」みたいな感じだったんですけどね。

とりあえず寝坊したとはいえまだ午前9時。あわてる時間ではない、ちゃんと回れるはず…ということで船の時間をちゃんとメモって出かけました。直島と違って豊島、犬島はそんなに船の本数が多くないので、下手に乗り損ねるとそのまま島で遭難という感じなのでマジで注意が必要です。まぁ旅行で乗る予定だった交通機関に乗り遅れたことほぼないのでそこはあんまり心配してなかったですが。

でも、天気は本当に悪かった。

ということでまず高松から豊島へ。豊島から犬島にいく船まで滞在時間が50分あるので、家浦港からすぐ近くにある豊島横尾館へ。これなんも下調べしてなくてどんなものがあるか全然しらなかったんですが、エキセントリックな作品と源流的なテーマでかなりよかったです。生と死をテーマにする作品ってどうしても見てて重くなる傾向があると思うんですが、そういうのがなかった。

この日も天気が本当に悪くてほとんどだれもいなかったんですが、その分係員の人が丁寧に説明してくれて、なるほどね! なるほどね! と納得ずくめみたいな感じで観てきました。この豊島横尾館が出来たのは昨年(2013年)らしいので、まだ行ったことある人がそんなに多くないと思いますが、30分かからずに観れるわりにいろいろと刺激があるのでオススメです。絵も楽しめるしインスタレーションも楽しめる、よいところでした。特にトイレのインスタレーション、あれたまたまトイレに行きたかったので気付いたけど順路からちょっと外れてるところにあるので気付かずに通り抜けちゃうともったいないのでトイレまで作品になってることを忘れないようにしとくとよいです。

その後は犬島へ。犬島の滞在時間は2時間30分ですが、無理なく回れました。まずはお待ちかねの精錬所へ。行ってみると、入り口からしてなぞのレンガのオブジェの山みたいなやつで廃墟感を醸し出してました。わざわざこれアート施設にするためにたくさん積んだとも思えないしなんでこんなことになってるんだ…と思いましたが、係員の説明でただのレンガではなく、精錬の時にでてくるスラグ(鉱滓)で出来たレンガだそうで、それを積んであったという話を聞いてなるほどーと。たしかに触れてみるとひんやりしてました。

あいにくの天気ながらも精錬所の他の犬島の家プロジェクトも一通りまわり、ちょうど2時間くらいで港に戻って来て、ごはん食べてなかったので犬島ぜんざいを食べました。この犬島ぜんざい、かぼちゃとそうめんが入っていて、かぼちゃはともかくそうめんを甘い汁とともに食べたことがなかったので結構不思議な体験の食べ物でした。とにかく麺類なのに甘いっていう体験が不思議すぎてその鮮烈な記憶しか残っていない…という食べ物でしたが、さすがそうめんだけあってちょっとお腹膨れました。

その後、犬島から豊島に戻ってさて豊島美術館へいくぞーと思ってたんですが、その時間バスがないんですよ。犬島から戻ってきて15:45に豊島の港に着いて、高松に戻る船が17:20に出るので1時間半以上時間あるので豊島美術館いって戻ってくるくらいの時間はあるなーと思ってたんですが、バスが1時間に1本くらいしか走ってなくて、港から出てるバスの時間が15:11、16:28という感じでした。15:11のやつはまだ島に着いてないので当然乗れなくて、16時半のやつに乗るとずーっと乗ってバスの中から外を眺めて17時に港に戻ってくることしかできないということで、バスでいくのはムリです。

でも徒歩でいけるのでは…? と思って調べたんですがどうやら4kmくらいあるらしく、普通に歩くと片道1時間コースなので徒歩もムリ。あとレンタサイクルがあるんですが、この日は雨降っててちょっと自転車乗ってる場合じゃないみたいなかんじなのでおとなしくフェリー乗り場で1時間半待ちぼうけしてました。

まぁこんなこともあるよねー。しかたないしかたない。これちゃんと朝7時くらいに起きて朝イチの船に乗ってればちゃんと回れたのかなぁ…っていうのは気になるところですが、それちゃんと調べたところで寝てた時間が戻ってくるわけでもないし、また行くことがあればその時は参考にしよう…という反省だけして高松に帰ってきました。

2日目の晩ご飯は、ライオン通りからちょっとはずれたところにあるふみやというお好み焼きやさんできも玉焼き。植物性じゃなくて動物性の背脂でこんがり焼いた臓物入りのお好み焼きが出てきて、皿なし、箸なしでお好みヘラで鉄板上から直接食べるというワイルドなスタイル。あとお酒を一切出してないというストイックさもあってなかなかよいなーと思いました。まぁなんだ、(見たことないけど)孤独のグルメとかに出てきてもいいんじゃないでしょうか…たぶん。〆でうどん食べようと思ったんですが、行こうと思った店がやってなくてそのまま晩ご飯おわりとなりました。

金刀比羅宮

さて3日目です。2泊3日旅行なので最終日、帰りの飛行機は高松空港16:35ということで、島に行くほどの時間はないねってことで普通に香川の観光にでかける予定でした。とはいえ行く前は香川って何があるの…? うどんしか知らないよ…と思ってたんですが、初日に空港から高松市街へ向かうときにこんぴらさんと書かれた看板を見てしまったのです。こんぴらさん! オレ知ってる! N64のゴエモンでめっちゃ階段登ったやつだ! よし行ってみるか! ということでこんぴらさん参りへ行きました。

高松駅からこんぴらさんへのふもとへはJRでいく方法とことでんで行く方法があってどっちでも琴平駅で降りればOKということだったんですが、こういうときはちょっと時間かかってもローカルな電車に乗った方がいいよねってことでことでんで出発。ちなみにこの日は高知に1000mmの雨が降った週末で、四国のJRもいろんな路線が運休しまくってて高松から琴平までは電車あるけどそれより先は運休みたいな感じで大変でした。

さて、小一時間電車に揺られて始発駅から終着駅まで乗ってこんぴらさんのふもとに到着です。この日は高知のほうはまだ天気悪そうでしたが香川では運良く雨がほぼ降ってなくて、なんとかこんぴらさんに登れそう。さっそく1368段登って奥社を目指します。

最初の100段くらいは余裕で登ってたんですが、200段くらい上ったところで気付きました。ここの階段、容赦ない…。なにが容赦ないって、大体こういう段数の多い階段って1段がそんなに高くないんですよ。ほらお年寄りとかにも配慮して1段のステップをそんなに高くしないみたいな。しかしこんぴらさんの階段はそんなことなくて、普通の駅の階段よりも1段の段差があるというなかなかハードな階段でした。えーこれこのペースで1300段もあるの…? マジで…? と思いながら登り続けます。

こんぴらさんの階段は最初登ってるうちは階段脇に普通に売店があって、この売店どこらへんまであるのかなぁという感じだったんですが、いくつか鳥居をくぐってデカい門(大門/365段)を通過する頃には売店がなくなります。ここからが本当の勝負というところですね。大門をくぐった後は石畳になっててゆるやかな坂道になって所々階段がある感じです。ここはどうやら(後から調べたら)桜並木らしいのですが、真夏なのでそんなことには気付くわけもありませんでした。

で、500段上ったところでなんと資生堂パーラーが出現。うわーもう既にだいぶ汗だくだしパフェ食べたいわーと思ったんですが、この時点で既に12時過ぎてまして、時間を逆算すると16:30に飛行機に乗るにはこんぴらさんを15:00すぎに離れる必要があり、14時には汗を流すために温泉に入っている必要があって、そのためには奥社には13時くらいには着いている必要がある…という感じで計算していくとパフェ食ってる時間などないのでした。

実際の所奥社いくなら2時間は見る必要があると言われていますが、まさにその通りですね。ぼくはまだ(こんぴら勢としては)若い方なので実際に上り下りするのは合計1時間半程度で済んでますが、せっかく奥社行って3分とかでまた降りるのももったいないですし、そこは時間に余裕をもったほうがよいですね。実際、奥社で30分くらいのんびりしてたので、結局登り始めから降りてくるまでで2時間以上かかっています。

資生堂パーラーの誘惑に勝ってさらに登り続けると785段で本宮に到着です。とりあえず参拝して、さらに奥社を目指します。ちなみにほとんどの人は本宮で参拝したらそのまま降りちゃう感じです。奥社行く人は若くて物好きな人が多い感じでした。なお、階段登ってる途中に幸福の黄色いお守りみたいな看板が何回か出てきますが、それをゲットできるのもこの本宮です。そんな感じでだいたい本宮までいけばOKみたいな感じのようですね。

さて、奥社まではあと583段なんですが、段数よりも結構距離があります。奥社への道の前半はほとんど階段のない上り坂の山道という感じでした。途中、いくつか神社がありますが、基本的には立ち入り出来ないのでそのまま通過してだいたい1000段近くまでゆるゆると登っていくと、状況が急変します。

な、なんかいきなり階段しかない感じになったな…あ、赤い建物があるからあれがゴールかなーと思ってそこまでいってみると、あずまや(1098段)でただの休憩スペースでした。そこから折り返してさらに階段を上ると手水舎(1261段)があり、やっとここで手水を清めるのか!! みたいな感じになりますが、これが見えたらあとはラストスパート。さらに100段ほど上って奥社の厳魂神社に到着です。

本宮では黄色いお守りを売ってましたが、奥社では色違いの赤いお守り、青いお守りが売られています。いわゆる色違いレアってやつです。そんなわけでせっかく登ってきたんだしということで青いやつをゲットして、眼下に広がる讃岐平野を見渡して汗が引いたところで下山開始。帰りはすいすいですが、前日からの雨で階段が結構滑りやすいので注意しつつ降りて、琴参閣という温泉で日帰り入浴してソフトクリームを食べて飛行場へ。

とまぁそんなわけで、あんまり…というか全く天気に恵まれなかったですが、ぼくがいつも旅行するときに大切にしてる「インスピレーションを得るために旅行をする」という観点でいくとなかなか良い旅行でした。なにしろ四国にちゃんと上陸したのはこれが初でした(2年前の尾道旅行のついでにしまなみ海道渡ったときに50分だけ愛媛に滞在したことがあった)。それだけでも価値があったなぁという感じです。

うるさい。

Comment