Open6

Hasura

みるべあみるべあ

論理削除

now() を使えば現在時刻をカラムに保存してくれる。

export const DELETE_PURCHASED_POST = gql`
  mutation DeletePurchasedPost($id: bigint!) {
    update_purchased_posts_by_pk(pk_columns: { id: $id }, _set: { deleted_at: "now()" }) {
      id
      deleted_at
    }
  }

today() を使えば今日の日付。

みるべあみるべあ

カスタマイズしたフィールドを返す

▼ こんな query を書きたい場合...

export const GET_ARTICLES = gql`
  query GetArticles {
    # 公開記事
    publicArticles {
      id
      title
      body
   }
    # 下書き記事
    draftArticles {
      id
      title
      body
   }
  }
`

▼ Hasura でいう Computed fields を使って実現できそう。

https://hasura.io/docs/latest/schema/postgres/computed-fields/

みるべあみるべあ

Hasura Cloud を CLI で操作したい

--endpoint オプションを付けて実行する。

▼ シードデータを適用したいとき

hasura seed apply --endpoint https://エンドポイント.hasura.app
みるべあみるべあ

Hasura Cloud で実行されたクエリの変数を見られるようにしたい

MONITORING > Operations にある Capture query variables をオンにする。

Query variables が表示されるようになった🙌

※オンにする前に実行されたクエリについては表示されない。

みるべあみるべあ

GROUP BYを使いたい

SakeDokoの新機能として、よく行くスポットランキングを表示したいなと。
posts テーブルから place_namegroup_by して、さらに count もしたい。

Computed fields

https://hasura.io/docs/latest/schema/postgres/computed-fields

この機能を使ってSQL関数を作って、Table computed fieldsとして扱えば実現できそうだとChatGPT先生と考えたわけです。

CREATE OR REPLACE FUNCTION get_top_places_by_user(user_id_input TEXT)
RETURNS TABLE(
  place_name TEXT, 
  post_count BIGINT
) AS $$
BEGIN
  RETURN QUERY
  SELECT place_name, COUNT(*) AS post_count
  FROM posts
  WHERE user_id = user_id_input
  GROUP BY place_name
  ORDER BY post_count DESC;
END;
$$ LANGUAGE plpgsql STABLE;

さて、上記関数を登録して Computed fields に設定しようと Function name プルダウンを見ても何もない。。。

SQL関数が間違っていると思い、いろいろ試行錯誤したものの一向に状況が変わらない。

勘違いしていたこと

いろいろ調べて改めて前述のドキュメントを眺めてみると、関数の引数にレコードが入っていることに気が付きます。

-- 引数の author_row の部分
CREATE FUNCTION filter_author_articles(author_row authors, search text)
-- ...

ならば以下のようにすればできるだろう。

CREATE OR REPLACE FUNCTION get_top_places_by_user(post_row posts)
RETURNS TABLE(
  place_name TEXT, 
  post_count BIGINT
) AS $$
BEGIN
  RETURN QUERY
  SELECT place_name, COUNT(*) AS post_count
  FROM posts
  WHERE user_id = post_row.user_id
  GROUP BY place_name
  ORDER BY post_count DESC;
END;
$$ LANGUAGE plpgsql STABLE;

今度は Function name のプルダウンに get_top_places_by_user が表示されました。
クエリも叩けるようになったのですがエラーが出ました。
改めてドキュメントを見ると...

Return type: Either SETOF <table-name> or BASE type

RETURNS TABLE はサポートされていませんでした。
SQL関数ではできない...どうしたらいいか。

VIEW を作成

VIEW テーブルを作ってみたらどうだろうか?

CREATE OR REPLACE VIEW public.best_three_purchased_posts AS
  SELECT user_id, place_name, COUNT(*) as post_count
  FROM posts
  GROUP BY user_id, place_name

クエリ叩けたー万歳🙌