astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

企業ロゴの「ロゴパネル」の作り方

f:id:astamuse:20200324153227j:plain

こんにちは。デザイン部の橋本です。

アスタミューゼでは事業規模が大きくなるにつれて、取材をしていただく機会やEXPOなどのイベントに出展する機会が増え、それに伴って広報活動も活発になってきたので企業ロゴのロゴパネルを作ることになりました。

ロゴパネルとは企業ロゴを大きくパネル化したもので、写真撮影の時に手に持って撮影するだけで、企業ロゴの認知度を上げることができるものです。

f:id:astamuse:20200319170731j:plain
完成したアスタミューゼのロゴパネル

使わない時はオブジェとして置いておくだけで、なんだかちゃんとした会社っぽい雰囲気を出してくれます!

しかもデータを作成・入稿するだけでお値段は一枚数千円からとコスパも良好。今回はそんなロゴパネルの作り方についてのお話しです。

ロゴパネルの作り方

1. 印刷業者を決める

まず、ロゴパネルをどこに発注するのか決めます。完成したパネルを思い浮かべて、要件を固めましょう。 パネルが折れないように厚みが欲しい、表面をマット加工にしたい、サイズはだいたいこれくらい…など、使用目的に合わせてなんとなくで大丈夫です。

アスタミューゼのロゴは横長なので、大きめのA1サイズで作成することに決定。(※他の企業さんを調べてみるとA2サイズで作成することが多いみたいでした。)

ある程度厚みが欲しかったのと、表面をマット加工にしたかったので、いくつか業者さんを比較して、今回はアクセアさんに発注することにしました。

アクセアさんの場合、厚さは5mmと7mmから選択できるので、7mmに決定。両面貼りも可能でしたが、片面貼りで問題ないので、片面貼りにするところまでこの時点で決めてしまいました。

2. Illustratorでデータを作る

ではデータを作成していきましょう。

ロゴの周りを囲むように、切り取り線(カットパス)を作ります。この線に沿ってパネルが切り出されるので、ロゴから適度な余白を取ることと、線がガタつかないように気をつけて作っていきます。

  1. Illustratorを起動してA1サイズ(841×594mm)のアートボードに、アスタミューゼのロゴデータを置く
  2. オブジェクト>パス>パスのオフセット で余白部分を作成
  3. パスファインダーで合体して パスの背景→白、パスの線→黒 にする
  4. オブジェクト>パス>単純化 で不要なアンカーポイントを削除

f:id:astamuse:20200324163107j:plain
1. アスタミューゼのロゴデータ(760×113mm)を置く

パスのオフセットは20mm〜40mmを目安に調整すると良いと思います。アスタミューゼはフォントが細めなので、それに合わせて余白も少なめの22mmにしました。

f:id:astamuse:20200324161706j:plain
2. オブジェクト>パス>パスのオフセット で余白部分を作成

f:id:astamuse:20200324164038j:plain
3. パスファインダーで合体して背景と線の色を変更

f:id:astamuse:20200324164600j:plain
4. パスの単純化でアンカーポイントを削減

単純化した後は多少パスがガタついたり、取り除ききれなかった不要なアンカーポイントが残っていたりすると思いますので、パスの調整を行います。このパスを綺麗にする作業くらいしか正直やることがないので、データ作成は本当にあっという間です。

パネルを発注する前に、出来上がったデータを等倍で印刷して、サンプルを作ってみます。

f:id:astamuse:20200324111511j:plain
等倍印刷したロゴ

切り取り線に沿ってハサミを入れて、セロハンテープでくっつけて……できました!

f:id:astamuse:20200324104104j:plain
ロゴパネルのサンプル

良い感じです。気になったところを微調整した後、いよいよデータ入稿です。

3. データを入稿する

ではデータを入稿していきましょう。

アクセアさんのWEB入稿を使うので、アクセアさんのアカウントがない場合は作成してください。 アカウントを作成したら、新規データ入稿よりデータを入稿していきます。

2020年3月現在、アクセアさんのデータ入稿の流れは5ステップです。

  1. 注文内容入力
  2. 配送先入力・支払方法選択
  3. ファイルアップロード
  4. 注文内容確認
  5. 注文完了

1.の注文内容入力では、入稿タイトルと印刷内容を聞かれます。 今回は入稿タイトルをアスタミューゼロゴパネルとし、印刷内容を下記のようにしました。

