digdag
を使ってログから中間テーブルを起こそうとした時に起きた話です。
hive
の独特な書き方みたいなところで引っかかりました。
結論
with
句が終わって実際にselect
するところに
-- DIGDAG_INSERT_LINE
を突っ込め!
やろうとしたこと
すでにTD
上にある大量レコードのテーブルから、サマリーをした中間テーブルを作ろうとしました。
before(実データではtime
はtimestamp
ではなくlong
が入ってます)
user_id | event | time |
---|---|---|
1 | add | 2017/12/17 06:34 |
1 | add | 2017/12/17 06:35 |
1 | change | 2017/12/17 06:36 |
1 | add | 2017/12/17 06:37 |
1 | delete | 2017/12/17 06:49 |
1 | add | 2017/12/18 06:50 |
after
user_id | event | date | count |
---|---|---|---|
1 | add | 2017/12/17 | 3 |
1 | add | 2017/12/18 | 1 |
2 | add | 2017/12/17 | 1 |
こんな感じ。
抽出クエリ
with log as (
select
user_id
,event
,td_time_format(time,'yyyy-MM-dd','jst') as date
from
event_log
)
select
user_id
,event
,date
,count(1)
from
log
group by
1,2,3,
なんてことはないですね。
実際にtd上で実行しても通りました。
digってみる
timezone: Asia/Tokyo
+transport_raw:
_export:
td:
source_db: test
to_db: event_log
+drip_user_event_cnt:
td>: queries/user_event_cnt.sql
database: ${td.source_db}
engine: hive
create_table: ${td.to_db}.user_event_cnt
td wf run --rerun user_event_cnt.dig
えいっ!
…
あれエラー出ましたね。
FAILED: ParseException line 2:0 cannot recognize input near 'with' 'log' 'as' in select clause MapReduce time taken: 0.195 seconds
予約語関連でエラー?そんなバカな
というわけで、もろもろ調べてみました。
原因判明
digdag
のcreate_table
コマンドが何をしているかというと、
指定したsql
の前にこの一文を発行しているようです。
```INSERT OVERWRITE TABLE test
.`user_event_cnt`
`INSERT`の後に`WITH`句がおけないという`hive`のローカルルールに引っかかりエラーが起きていました。
実際に`select`をするところの前に`-- DIGDAG_INSERT_LINE`を記述してあげないといけません。
```sql:user_event_cnt.sql
with log as (
select
user_id
,event
,td_time_format(time,'yyyy-MM-dd','jst') as date
from
event_log
)
-- DIGDAG_INSERT_LINE
select
user_id
,event
,date
,count(1)
from
log
group by
1,2,3,
これでおっけい!
実行結果もうまくいきました。
余談
td
といえば、クエリをpresto
とhive
で選べますが、presto
ではどうなってるでしょうか。
presto
では、with
の前でinsert
が記述されても特に問題なく実行されます。
なので気にせずにinsert
とできると思います。
hive
でクエリ書き換えたけど動かねーぞ!となったら、ぜひ試してみてください。