Python
bigquery
Linuxコマンド
pythonDay 12

Bigqueryで集計したcsvファイルを指定した行数で分割するpythonスクリプト

More than 1 year has passed since last update.

これは、Python Advent Calendar 2017の12日目の記事です。

背景

ゲーム会社で分析をやっています。
分析をやってるとログ分析やレポート作成だけでなく、ちょいちょい補填作業(いわゆる侘び石配布とか)も依頼がきます。
この補填作業で分析部員が主にやることは不具合のあった該当時間に特定の操作を実施した人をプレイログから割り出してそのユーザーIDをリスト化する、という割と単純なものです。
が、ファイルサイズの関係上、指定行数に納めないといけないといった制約があったので「集計したcsv→指定行数でファイル分割」の流れをスクリプト化しました。

CLI上でBigqueryからcsvファイルを抽出

まずBigqueryで特定ユーザーIDをリストアップするためのsqlを書いてcsvファイルとして吐き出します。

$ bq query --format=csv --use_legacy_sql=false --max_rows=100000 --flagfile user_list.sql > user_list.csv

オプションの意味は以下。
--format:抽出ファイルの形式を指定。現状csvとjsonが選べる
--use_legacy_sql:標準SQLを使用(trueだとレガシーSQL)
--max_rows:ファイルに書き込めるか行数を指定。このオプションがないと100行までしか抽出されない
--flagfile:sqlファイルを実行するためのオプション

得られたファイルを指定行数で分割する

↓1000行ごとに分割するスクリプトを愚直に書くと以下。

split.py
origine_file = "user_list.csv"
split_file   = "split_%d.csv"

split_idx = 1
line_idx  = 1
origine_file2  = open(origine_file)
split_file2    = open(split_file % (split_idx,), "w")

max_lines = 1000
line = origine_file2.readline()
while line:
    if line_idx > max_lines:
        split_file2.close()
        split_idx += 1
        line_idx   = 1
        split_file2 = open(split_file % (split_idx,), "w")
    split_file2.write(line)
    line_idx += 1
    line = origine_file2.readline()

origine_file2.close()
split_file2.close()

参考サイト

あとはバッチファイルにbqコマンドとsplit.pyと記載すればよい。

splitコマンドだったらワンライナー

当時はプログラミング初めたばっかりかつ、Linuxコマンドはほとんど無知に近い状態で使っていたけどsplitコマンドというものがあることをその後知りました。(Linuxコマンドって便利ですね)

split.bat
bq query --use_legacy_sql=false --format=csv --max_rows=100000 --flagfile user_list.sql > user_list.csv
split -l 1000 user_list.csv split_

結局bqコマンドと合わせてたった2行でファイル抽出→ファイル分割までできました。
適したツールを使うべき、ということは教訓としつつ、pythonによって業務効率化できた初めての経験ができて良かったです。