項目 印刷内容
仕様 切り抜きパネル
用紙 ポスター部分:フォト半光沢紙、パネル:発泡ポリスチレン(厚さ7mm)
加工 切り抜き加工あり
個数 1
サイズ A1(841×594mm)
その他ご要望 ラミネート(マット)加工のオプション付き

あとは配送先と支払い方法を指定し、データをアップロードして完了です。

そしてデータを入稿して数日後、ロゴパネルが社内に届きました。とってもスピーディーな対応で大満足です!

今回発注したロゴパネルの料金は9,460円(税込)でした。店舗に受け取りに行くとあと1000円ほどお安くなるみたいです。

ロゴパネルを作成するくらい事業規模拡大中のアスタミューゼでは、一緒に働いてくれる仲間を募集しています。 採用サイトもありますので、是非ご覧ください!

初めてBigQueryを触って学んだ節約トピックを紹介するよ

みなさんこんにちは。たぶんアプリケーションエンジニアのkjです。

私にはもうすぐ1歳半になる娘がおりまして、リモート勤務の傍ら、ホンヨンデー!って訴えてきます。 その表情、振る舞いが愛おしく(親バカ)、スキマ時間をとって本を読んでいます。

ちなみに、娘の最近のお気に入りはハッピーセットのオマケでついてきた「小学館の図鑑 危険生物」

f:id:astamuse:20200315225806p:plain
お気に入りの本は「小学館の図鑑NEO 危険生物」一度手にとったら、もう離さないよ!

こちら、世界の様々な人食いザメや凶暴なピラニアなどが掲載され、海にはアブナイ生き物がいるよ!気をつけてね!と紹介されているダイジェスト本です。

自分の娘ながら嗜好が理解できません。。。

閑話休題

突然ですが、BigQueryって便利ですよね!最近は業務でbqコマンドをよく使っています。bqコマンドとは、ざっくりというと、Google社が提供しているCloudSDKに内包されている、BigQueryのデータを操作するためのコマンドです。コマンドの裏側ではPythonが動いており、GoogleCloudのAPIを叩いています。

ちなみに私、前職はコテコテのJavaエンジニアで、システムはオンプレやろ!って世界に住んでおました。 「くらうど??ナニソレ オイシイノ?」ってところから、都度都度調べながらBigQueryを触っております。 今回は、自分の理解の整理がてら、bqコマンド(+ときどきBigQuery)について、トピックをご紹介したいと思います。

本日のポイント

本日触れないこと

  • BigQuery, GCPとはなにか
  • bqコマンドのインストール方法について。こちらは公式サイトを参照してね!

その他注意書き

  • 以下、bqコマンドでこんなことできるぞ!とドヤりますが、実はBigQueryのWebコンソールにて特殊な操作することなく表示されるものが多いです。

    ですので、BigQueryにこなれている方は、コマンドでもできるんだフーンとしていただければ。まぁでも、コマンドでできた方がいろんなツールと連携しやすいので、知っておいて損はないよね!

  • 2020年3月時点での内容になりますので、将来変わる可能性もあります。
  • GoogleCloud Japanのブログにて弊社が紹介されております。むしろそちらをご覧ください。

    cloud.google.com

BigQueryの料金について把握する

さて、はじめてBigQueryを触るにあたって、まず気になったのが料金です。ネットにはクラウドサービスでウン万円溶かしたって記事は事欠きません。ちなみに私、しらないお店はお金にビビって入れないタイプです。

なので、どういう時に課金される、されない、もしくはどれくらい課金されるか、を調べました。 結論、扱うデータサイズによりますが、よっぽどな操作をしない限りは大丈夫かと思っています。 2020年3月時点でざっと把握したカンジは以下となります。(なお、正確な情報は公式サイトをご参照ください)

課金タイプは2種類

BigQueryの課金パターンとして以下2つとなります。カッコ内の金額は参照値。実際は操作内容やリージョン、契約内容、無料枠などによって変わってきます

  • 保存しているデータ量に応じて課金(月に$0.020/GB @ US multi-region)
  • クエリを実行した際に読み込んだデータ量に応じて課金($5.00/TB @ US multi-region)

    ただし、読み込んだ1テーブルあたり最小サイズは10MBで、以降1MB単位(端数は四捨五入)で課金。つまり1テーブル読み込むごとに10MBが課金対象となる

