中野智文のブログ

データ・マエショリスト(※データ・マエストロではない)のメモ

BigQuery でテーブルを正規表現を指定して削除する

背景

BigQuery で特定のテーブルをワイルドカードで指定して削除したいことがある。ところが、CLIコマンドである bq はそのようなワイルドカード指定はできない。

データセットのファイル一覧を出して、それを egrep で抽出する

下記の <dataset_name> と、<regular expression> にそれぞれ、データセット名と正規表現を書く。

bq --format json ls -n 10000 <dataset_name> | jq -r 'map("<dataset_name>."+ .tableId)|.[]' | egrep '<regular expression>' | xargs -L1 bq rm -f

ただし、本当に望ましいファイルが対象となっているかを最後の削除を除いたコマンドである、

bq --format json ls -n 10000 <dataset_name> | jq -r 'map("<dataset_name>."+ .tableId)|.[]' | egrep '<regular expression>' 

で一旦確認したり、ファイル数を少なくして実行してみることをおすすめする。

pdf を送ると、「Kindleに送信された文書に問題がありました」

症状

次の論文をchromeでダウンロードして、

https://openreview.net/pdf?id=BkJsCIcgl

mail で kindle に送信すると次のようなエラーメールが届く

2017年6月19日(月) 午前 09:59(JST) に送信された以下のドキュメントは、指定されたKindle に送信できませんでした:
XXXXX.pdf

Kindle パーソナル・ドキュメントで変換・転送できるドキュメントは以下のファイル形式です:
Microsoft Word (.doc, .docx)
Rich Text Format (.rtf)
HTML (.htm, .html)
Text (.txt) documents
圧縮フォルダ (zip , x-zip)
Mobi book

画像ファイル: JPEG (.jpg)、GIF (.gif)、Bitmap (.bmp)、PNG (.png)。
Adobe PDF (.pdf) ドキュメントは、Kindle DX, 第二世代および最新の Kindle には変換されずに送信されます。

PDF ファイルの Kindle フォーマットへの変換・転送は試験段階の機能としてご提供しております。

転送に失敗したドキュメントが上記の形式だった場合は、ファイルがパスワード保護されていたり、暗号化されていたりしないかをご確認ください。最新の Kindle はパスワード保護された PDF ファイルの転送が可能です。

パーソナル・ドキュメントの添付ファイルに関するご注意:
添付ファイルは、それぞれ ZIP 圧縮前のサイズが50MB未満である必要があります。
一通のEメールで送信できるファイル数の上限は25個です。

パーソナル・ドキュメントの転送についての詳細は、ヘルプページをご覧ください:
http://www.amazon.co.jp/kindlepersonaldocuments/

調査

当初ファイル名の問題かと思われたが、同じエラーメールが来る。

解決

mac のプレビューワで 「ファイル」「pdf として書き出す」で送信後、問題なく、kindle で表示されることを確認。

原因(不明)

オリジナルのPDFに何かあったのか、chrome で一旦表示後、ダウンロードしたのがよくないのか、そのあたりは不明。

Permission denied while globbing file pattern. のエラー

症状

BigQuery のWebコンソールでは特にエラーは出ないのに、redash だと Error running query: The job encountered an internal error during execution and was unable to complete successfully. みたいなエラー。

調査

コマンドコンソールにて同クエリーを実行。 すると、

Permission denied while globbing file pattern. 

のエラー。 そのエラーのクエリをヒストリから選び、Open Query から RUN QUERY を再実行するも、正常に返ってくる。

Webで調べてみると、google drive がらみの権限エラーの模様。

stackoverflow.com

Google Driveは全く使っていないが、たしかに 直接インポート した。

インポートしたテーブルを外すと、コマンドからでも正常にクエリは実行された。

該当テーブルの detail をwebコンソールから見ると、

External Data Configuration
Source URI(s)   https://docs.google.com/spreadsheets/d/XXXXXXXXXXXXX/edit#gid=0
Auto-detect Schema  true
Source Format   GOOGLE_SHEETS
Max Bad Records     10

となっており、たしかに外部から持ってきたデータであることと、source format も GOOGLE_SHEETS となっている。

対応

原因が分かったが、対応方法は不明。

まず、bq コマンドによりコピーを試みるが、当然失敗した。

次に、

SELECT * FROM [TABLE_NAME]

を実行し、その結果を別テーブルに保管した。そしてそのテーブルを参照するようにすると、bq コマンドで問題なくクエリは実行できた。 redashも問題なく動作した。

luigi の exit status

luigi の exit status

は失敗しても 0 が返ってくるので、make などから呼び出した場合、そのまま通過してしまう。

調べると、次のページが見つかる。

qiita.com

