よしたく blog

IT技術を中心に様々なことを書いています

オホーツク海沿いドライブ旅行記 1日目 - 稚内へ

紋別から稚内

昼に紋別空港に着き、レンタカーを借りて稚内へ向かった。
天気は曇りで、翌日からは荒れそうな気配があった。

道はほとんど海沿いで、横には牧場や草原が広がっていた。途中で風車も目立ち、北海道らしい景色が続いた。
観光らしい寄り道はしなかったが、セイコーマートに何度も立ち寄ったので、運転は3時間ほどかかった。

宗谷岬

稚内に入る前に宗谷岬に立ち寄った。
奥さんと記念碑の前で写真を撮り、日本最北端に来たことを実感した。観光客が多く、意外とにぎわっていたのも印象的だった。

滞在は10分ほどだったが、水平線の先にうっすらとロシアが見えたのは不思議な感覚だった。

夜ごはん

夜は稚内市内の居酒屋「浪漫」へ。どこも予約でいっぱいだったが、なんとか入ることができた。

tabelog.com

長距離ドライブのあとに飲んだビールがとにかく美味しかった。地元のタコ料理も良く、最北の酒蔵「国稀」の日本酒も一緒に楽しんだ。

食事のあと、ホテルまでの帰り道に南稚内駅へ立ち寄った。夜の駅前は静かで、最北の街の日常を少しだけ垣間見た気がした。

宿泊

駅から戻って、この日は「ホテル奥田屋」に宿泊した。駅に近く、移動の疲れを落ち着いて休めた。

www.hotel-okudaya.jp

1日目を振り返って

この日の一番の思い出は宗谷岬だった。日本最北端に立ち、遠くにロシアが見えたことが強く残った。

稚内の街は思っていたより人が多く、居酒屋も満席でにぎわっていた。南稚内駅を歩いて訪れたことも含めて、最果ての街の雰囲気を少し感じ取れた。

BigQueryの出力フォーマットをprettyjsonに変更する手順

BigQuery の bq コマンドでは、デフォルトの出力フォーマットはテーブル形式が使われます。 このデフォルトの出力形式を.bigqueryrc ファイルを使うことで、件数や行数が多くなっても見やすいprettyjson形式に変更します。

.bigqueryrc ファイルを作成する

ホームディレクトリに .bigqueryrc ファイルがなければ作成します。

touch ~/.bigqueryrc

エディタでbigqueryrcファイルを開きます

vim ~/.bigqueryrc

query セクションに設定を追加

--format=prettyjson

設定が反映されているかの確認

設定前

$ bq query "SELECT CURRENT_DATE()

+------------+
|    f0_     |
+------------+
| 2025-04-11 |
+------------+

設定後

$ bq query "SELECT CURRENT_DATE()"

[
  {
    "f0_": "2025-04-11"
  }
]

数が少ないとあまり効果を実感できませんが、行や列の数が多いと...