なお、BigQueryでは内容によってはクエリ無料のものがあります。全部あげるとキリがないですが、私がよく使う無料枠のものは以下のようなものになります。(以下、保存データに関する課金は考慮していません)

  • bq ls, bq show などのデータを直接参照しない閲覧コマンド
  • bq head, bq cp によるフィルタリングや加工を伴わない照会コマンド。(コピーは照会とは違うけど、readしても課金されないよ!という意味でここに)
  • bq mk, bq rm などのテーブル作成、および削除。

    bq queryで実行するCREATE (OR REPLACE) TABLE, DROP TABLEなども、テーブルをSELECTしていなければ課金されないよ!

一方で有料となるクエリは以下のようなものがあります。詳細は以降で一部紹介します。

  • bq query にてテーブルをSELECTするもの
  • bq query にて、「INSERT INTO 〜〜 SELECT 〜 FROM 〜〜」のようにテーブルSELECTしてレコード挿入するもの
  • bq query にて、「UPDATE SET 〜〜」や「DELETE 〜〜」するもの。

bqコマンドを色々触ってみる

さてここまでウンチクを記載してましたが、実際のデータを参照しながらbqコマンドを触ってみたいと思います。

プロジェクトの作成、CloudSDKのインストール

詳細の手順は公式サイトをご参照ください。 なお公式サイトでは、サンプルデータセットを利用したクイックスタートも載っています。GCPの1年間の無料クレジットがある方はこちらを試すのもありかと思います。

また、以降のクエリはStandardSQLを前提にしています。bqコマンドの設定方法は以下をご確認ください。 cloud.google.com

bqコマンドのヘルプをみてみる

bqコマンドにはヘルプが用意されています。とりあえずbqだけ打ってみると(ただし、CloudSDKインストール後、初めて実行する場合はアカウントの設定等、諸々初期設定が行われる場合があります)

$ bq
Python script for interacting with BigQuery.
USAGE: bq.py [--global_flags] <command> [--command_flags] [args]

Any of the following commands:
  cancel, cp, extract, get-iam-policy, head, help, init, insert, load, ls, mk, mkdef, partition, query, rm, set-iam-policy, shell, show, update, version, wait

cancel          Request a cancel and waits for the job to be cancelled.

# (以下省略)

という風に、bqで指定できるサブコマンドとその概要が表示されます。ちなみに上記出力の最後に以下のような表示があるはずです。

Run 'bq.py --help' to get help for global flags.
Run 'bq.py help <command>' to get help for <command>.

試しにbq --helpを打ってみると、

$ bq --help
Python script for interacting with BigQuery.
USAGE: bq.py [--global_flags] <command> [--command_flags] [args]

Global flags:

/<PATH TO SCRIPT>/bq.py:
  --api: API endpoint to talk to.
    (default: 'https://www.googleapis.com')
  --api_version: API version to use.

# (以下省略)

という風に、違う内容が表示されました。(ちなみにbq helpを打つとbqと同じ結果が表示されます)

つまり、bqコマンドには大きく2種類のヘルプがあります。bqの後に続けるサブコマンドに関するヘルプと、bqコマンドのフラグに関するヘルプです。 前者についてはWebドキュメントにも詳細が記載されているので利用する機会は少ないのですが、フラグについてはWebドキュメントに記載されていないものもあり、中には便利なものがあります。是非見てみてください。

動作環境

$ sw_vers
ProductName:  Mac OS X
ProductVersion: 10.15.3
BuildVersion: 19D76

$ bq version
This is BigQuery CLI 2.0.54

今回扱う確認用データセットの作成

まずはデータセットを作成して、検証用のデータを登録します。

$ bq query <<-EOF
> CREATE TABLE test_kj.sample
> AS
>     SELECT 1 AS id, 'a' AS key1, 'aa' AS key2, 'aaaa' AS key3, 'aaaaaaaa' AS key4
> UNION ALL
>     SELECT 2 AS id, 'b' AS key1, 'bb' AS key2, 'bbbb' AS key3, 'bbbbbbbb' AS key4
> UNION ALL
>     SELECT 3 AS id, 'c' AS key1, 'cc' AS key2, 'cccc' AS key3, 'cccccccc' AS key4
> UNION ALL
>     SELECT 4 AS id, 'd' AS key1, 'dd' AS key2, 'dddd' AS key3, 'dddddddd' AS key4
> EOF
Waiting on bqjob_r1367xxxxxxxxxxxxxxxxxxxxxxxxxxxxx_1 ... (0s) Current status: DONE
Created 【Project Name】.test_kj.sample

