gsutil compose で 32より多いファイルを結合したいとき
背景
gsutil compose はファイルを結合する便利コマンド。しかし32より多いファイルは結合できない。
解決策
xargs -L31 を使う。
echo -n | gsutil cp - gs://your-bucket/total.gz gsutil ls gs://your-bucket/your_file*.gz | xargs -L31 | xargs -I{} echo gsutil compose gs://your-bucket/total.gz {} gs://your-bucket/total.gz | sh
ここで、your-bucket
はバケット、total.gz はコピー先、your_file*.gz はコピー元を示す。
詳細
本当は xargs を一つにまとめたかったのだが、-I
オプション(リプレイス)を使うと、強制的に -L31
が -L1
に変更されてしまうので、こうなった。
また echo ... | sh
になっているのは、リプレイス先がスペースを含んだ複数のファイルが一つのファイルと認識されてしまうため。
Cloud Firestore は、オブジェクトをサポートされているデータ型に変換します。
background
firestore からデータを取得する良い方法を探して公式ドキュメントを眺める。
すると、
一部の言語では、カスタムのオブジェクト タイプを使用する方が便利な場合が多くあります。
と書いてあるではないか?
doc_ref = db.collection(u'cities').document(u'BJ') doc = doc_ref.get() city = City.from_dict(doc.to_dict()) print(city)
City
というカスタムのオブジェクトタイプに戻すのか。pythonはどうやらfrom_dict
関数によってサポートされているらしい。
カスタムのオブジェクトタイプとは?
どうやらデータの追加のセクションにあるらしい。
つぎのような心強いお言葉が。
Cloud Firestore では、カスタムクラスを使ったドキュメント作成をサポートしています。 Cloud Firestore は、オブジェクトをサポートされているデータ型に変換します。
Webのサンプルコードは次の様。
class City(object): def __init__(self, name, state, country, capital=False, population=0, regions=[]): self.name = name self.state = state self.country = country self.capital = capital self.population = population self.regions = regions @staticmethod def from_dict(source): # ... def to_dict(self): # ... def __repr__(self): return( f'City(\ name={self.name}, \ country={self.country}, \ population={self.population}, \ capital={self.capital}, \ regions={self.regions}\ )' )
肝心な from_dict
クラスは省略されている。このカスタムオブジェクトクラスも、単なる object
クラスから作られていない?
Cloud Firestore は、オブジェクトをサポートされているデータ型に変換します。
ってどういう意味だろう。日本語の翻訳誤りかな。英語で見てみると、
Cloud Firestore converts the objects to supported data types.
誤りはなさそうだ。。。だが、何もサポートされていないじゃないかな…。一応コードを見てみる。
全部自前でやってるじゃないか。どこにもライブラリでなんとかしている箇所がない。
まとめ
Cloud Firestore は、オブジェクトをサポートされているデータ型に変換しません。 ご自分で頑張って下さい。
BQで地域メッシュコード(2分の1)のポリゴン
背景
BQで地域メッシュコード(2分の1)からポリゴンを作ることになった。
クエリ
とはいっても、ほとんど temp function ですが。
create temp function INT(S STRING) AS (CAST(S AS INT64)); create temp function STR(F FLOAT64) AS (CAST(F AS STRING)); create temp function FINT(F FLOAT64) AS (CAST(F-0.5 AS INT64)); create temp function SS1(CODE STRING, POS INT64) AS ( INT(SUBSTR(CODE, POS+1, 1))); create temp function SS2(CODE STRING, POS INT64) AS ( INT(SUBSTR(CODE, POS+1, 2))); create temp function LA4(CODE STRING) AS (FINT((SS2(CODE, 8)-1)/2)); create temp function LAT4(CODE STRING, I INT64) AS ((SS2(CODE, 0)+(SS1(CODE, 4)+(SS1(CODE, 6)+(LA4(CODE)+I)/2)/10)/8)/1.5); create temp function LAT40(CODE STRING) AS (STR(LAT4(CODE, 0))); create temp function LAT41(CODE STRING) AS (STR(LAT4(CODE, 1))); create temp function LO4(CODE STRING) AS (FINT(MOD((SS2(CODE, 8)-1), 2))); create temp function LON4(CODE STRING, I INT64) AS (SS2(CODE, 2)+100+(SS1(CODE, 5)+(SS1(CODE, 7)+(LO4(CODE)+I)/2)/10)/8); create temp function LON40(CODE STRING) AS (STR(LON4(CODE, 0))); create temp function LON41(CODE STRING) AS (STR(LON4(CODE, 1))); create temp function WKT4(CODE STRING) AS ("POLYGON((" || LON40(CODE) || " " || LAT40(CODE) || ", " || LON41(CODE) || " " || LAT40(CODE) || ", " || LON41(CODE) || " " || LAT41(CODE) || ", " || LON40(CODE) || " " || LAT41(CODE) || ", " || LON40(CODE) || " " || LAT40(CODE) || "))" ); select ST_GEOGFROMTEXT(WKT4("533946113")) AS geog
まとめ
とりあえず、できた。エラーチェックなどはないので、偉い人は自分でつくろう。
参考文献
Azure Storage Blob に python で、stream upload
背景
Azure Storage Blobにpython で、stream upload したので、メモ。
こうした
Azure 自体触ったことないので、よくわからないが、
from azure.storage.blob import BlobServiceClient
というライブラリを使った方法(レガシーなライブラリも存在するらしい)。 詳しくは、ここを参照。
blob_service_client = BlobServiceClient(account_url=AZURE_STORAGE_ACCOUNT_STRING) blob_client = blob_service_client.get_blob_client(container=CONTAINER_NAME, blob=BLOB_NAME) blob_client.upload_blob(sys.stdin.buffer, length=length)
ここで、AZURE_STORAGE_ACCOUNT_STRING
は、然るべき方法で取得した文字列(実は知らない)。
CONTAINER_NAME
はコンテナ名の文字列、BLOB_NAME
はblobの文字列。
sys.stdin.buffer
は標準入力のバイナリ。
大切なのは、length 。これがないと、エラー。
ストリームなのに、サイズが分かってないとダメ。これは仕様(書いてないけど)としては厳しいなあ…
まとめ
stream upload したければ、サイズを先に調べて、lengthに渡す。
リポジトリに接続できませんでした cloud source repositories
背景
Cloud Build 使おうと思ったけど、github のprivate repositories を使うのは、Cloud KMSなどのサービス使うから嫌だなあと思っていたら、
GitHub リポジトリのミラーリング | Cloud Source Repositories のドキュメント | Google Cloud
という方法もあってそれをやろうとしたら、
解決策
Cloud Source Repositories にとりあえず、空でいいのでレポジトリを一つ作る。
BigQuery で最大最小が overlap しているものをまとめる(その最大最小を得る)
背景
最小と最大のペアの集合があるとする。
例えば、[最小, 最大]とすると、
[1, 2], [3, 4], [4, 5], [6, 7], [6, 8], [9, 10]
というような集合。
[3, 4], [4, 5]
は、まとめて、
[3, 5]
にしたい。
他にも、
[6, 7], [6, 8]
も、まとめて、
[6, 8]
にしたい。
最終的に、
[1, 2], [3, 5], [6, 8], [9, 10]
と出力したい。
つまり、ある要素の最大が、別の要素の最小値と同じかそれより大きい場合は、 その2つの要素を一つの要素にまとめたいということがある。
そのクエリ
WITH sample_data as ( SELECT s.a AS a, s.z as z FROM ( SELECT [ STRUCT(1 as a, 2 AS z), STRUCT(3 as a, 4 AS z), STRUCT(4 as a, 5 AS z), STRUCT(6 as a, 7 AS z), STRUCT(6 as a, 8 AS z), STRUCT(9 as a, 10 AS z) ] _a) JOIN UNNEST(_a) s), w as ( SELECT a, z, LAG(z) OVER (ORDER BY a, z) AS pre_z, LAG(a) OVER (ORDER BY z desc, a desc) AS post_a FROM sample_data ORDER BY a, z), head AS ( SELECT DISTINCT a FROM w WHERE pre_z IS NULL OR a > pre_z), tail AS ( SELECT DISTINCT z FROM w WHERE post_a IS NULL OR post_a > z), head_tail AS ( SELECT a, MIN(z) AS z FROM head CROSS JOIN tail WHERE a <= z GROUP BY a ) -- -- SELECT * FROM head_tail
解説
ウィンドウ関数を使って、並べた一つ上(もしくはひとつ下の)最大値(最小値)がその列の最小値より小さい(最大値より大きい)場合、まとめた要素の最小値(最大値)となる。
統計でいう treatment
treatment とは、因子の組み合わせでできる(実験の)集計グループのー要素。