Hasura GraphQLで、配列にある値を含むレコードのみでフィルタする

概要 HasuraはバックエンドにPostgresQLを持つGraphQLサーバーです。PostgresQLのテーブル要素に配列があった場合にSQLであれば@>といった演算子でフィルタします。Hasura GraphQLにおいても同等のことができましたのでレポートします。 フィルタ方法 例えばmytableのmyarrayカラム(型はjsonb)に以下のようなデータが入っていたとします。 id: 1, myarray: ['foo', '1', '2'] id: 2. myarray: ['3', '4'] id: 3. myarray: ['5', 'foo'] 例えばid=1のmyarrayカラムには['foo', '1', '2']というjsonbが入っている状態です。 ここでmyarrayにfooが入っているレコードだけを引いてきたいとします。その場合のクエリは以下のとおりです。 query MyQuery { mytable(where: {myarray: {_contains: "foo"}}) { id } } これで1,3のレコードを取得できます。HasuraのUI上から見る限りですとjson型ではcontainsオペレータが存在しません。公式ドキュメントでもJSONB Operatorと述べられている通り、jsonb限定の機能のようです。

December 22, 2021 · 1 min · Me

Vuetifyのv-data-tableのヘッダがズレてしまう

概要 Vuetifyでv-data-tableを使っていてカラムがずれる症状がでました。悩みましたが解決したのでレポートします。 問題 以下のようなv-data-tableを作成してみます。 <template> <v-data-table :headers="headers" :items="cards" :items-per-page="5" class="elevation-1" :mobile-breakpoint="0" ></v-data-table> </template> すると以下の画像のようになります。 ヘッダと値の位置が大きくずれていて非常に見づらい表になっていまっています。 解決 以下のようにv-data-tableの前にv-appをはさみます。 <template> <v-app> <v-data-table :headers="headers" :items="cards" :items-per-page="5" class="elevation-1" :mobile-breakpoint="0" ></v-data-table> </v-app> </template> すると以下のようになります。 きれいに列が揃っています。詳しく理由はわかりませんが修正方法は以上です。UI系って「なんだかよくわからないがこうすれば動く」みたいなもの多いですね。理由を知っている方おりましたらDMでもなんでもいただけましたらと思います。

December 13, 2021 · 1 min · Me

Kustomize Patch

概要 kustomizeを利用するとベースのyamlからパッチをして、「ほとんどの部分は同じだが一箇所だけリソースが異なる」といったようなリソースを作成することができます。差分だけ記述すれば済むため、yamlの定義ははシンプルで管理しやすくなります。環境ごとに多数のリソースを扱うといった場合は特に有効です。 1 基本 kustomizeでnamespaceやnameのプリフィックス、ポストフィックス、label、annotationをつけることは簡単です。以下のファイルを用意します。 deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 2 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 kustomization.yaml resources: - deployment.yaml namespace: myns namePrefix: pre- nameSuffix: -suf commonLabels: label1: lab1 label2: lab2 commonAnnotations: annotation1: ann1 annotation2: ann2 kustomizeを実行します。 $ kubectl kustomize ./ apiVersion: apps/v1 kind: Deployment metadata: annotations: annotation1: ann1 annotation2: ann2 labels: label1: lab1 label2: lab2 name: pre-my-nginx-suf namespace: myns spec: replicas: 2 selector: matchLabels: label1: lab1 label2: lab2 run: my-nginx template: metadata: annotations: annotation1: ann1 annotation2: ann2 labels: label1: lab1 label2: lab2 run: my-nginx spec: containers: - image: nginx name: my-nginx ports: - containerPort: 80 kustomization....

November 23, 2021 · 5 min · Me

Heroku Postgres Tips

概要 heroku環境でpostgresqlを運用しているのですがハマりどころが多く、運用の度に思い出しながら対応していました。そろそろなんとかしなければという思いで、準備から頻繁に利用する運用コマンドをまとめていきます。 環境 $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.5 LTS Release: 18.04 Codename: bionic herokuのPostgresサーバーへ接続する 通常以下のコマンドでherokuのPostgresサーバーに接続できます。 $ heroku pg:psql しかし、以下のようなエラーになることがあります。 EACCES: spawn psql EACCES heroku cliのラッパーからPostgresへ接続する際にはローカルのpsqlコマンドを利用しているため、psqlがインストールされていない場合上記のようなエラーになることがあるようです。非常にわかりにくい。 ではローカルのUbuntu環境へpsqlをインストールしていきます。今回wgetとlsb_releaseを利用しますのでインストールしてください。 sudo apt-get install lsb-release wget 次に以下の通りパッケージリストへrepoを追加します。 wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |sudo tee /etc/apt/sources.list.d/pgdg.list あとはアップデートして sudo apt update インストールします。heroku環境に接続するだけならクライアントだけで十分です。インストールするクライアントのバージョンをサーバー環境とあわせないと実行できないコマンドなどもありますのでheroku pg:infoでバージョンを確認します。私の環境では13でした。 sudo apt install postgresql-client-13 これでPostgresサーバーへ接続できるようになります。...

November 21, 2021 · 1 min · Me

Nodejs raceでスクリプトをタイムアウトさせる

概要 kubernetes上でcronjobでnodejsのスクリプトを実行させていると、どうしてもapiへのリクエストなどで時間がかかってしまうことがあります。いつまでも終了しないcronjobのpodが滞留してくるとクラスタ全体が重くなってmasterに影響がでたりすることもあります。そうならないようスクリプトは適宜タイムアウトするような作りにしておくと良いですが、その際便利だったのがPromise.raceという仕組みでした。 実験 まずは基本のサンプルコードです。 const TIMEOUT = Number(process.env.TIMEOUT) || 5000; const timeout = async (msec) => { return new Promise((_, reject) => setTimeout(() => { reject(new Error("timeout")) }, msec)) } function sleep(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } const exec = async () => { try { await sleep(1000); } catch (error) { throw new Error(error); } } (async () => { return Promise.race([exec(), timeout(TIMEOUT)]) .then(() => { console....

November 20, 2021 · 1 min · Me