ちなみに「Waiting on」の後に表示されている文字列(上記のbqjob_r1367xxxx....)が、そのクエリを実行しているジョブIDになります。ジョブIDは後でその処理を照会する場合に利用します。

データの照会

テーブルの確認、データの確認にはそれぞれbq show, bq headを利用します。

$ bq show test_kj.sample
Table 【Project Name】:test_kj.sample

   Last modified        Schema        Total Rows   Total Bytes   Expiration   Time Partitioning   Clustered Fields   Labels
 ----------------- ----------------- ------------ ------------- ------------ ------------------- ------------------ --------
  14 Mar 17:58:23   |- id: integer    4            124
                    |- key1: string
                    |- key2: string
                    |- key3: string
                    |- key4: string

$ bq head test_kj.sample
+----+------+------+------+----------+
| id | key1 | key2 | key3 |   key4   |
+----+------+------+------+----------+
|  3 | c    | cc   | cccc | cccccccc |
|  1 | a    | aa   | aaaa | aaaaaaaa |
|  2 | b    | bb   | bbbb | bbbbbbbb |
|  4 | d    | dd   | dddd | dddddddd |
+----+------+------+------+----------+

なお、bq headでデータを読み込んだ場合は課金されませんが、bq queryでテーブルを読み込んだ場合は課金対象となります。--dry_runオプションをつければ、クエリを実行することなく、実行した場合に何byte読み込むかを確認できます(下記の例では124byte)。

$ bq query --dry_run "SELECT * FROM test_kj.sample"
Query successfully validated. Assuming the tables are not modified,
 running this query will process 124 bytes of data.

--dry_runオプションをつけ忘れた場合、後で読み込んだbyte数を確認するには、ジョブIDがわかっていればbq show -j <ジョブID>で確認できます。

$ bq show -j bqjob_r1367xxxxxxxxxxxxxxxxxxxxxxxxxxxxx_1
Job 【Project Name】:bqjob_r1367xxxxxxxxxxxxxxxxxxxxxxxxxxxxx_1

  Job Type    State      Start Time         Duration                      User Email                    Bytes Processed   Bytes Billed   Billing Tier   Labels
 ---------- --------- ----------------- ---------------- --------------------------------------------- ----------------- -------------- -------------- --------
  query      SUCCESS   14 Mar 17:57:16   0:00:00.927000   account@【Project Name】.iam.gserviceaccount.com   0                 0              1

Created 【Project Name】.test_kj.sample

上記はsampleテーブルを作成した際のジョブIDを指定したものです。今回のCREATE TABLEの場合は「Bytes Processed」、「Bytes Billed」が0であることが確認できます。(「Billing Tier」は、過去は利用されていたけど現時点では課金に利用されていない項目のようです)

bq head で使える表示オプション

bq headコマンドの表示結果はテーブル形式で人にとっては見やすいですが、コマンドで連携したり、ファイルに出力する場合には扱いづらいです。この場合はbqコマンドのオプションである--formatを利用できます。 例えば、CSV形式にする場合は以下のように--format=csvを指定します。

$ bq head --format=csv test_kj.sample
id,key1,key2,key3,key4
3,c,cc,cccc,cccccccc
1,a,aa,aaaa,aaaaaaaa
2,b,bb,bbbb,bbbbbbbb
4,d,dd,dddd,dddddddd

json形式も指定できます。改行やインデントがない--format=jsonの他、人に見やすくインデントされた--format=prettyjsonもあります。 たとえば、

$ bq head test_kj.sampleo_long
+----------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
|                                            value1                                            |                                         value2                                          |
+----------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+
| toooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo LONG!! | sample2                                                                                 |
| sample1                                                                                      | toooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo long! |
+----------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------+

テーブル形式の場合、1レコードのある値が長いと、その値で1列の幅が調整されてしまい見づらいですが、

$ bq head --format=prettyjson test_kj.sampleo_long
[
  {
    "value1": "toooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo LONG!!",
    "value2": "sample2"
  },
  {
    "value1": "sample1",
    "value2": "toooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo long!"
  }
]

インデントしたjson形式なら多少は見やすくなります。

その他bqのオプションとして、デフォルト表示件数100件を変更できる-n <表示件数>オプション 1 があります。またbq headのオプションとしては、表示する列を指定できる-c <カラム1>,<カラム2>,...オプション、表示開始のレコード位置を指定できる-s <表示開始インデックス>オプション(-s 0とすれば、1行目から表示される)があります。 --formatオプションとこれらを組み合わせれば、テーブルをちらっと閲覧したいケースは大方カバーできるかと思います。