実はコマンドラインのオプションでも設定できる。

$ luigi --help-all
...
  --retcode-unhandled-exception RETCODE_UNHANDLED_EXCEPTION
                        For internal luigi errors.
  --retcode-missing-data RETCODE_MISSING_DATA
                        For when there are incomplete ExternalTask
                        dependencies.
  --retcode-task-failed RETCODE_TASK_FAILED
                        For when a task's run() method fails.
  --retcode-already-running RETCODE_ALREADY_RUNNING
                        For both local --lock and luigid "lock"
  --retcode-scheduling-error RETCODE_SCHEDULING_ERROR
                        For when a task's complete() or requires() fails, or
                        task-limit reached
  --retcode-not-run RETCODE_NOT_RUN
                        For when a task is not granted run permission by the
                        scheduler.
...

オプションで指定できることは、設定ファイルでも設定できるといったほうがいいのか、設定ファイルで設定できることはオプションで指定できるといったほうがいいのか。 いずれにしろ便利。

already_running については悩ましいが、とりあえず、全て非ゼロに設定ファイルにしておき、必要に応じてオプションで指定するなどがいいのでは。

Airflow と格闘中(15)

nakano-tomofumi.hatenablog.com

上記のように、もう使わない予定だが、エラーが出たので貼り付ける。

backfilldeadlocked エラー

Traceback (most recent call last):
  File "/XXX/bin/airflow", line 28, in <module>
    args.func(args)
  File "/XXX/lib/python2.7/site-packages/airflow/bin/cli.py", line 167, in backfill
    pool=args.pool)
  File "/XXX/lib/python2.7/site-packages/airflow/models.py", line 3330, in run
    job.run()
  File "/XXX/lib/python2.7/site-packages/airflow/jobs.py", line 200, in run
    self._execute()
  File "/XXX/lib/python2.7/site-packages/airflow/jobs.py", line 2031, in _execute
    raise AirflowException(err)
airflow.exceptions.AirflowException: ---------------------------------------------------
BackfillJob is deadlocked. These tasks have succeeded:
set([(u'dag_name', u'dag_name', datetime.datetime(2017, 6, 6, 0, 0)), (u'dag_name', u'task_name0', datetime.datetime(2017, 6, 6, 0, 0))])
 These tasks have started:
{}
 These tasks have failed:
set([])
 These tasks are skipped:
set([])
 These tasks are deadlocked:
set([<TaskInstance: dag_name.task_name1 2017-06-06 00:00:00 [scheduled]>, <TaskInstance: dag_name.task_name2 2017-06-06 00:00:00 [up_for_retry]>, <TaskInstance: dag_name.task_name3 2017-06-06 00:00:00 [scheduled]>, <TaskInstance: dag_name.task_name4 2017-06-06 00:00:00 [scheduled]>])

もう一度実行したらうまくいった。

何がデッドロックなのかは分からない。もしかしたら、仮想マシンの共有ディレクトリを使っているので、その関係上 sqlite などの更新が間に合わずおかしくなっているのかもしれない。

まとめは、

nakano-tomofumi.hatenablog.com

会社の新しいmac book pro に Julia をインストールする

自宅 mac の Julia のインストールには結構時間がかかった。

nakano-tomofumi.hatenablog.com

今回は会社の mac book pro にインストールする。

brew cask install julia でインストー

cask 版を使ったら驚くべきことにサクッとインストールできた。

$ brew cask install julia
==> Satisfying dependencies
complete
==> Downloading https://s3.amazonaws.com/julialang/bin/osx/x64/0.5/julia-0.5.2-osx10.7+.dmg
######################################################################## 100.0%
==> Verifying checksum for Cask julia
==> Installing Cask julia
==> Moving App 'Julia-0.5.app' to '/Applications/Julia-0.5.app'.
==> Linking Binary 'julia' to '/usr/local/bin/julia'.
�  julia was successfully installed!
user@machine:~$ julia
               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: https://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.5.2 (2017-05-06 16:34 UTC)
 _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org/ release
|__/                   |  x86_64-apple-darwin13.4.0

うーむ…