$ bq query 'SELECT * FROM bigquery-public-data.covid19_open_data.covid19_open_data LIMIT 10'
[
  {
    "adult_female_mortality_rate": "73.319", 
    "adult_male_mortality_rate": "171.82", 
    "age_bin_0": "00-09", 
    "age_bin_1": "10-19", 
    "age_bin_2": "20-29", 
    "age_bin_3": "30-39", 
    "age_bin_4": "40-49", 
    "age_bin_5": "50-59", 
    "age_bin_6": "60-69", 
    "age_bin_7": "70-79", 
    "age_bin_8": "80-", 
    "age_bin_9": null, 
    "aggregation_level": "0", 
    "area_rural_sq_km": "219047", 
    "area_sq_km": "238400", 
    "area_urban_sq_km": "15594", 
    "average_temperature_celsius": "5.044444", 
    "cancel_public_events": "1", 
    "comorbidity_mortality_rate": "21.4", 
    "contact_tracing": "1", 
    "country_code": "RO", 
    "country_name": "Romania", 
    "cumulative_confirmed": "1346240", 
    "cumulative_confirmed_age_0": "36379", 
    "cumulative_confirmed_age_1": "74690", 
    "cumulative_confirmed_age_2": "133053", 
    "cumulative_confirmed_age_3": "224942", 
    "cumulative_confirmed_age_4": "260809", 
    "cumulative_confirmed_age_5": "233996", 
    "cumulative_confirmed_age_6": "194750", 
    "cumulative_confirmed_age_7": "124220", 
    "cumulative_confirmed_age_8": "63227", 
    "cumulative_confirmed_age_9": null, 
    "cumulative_confirmed_female": null, 
    "cumulative_confirmed_male": null, 
    "cumulative_deceased": "39209", 
    "cumulative_deceased_age_0": null, 

    ...(中略)

このようにとても見やすくなります

2024年の振り返り

今更だけど2024年を備忘録として振り返っておく。

私生活

2024年は、結婚式とその準備が私生活のすべてになった。奥様とは2023年10月に結婚し、年が明けた2024年1月に「そろそろ結婚式に向けて動き出したほうがいいかもね」と会話し、結婚式関連の相談カウンターへ行った。すると、あっという間に話が進み、気づけば前撮りの日程、結婚式場、挙式の日取りまで決まっていた。

そこからは、ダイエットを継続する日々と、節目ごとに訪れる結婚式関連のイベントをこなしていく日々だった。和装と洋装での前撮り、遠方での結婚式に向けた現地での打ち合わせ……と、気づけばあっという間に時間が過ぎていた。準備も大変だったが、それ以上に大変だったのは体重を5〜6キロ落とすことだった。仕事がほぼフルリモート(週1回出社)のため、普段は家から出ることが少ない。そのため、毎朝早起きして公園を散歩したり、ジムに通ったりと、意識的に運動する時間を作った。結果として、前撮りも結婚式本番も納得のいく形で写真を残すことができ、本当に良かった。式が終わった後は、好きな食べ物やお酒を自由に楽しめて最高だった。

お仕事

エンタメ企業で引き続きデータエンジニアとして働いている。既存のデータ基盤の運用をしつつ、新しいプロダクトのデータ基盤をゼロから構築するという大きな仕事もこなした。このプロジェクトでは、ETLツールの選定や、それを動かす基盤の設計・構築を担当し、さまざまなデータ基盤を参考にしながら、一から作り上げた。転職後は、すでに存在しているデータ基盤の改修が主な業務であり、前職はSIer・SESだったため、完全にゼロから構築する経験は初めてだった。とても貴重な経験になったと思う。 また、メインのデータ基盤以外の部分でも、ドキュメントを整備することの重要性を改めて実感した。長期休暇を取る際や業務の引き継ぎ時に、ドキュメントがなければ他のメンバーに作業を依頼することが難しくなる。そのため、プロダクト外の部分にも気を配ることが大切だと改めて学んだ。もちろん、現在も引き続きデータ基盤の運用・改善に取り組んでおり、より良くしたい点や修正が必要な箇所を見つけながら、楽しく(ときには大変な思いをしながら)日々の業務に取り組んでいる。

その他

2023年と2024年、趣味で集まっているフットサルチームの年間ゴール集動画を作成した。編集には DaVinci Resolve を使用している。 動画は公開しないが、個人的には一昨年より去年と、動画のクオリティと作業効率が向上しているのを実感している。2024年は、テロップやサムネイルにもこだわり、より完成度を高めた。幸いなことに、YouTubeには動画編集の教材が山ほどあり、参考になる表現をすぐに学ぶことができる。そして「これいいな」と思ったら、すぐ自分の動画に取り入れることができる。この学びのサイクルが楽しい。 最近では、この動画編集の経験を活かして、旅行のVlogも撮ってみようかと考えている。

という文章を書いて、生成AIに添削を依頼したら、とても読みやすい文章になった。生成AIで遊ぶのも楽しいです。

追伸

この広告は、90日以上更新していないブログに表示しています。

という広告を見て悲しくなった。ブログを書いていこうと思った

【Dataform】pre_operationsを使ってdelete insertを実現する方法

Dataform では incremental モードを使ってデータを積み上げていくことができます。 しかし、データを積み上げていくことのみしか出来ず、仮に一度実行した処理を再度実行すると同じデータがシンク先に書き込まれます。 要はDELETE INSERT には対応していないということになります。

現時点の Dataform の機能としては対応していないということで工夫が必要になり、それを実現するためにpre_operationsを使います。

pre_operations

pre_operationsは SQLX ファイル内に記述し、テーブルの作成前に実行できる SQL ステートメントです。 Dataform の docs の例 では、一時的なファンクションを作っています。

  pre_operations {
    CREATE TEMP FUNCTION AddFourAndDivide(x INT64, y INT64)
      RETURNS FLOAT64
      AS ((x + 4) / y);
  }

ref: https://cloud.google.com/dataform/docs/table-settings?hl=ja#execute-sql-before-table

ちなみにテーブルの作成後に実行できる SQL ステートメントpost_operationsも存在します。

pre_operationsの中に DELETE 文を記述することで、同じデータが追加されず冪等性のある処理にすることが出来ます。

次は、WITH のサブクエリ内で作ったソースデータを、sample_table に入れている処理です。 pre_operations の中で、2024-05-13 の日付のデータを DELETE する処理を実行しています。 その後、WITH のサブクエリのデータを sink先のtable に insert しています。

ソース元は実際のテーブルへと、また日付は動的に変更できるようにする必要はありますが、これで date 単位でのDELETE INSERTの洗替処理は実行できます。

config {
  type: "incremental",
  schema: "sample_dataset",
  name: "sink_table",
}

pre_operations {
    DELETE FROM ${self()} WHERE date = '2024-05-13'
}

WITH source_table AS (
  SELECT
    DATE('2024-05-13') AS date,
    1 as user_id,
    100 as value,
  UNION ALL
  SELECT
    DATE('2024-05-13') AS date,
    2 as user_id,
    200 as value,
)

SELECT
  date,
  user_id,
  value
FROM source_table
WHERE date = '2024-05-13'

Dataform の公式 GitHub の issue にて質問中...

返事が返ってきませんが、公式 GitHub の issue にて質問をしています。

github.com

現状色々調べた中で pre_operations を使って DELETE INSERT の洗替処理をする方法しかなさそうというところに行き着きました。 公式が提供する機能で同じ処理と結果が得られるのであれば、そちらのほうが嬉しいので実現を待ちたいです。

英語の翻訳はChatGPTがよしなにやってくれるので便利ですね。