SELECT文に関するトピック

ここまでbq headを推してきましたが、SELECT文を使ってレコードをフィルタしたり、値の変換等、諸々操作したい場合もあるかと思います。 SELECTするにあたって、表示する列を限定することで課金額を節約できます。

たとえば、以下のように、とりあえずSELECT *すると、、、

$ bq query --dry_run "SELECT * FROM test_kj.sample"
Query successfully validated. Assuming the tables are not modified,
 running this query will process 124 bytes of data.

全ての列の全データが課金対象になります。

なお計算式は以下の通り。データ型によるサイズは BigQuery の料金  |  Google Cloud を参照。

id=1のレコードについて、

  • id列はinteger型なので、8 byte
  • key1列はstring型の'a'なので、2 + 1 = 3 byte
  • key2列はstring型の'aa'なので、 2 + 2 = 4 byte
  • key3列はstring型の'aaaa'なので、 2 + 4 = 6 byte
  • key4列はstring型の'aaaaaaaa'なので、 2 + 8 = 10 byte

id=1のレコードの読み込んだbyte数は 8 + 3 + 4 + 6 + 10 = 31 byte

id=2,3,4も同様に計算して、全4レコードを読み込んだbyte数は 31 + 31 + 31 + 31 = 124 byte

ところが、実際に閲覧したい列はidとkey1のみだったとすると、この2つの列に絞ってSELECTすることで、

$ bq query --dry_run "SELECT id, key1 FROM test_kj.sample"
Query successfully validated. Assuming the tables are not modified,
 running this query will process 44 bytes of data.

となり、元のクエリと比べて読み込みサイズが3分の1になりました! この場合は (id列の 8 byte + key1列の 3 byte) * 4 レコード = 44 byte

まぁこの例の場合だと大したサイズではないので有り難みは全くないのですが、何百万、何千万件と扱うデータサイズが大きくなるとじわじわと懐に響いてきます。

あと、公式ドキュメントにも記載されていますが、WHEREやLIMITによるレコードの絞り込みは課金に影響しません。

$ bq query --dry_run "SELECT id, key1 FROM test_kj.sample WHERE id = 1"
Query successfully validated. Assuming the tables are not modified,
 running this query will process 44 bytes of data.

$ bq query --dry_run "SELECT id, key1 FROM test_kj.sample LIMIT 1"
Query successfully validated. Assuming the tables are not modified,
 running this query will process 44 bytes of data.

ただ、私個人的な体感ですが、LIMITで表示件数を絞るとクエリの応答速度が速くなるようです。 特にbqコマンドのデフォルト表示件数は100件ですが、LIMIT 100があると応答速度が速くっているカンジがします。(もちろん、クエリ結果の件数が多い場合です) なので、結果件数が多い場合は、bqコマンドの-nオプションと合わせてLIMITの数を合わせるとよいでしょう。

ちなみに余談ですが、SELECT COUNT(*)SELECT COUNT(1)はSELECT文ですが、課金されません。

$ bq query --dry_run "SELECT COUNT(*) FROM test_kj.sample"
Query successfully validated. Assuming the tables are not modified,
 running this query will process 0 bytes of data.

$ bq query --dry_run "SELECT COUNT(1) FROM test_kj.sample"
Query successfully validated. Assuming the tables are not modified,
 running this query will process 0 bytes of data.

テーブルのレコード件数は、課金されないbq showで確認できるから、ですかね。中々粋なことをしてくれます。

しかし、列を指定すると課金されます。

$ bq query --dry_run "SELECT COUNT(id) FROM test_kj.sample"
Query successfully validated. Assuming the tables are not modified,
 running this query will process 32 bytes of data.

こっちはCOUNT(DISTINCT <列名>)とすると、単純なレコード数ではなくなるから、ですかね??

あるテーブルの全レコードを削除するぞ。もちろん課金なしで

ちょっと長くなってきました。ここからはちょっとした小ネタを紹介します。

テーブルの全レコードを削除する場合、普通のDBと同じ感覚でDELETE FROMを実行すると、、、

$ bq query --dry_run "DELETE FROM test_kj.sample"
Error in query string: DELETE must have a WHERE clause at [1:1]

