
NocoBaseのAPIで関連テーブルのフィールドもまとめて取得する方法はありますか
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
困っていたこと
NocoBaseで2つのテーブルが関連付けられています。APIでレコードを取得するときに、関連先テーブルのレコードも取得することはできますか?
どう対応すればいいの?
APIの appends パラメータに Association fields となっているフィールド名を指定すると、関連先テーブルのまとめて取得することができます。
サンプルデータ
サンプルとしてNocoBaseの初期テーブル "ユーザー (users)" と "役割 (roles)" の例を紹介します。ユーザー と 役割 は多対多の関連になっています。
さらに今回の動作確認のため上長を指定するフィールド "manager" を追加しました。 users テーブルは manager フィールドを介して自身を参照します。

Pythonコード
APIへのアクセスはGoogle Colab上でPythonから行います。ライブラリには python-nocobase を使っています。詳しくは以前書いたブログを参照してください。
まずpipで必要なライブラリをインストールします。
!pip install git+https://github.com/ueki-kazuki/python-nocobase
!pip install gspread
次にNocoBase APIに接続するため、接続先とトークンを設定します。
from google.colab import userdata
from nocobase.exceptions import NocoBaseAPIError
from nocobase.nocobase import JWTAuthToken
from nocobase.infra.requests_client import NocoBaseRequestsClient
auth = JWTAuthToken(userdata.get("NOCOBASE_TOKEN"))
client = NocoBaseRequestsClient(auth, userdata.get("NOCOBASE_URL"))
client.collection("users") で users テーブルを操作するためのインスタンスを生成します。このインスタンスに対してlistやcreateなどの各種操作を行います。
import pprint
# ユーザーデータを取得する(id=6が私)
users = client.collection("users")
filters = { "id": 6 }
# データフレームを作成
data_rows = []
for u in users.list(filter=filters, appends=["roles", "manager"]):
  pprint.pp(u)
  data_rows.append(
      [
          u["username"],
          u["email"],
          u["roles"][0]["name"],
          u["manager"]["username"]
      ]
  )
上記コードで listメソッドの appends パラメータに関連テーブルを指定するのがポイントです。指定する文字列は users テーブルの Association fields のフィールド名を指定してください。

出力結果
usersとrolesは多対多(ManyToMany)の関係なので roles はレコードが配列で返ってきます。
users と manager は多対1(ManyToOne)の関係なのでレコードがそのまま返ります。
{'email': 'ueki.kazuki@classmethod.jp',
 'id': 6,
 'username': 'ueki_kazuki',
 'nickname': '植木和樹',
 'f_users': 1,
 'roles': [{'title': '{{t("Admin")}}',
            'name': 'admin'},
           {'title': '{{t("Member")}}',
            'name': 'member'}],
 'manager': {'email': 'admin@nocobase.com',
             'id': 1,
             'username': 'nocobase',
             'nickname': 'Super Admin',
             'f_users': None}}