julia> Pkg.add("HypothesisTests")
INFO: Initializing package repository /Users/user/.julia/v0.5
....
INFO: Changing Directory to /Users/user/.julia/v0.5/Rmath/deps/src/Rmath-julia-0.1
make -C src
gcc  -Wall -O3 -fPIC -DMATHLIB_STANDALONE -I/Users/user/.julia/v0.5/Rmath/deps/dSFMT   -std=gnu99 -I../include -DNDEBUG -c bd0.c -o bd0.o
...
gcc  -Wall -O3 -fPIC -DMATHLIB_STANDALONE -I/Users/user/.julia/v0.5/Rmath/deps/dSFMT   -std=gnu99 -I../include -DNDEBUG -c randmtzig.c -o randmtzig.o
rm -rf libRmath-julia.dylib
gcc   -shared -o libRmath-julia.dylib bd0.o dnbeta.o i1mach.o pnbinom.o qlnorm.o rgeom.o bessel_i.o dnbinom.o imax2.o pnchisq.o qlogis.o rhyper.o bessel_j.o dnchisq.o imin2.o pnf.o qnbeta.o rlnorm.o bessel_k.o dnf.o lbeta.o pnorm.o qnbinom.o rlogis.o bessel_y.o dnorm.o lgamma.o pnt.o qnchisq.o rmultinom.o beta.o dnt.o lgammacor.o polygamma.o qnf.o rnbinom.o chebyshev.o dpois.o log1p.o ppois.o qnorm.o rnchisq.o choose.o dt.o mlutils.o pt.o qnt.o rnorm.o d1mach.o dunif.o pbeta.o ptukey.o qpois.o rpois.o dbeta.o dweibull.o pbinom.o punif.o qt.o rt.o dbinom.o expm1.o pcauchy.o pweibull.o qtukey.o runif.o dcauchy.o fmax2.o pchisq.o qbeta.o qunif.o rweibull.o dchisq.o fmin2.o pexp.o qbinom.o qweibull.o dexp.o fprec.o pf.o qcauchy.o rbeta.o sign.o df.o fround.o pgamma.o qchisq.o rbinom.o signrank.o dgamma.o fsign.o pgeom.o qexp.o rcauchy.o dgeom.o ftrunc.o phyper.o qf.o rchisq.o stirlerr.o dhyper.o gamma.o plnorm.o qgamma.o rexp.o toms708.o dlnorm.o gamma_cody.o plogis.o qgeom.o rf.o wilcox.o dlogis.o gammalims.o pnbeta.o qhyper.o rgamma.o librandom.o randmtzig.o -L/Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia -ldSFMT
INFO: Changing Directory to /Users/user/.julia/v0.5/Rmath/deps/src/Rmath-julia-0.1
INFO: Package database updated

julia>

おお、問題なくできてそう。

julia> using HypothesisTests
INFO: Precompiling module HypothesisTests.

julia> BinomialTest(24,25)
Binomial test
-------------
Population details:
    parameter of interest:   Probability of success
    value under h_0:         0.5
    point estimate:          0.96
    95% confidence interval: (0.7964830860775859,0.9989878003006891)

Test summary:
    outcome with 95% confidence: reject h_0
    two-sided p-value:           1.5497207641601605e-6

Details:
    number of observations: 25
    number of successes:    24


julia> confint(BinomialTest(24,25))
(0.7964830860775859,0.9989878003006891)

初回起動はちょっと時間がかかったが、ほぼ問題なさそう。自宅での苦労は何だったのか…。

ついでだから、息子の小学校の運動会の得点の信頼区間でも出してみる。

f:id:nakano-tomofumi:20170605192718j:plain

白組と紅組の得点は、1276と1272点だった。本当は団体戦などあるが、1点づつの個人毎の勝敗により点数が加算されたと仮定して、1276+1272=2548 回のベルヌーイ試行のうち、それぞれ、 1276, 1272 の成功があったと考えることにする。

julia> collect(confint(BinomialTest(1276,2548)))*2548
2-element Array{Float64,1}:
 1226.05
 1325.94

白組の95%信頼区間を計算すると、上記のようになる。 1226.05と1325.94の間である。 この失得点差は、非常に僅差であると言えるだろう。ある意味人為的な操作があったとも考えられても不思議ではない。

Airflow をおすすめしない理由

これまでずっと airflow と格闘してきたが(下記参照)

nakano-tomofumi.hatenablog.com

ここで一旦まとめることにする。

Airflow をおすすめしない理由

【致命的】Scheduler がコケる。

タスクは別プロセスで実行されるが、スケジュールもコードで書いてあるためそれを読み込む必要がある。そこで不具合(例えば日本語のコメントなど)があるとコケる。

重複実行されてしまう。

同じタスクIDでも別のDAG IDだと別のタスクとみなされるため、同じジョブが実行されてしまう。

ドキュメントがしっかりしていない。

DAGが paused のことがあったが、そのような話はどこにもなかった。また設定ファイルの重要な項目の説明は、設定ファイル中のコメントに書いてあるだけだったりする。

エラーの出力がしっかりしていない。

何か問題があったときでも、何が原因なのかが分からない。例えば SQLalchemy の一般的なエラーでてもなんの問題か分からない。 その原因を知るためには変数の中身を出力するデバッグコードを埋め込んだりする必要があった。