という風に、DELETE文を実行する場合はWHERE句が必須だよ!と怒られます。仕方ないのでトートロジーな条件を入れてあげると、、、

$ bq query --dry_run "DELETE FROM test_kj.sample WHERE TRUE"
Query successfully validated. Assuming the tables are not modified,
 running this query will process 124 bytes of data.

てカンジで、全レコードのサイズが課金対象になります。

$ bq query --dry_run "DROP TABLE test_kj.sample"
Query successfully validated. Assuming the tables are not modified,
 running this query will process 0 bytes of data.

テーブルそのものを削除する場合は課金されないのに、全レコード削除は課金対象なんかい!と。世知辛い世の中ですね。

ところで、我々はテーブルの削除と作成は課金されないことを知っています。ならば、これを上手く活用する方法はないか?と。

結論、あります。 jqコマンド 2 を利用すれば楽にできるので、それを紹介します。 なお、jqコマンドの説明は省略しますが、一言でいうとJSONフォーマットをよしなに扱えるコマンドです。詳細はぐぐってください。(だんだんテキトーになってきたな)

$ bq show --format=json test_kj.sample | jq .schema.fields > table_schema_sample.json
$ bq rm -f test_kj.sample
$ bq mk --schema table_schema_sample.json test_kj.sample
Table '【Project Name】:test_kj.sample' successfully created.

1つ目のbq show ... | jq ...にて、テーブルのスキーマに関するjson表記を取得して、それをリダイレクトしてファイルに保存しています。ここでbqコマンドに--forma=jsonオプションを指定しているのがポイントです。こうすることで、jqコマンドで必要な情報のみフィルタできます。 2つ目のbq rmで全レコードを削除したいテーブルを削除しています。 3つ目のbq mkにて、テーブルスキーマを記載したjsonファイルを指定して空テーブルを作成しています。

これにより、課金なしで全レコードを削除することを実現しています。ちなみにNOT NULL制約はスキーマの定義に記載されるので、テーブル作成した際にも再現できます。パーティション等については未確認なのであしからず。。。

まぁそもそも全レコードを削除する、というユースケースが実際あるのか?と。ここでは疑問に思ってはいけません。

間違えてクエリを発行してしまった!中断や!

bq queryをよく叩く方にはあるあるかと思いますが、実際は実行したくなかったのに--dry_runオプションをつけ忘れてしまい、クエリが走りだします。 コンソール上にRunningのメッセージが表示されるので、慌ててCTRL + Cで止めて「危なかったー!ヒヤリハットやったわ!」ってなりますよね??

いえ、それアウトですから。

実際はコンソールにRunningが表示された時点で、手元のマシンでCTRL + Cで止めたとしても、GCPにクエリの要求が届いておりクエリは処理されたままになります。 GCP側のクエリそのものを中断するにはbq cancel <ジョブID>を打ってあげる必要があります。

ちなみに、ジョブをキャンセルしても課金される可能性があります。それでもキャンセルを実行するのは、GCPを安く利用させてもらっている分、不要なマシンリソースを解放する心遣いですね。

その他

BigQueryにあまり慣れてない時によく参照したドキュメントはこちらです。

cloud.google.com cloud.google.com

あとは、上記のドキュメントから左側の目次から気になったのをピックアップすれば、色々と知れるのでおすすめです。

さいごに

ここまで、bqコマンドに触って知ったウンチクを色々記載しましたが、みなさんの参考になるものがあれば幸いです。


  1. bqコマンドの結果の件数が思ったより少ないときは、このデフォルト100件に引っかかっている場合が多いです。例えば、bq ls <データセット名> でテーブル一覧を出力したり、bq query "SELECT 〜〜"でレコードを出力した時に100件しか表示されていない場合は、-n <表示件数>オプションを設定してみてください。

  2. https://stedolan.github.io/jq/

細かすぎて教えてもらえなかった、psqlでSQLスクリプトを検証しながら書く方法

約半年ぶりの登場になります、データエンジニアのt-sugaiです。
最近アスタミューゼにも仲間が増えて、なかなかブログの順番が回ってこないので油断していました。
そんなわけで、今回は軽めな上にちょっとニッチなネタですが、ご容赦いただければと思います。

f:id:astamuse:20200311125058j:plain

データパッチ、書いてますか?

最近はなかなか生のSQLを書いてデータパッチを当てるというようなオペレーションも減ってきてはいますが、やはり最後に頼りになるのは生SQL力だと信じています。 とはいえ、本番DBに対してSQLを発行するのはなかなか緊張感のあるオペレーションです。 できるかぎり、複数回の試験・検証を経てから投入したいですよね。

一方、ローカルや開発環境では安心して試行錯誤をしたいですね。
PostgreSQLでは、DDLやTRUNCATEにもトランザクションが有効になるので、これをうまく使うと大部分のオペレーションはトランザクションの範囲内で実施できます。 したがって、明示的にトランザクションの開始とロールバックを使うことでデータパッチを安全に検証しながら作成することができます。
先日会社のSlackでこの話をしたら思いのほか反響があったので、ちょっとした話しすぎてだれも教えてくれなかったTIPSとしてまとめてみてもいいかなという試みです。

データパッチはアドホックに書きたい

ちょっとしたデータパッチを当てるときや、検証環境でアドホックにSQLを書いてデータの追加/更新/削除の処理を検証するとき、確認が取れたSQLをそのまま運用環境で実施するためにスクリプトファイルにしたりしますよね。
エディタなどで一気に書き下ろしたスクリプトを実行すると、ちょっとしたtypoをしてしまったり、うっかりカンマやセミコロンを忘れてしまうことがあります。 そんなとき、デフォルトが auto commit = true な PostgreSQL ですから、中途半端なデータがコミットされないように明示的にトランザクションを指定しますよね。
ということで、トランザクションで囲んだスクリプトを psql -f オプションで読み込ませると、前述のようなちょっとしたシンタックスエラーは安全にロールバックしてくれるので、安心です。

シンタックスじゃなくて、データパッチの内容を確認したい

ところで、エラーなく実施できれば当然トランザクションがコミットされますね。 ここでたとえば、AさんはこんなUPDATE文を実行するスクリプトを書いていたとします。

update_mistake.sql

START TRANSACTION;

UPDATE 
    patent_documents 
SET 
    category_id = 2
WHERE 
    patent_document_number = '12345'

COMMIT;

このスクリプトを素直に実行するならこんな感じですよね。

$ psql -f update_mistake.sql
START TRANSACTION
UPDATE 10
COMMIT
$ 

しかし、コミットしてしまってからデータを確認しているときに、データの不備に気づきました。
じつは変更対象は status = 1 のみだったのです。
そして、 今回の例示では10行だけだったようですが、status <> 1 のレコードがたくさんあり、しかもそれらの category_id が規則性らしい規則性もなくバラバラだったとしたら…… これを戻すデータパッチを考えるのはつらいですね。
検証環境なら以前のdumpなどから戻せばいいかもしれませんがちょっと大げさです。 コミットするまえにデータを確認できれば、もっと気楽にいろいろ試せますよね。

しかし、 psql -f で以下の様なコミットしないスクリプトを実施しても、当然ロールバックされてしまいます。

update_no_commit.sql

START TRANSACTION;

UPDATE 
    patent_documents 
SET 
    category_id = 2
WHERE 
    patent_document_number = '12345'

psql メタコマンド \i を使ってスクリプトの動作検証をする。

そこで、 psql のメタコマンド \i です。
このメタコマンドを使えば、対話コンソール上でファイルを読み込んで処理してくれるものです。

psql -d patents 

patents=>\i update_no_commit.sql 
START TRANSACTION
UPDATE 10

このようにすれば、スクリプトの終わったところまでで対話コンソールにコントロールが戻ってくるので、ここで SELECT 思う存分などして、中身を確認して、自分の意思で COMMIT or ROLLBACK を決めることができます。
当然ですが、COMMIT or ROLLBACK をするまでトランザクションをとり続けるので、特に更新の多いデータなどを扱っている場合には気をつけてください。このような手段をとることは言語道断なテーブル・データベースも世の中には少なからずあると思います。
しかし、ローカルや検証用環境などで更新クエリの試行錯誤をする際には便利だと思います。

psql メタコマンドは便利なものが多いよ。

pgAdminなどを利用しているとあまり知る機会がないかもしれませんが、psqlのメタコマンドには他にも \copy\o など、使ってみると便利なオプションが多数あります。
(逆に、私はpsqlが便利なのでpgAdminは使わなくていいかな、と思ってしまう方です)
\? で メタコマンドの一覧がいつでも確認できます。一度眺めてみると、自分のオペレーションに合ったものが見つかるかもしれませんよ。

Copyright © astamuse company, ltd. all rights reserved.