🙆

TiDB Data Service を触ってみる その2

2024/04/30に公開

前回の記事では、TiDB Cloud の Data Service を触ってみました。
https://zenn.dev/kameping/articles/e43894068d9928

Data Service はHTTPエンドポイント経由でSQLの実行結果をJSONで取得するサービスです。
Chat2Queryでいくつかの操作を行った結果、2種類のエンドポイントが生成されています。
https://zenn.dev/kameping/articles/9ebee487d30359

  1. 外部SQLファイル用エンドポイント
  2. Chat2Query用エンドポイント

前回の記事では外部SQLファイル用エンドポイントを操作しましたので、この記事では2番のChat2Query用エンドポイントを操作していきます。

外部SQLファイル用エンドポイントの違い

前回の記事で作業を行ったが外部SQLファイル用エンドポイントの大きな違いですが、前回の手順ではあらかじめ生成済のSQLファイル毎にエンドポイントが生成されていました。一方Chat2Query用エンドポイントではAPIを介した対話型でSQLを自動生成させて実行させる、という違いがあります。

さっそくやってみる

https://zenn.dev/kameping/articles/9ebee487d30359
の手順を終わらせると以下のようにChat2Query用エンドポイントが複数生成されています。

まず前回同様API Keyを作成します。外部SQLファイル用エンドポイントとChat2Query用エンドポイントで必要なAPI Keyは共通化されていないため別に作成する必要があります。
アプリのトップ画面に移動します。

Create API Keyを押します。

有効期限や権限の範囲を設定できますが一旦デフォルトのままNextをクリックします。

キーが生成されたのでCopy ALLを押してダイアログを閉じます。この値はどこかにメモっておきます。

ではAPIを操作します。現在V1V2があるのですが、ドキュメント上はV2を推奨しています。V2V1に比べて事前にデータベースを解析するというステップが発生するため手順は多くなりますが、その分制度が向上する、とのことです。

ではまず/v2/dataSummariesを操作しデータベースの解析を行います

Show Code Exampleをクリックするとcurlコマンドが出てきます。

鍵情報を先程コピーしたものに入れ替え実行すると以下のような値が戻ります。

{
  "code": 200,
  "msg": "",
  "result": {
    "data_summary_id": 284800,
    "job_id": "e03991c915f84a9a8a0466cb518322cb"
  }
}

つぎに/v2/jobs/{job_id}を先ほど戻ってきたjob_idで置換して実行します。以下のようにStatusがdoneになっていれば解析が完了です。

{
  "code": 200,
  "msg": "",
  "result": {
    "ended_at": 1714461101,
    "job_id": "e03991c915f84a9a8a0466cb518322cb",
    "reason": "",
    "result": {
      "app_id": 378074,
      "cluster_id": 10755440417080778301,
      "created_by": "harunobu.kameda@pingcap.com",
      "database": "test",
      "db_name": "test",
      "db_schema": {
        "user": {
          "columns": {
            "id": {
              "default": null,
              "description": "Unique identifier for each user",
              "description_cn": "",
              "description_en": "Unique identifier for each user",
              "name": "id",
              "nullable": false,
              "sample_data": "[\"1\", \"2\"]",
              "statistics": "{\"count\": 2, \"unique\": 2, \"top\": \"1\", \"freq\": 1}",
              "type": "int(11)"
            },
            "name": {
              "default": null,
              "description": "Name of the user, limited to 20 characters",
              "description_cn": "",
              "description_en": "Name of the user, limited to 20 characters",
              "name": "name",
              "nullable": false,
              "sample_data": "[\"koiping\", \"kameping\"]",
              "statistics": "{\"count\": 2, \"unique\": 2, \"top\": \"koiping\", \"freq\": 1}",
              "type": "varchar(20)"
            }
          },
          "description": "The table stores data about individual users and their corresponding names.",
          "entity": "User",
          "key_attributes": [
            "id",
            "name"
          ],
          "primary_key": "id",
          "status": "done",
          "table_name": "user",
          "type": "Dimension"
        }
      },
      "entity": {
        "User Information": {
          "attributes": [
            "user.id",
            "user.name"
          ],
          "involved_tables": [
            "user"
          ],
          "name": "User Information",
          "summary": "This larger entity combines data about individual users and their corresponding names."
        }
      },
      "org_id": "1372813089209225254",
      "project_id": 1372813089454541795,
      "region": "ap-northeast-1",
      "short_summary": "Centralized user data for personalized interactions.",
      "statistics": {
        "columns_count": 2,
        "tables_count": 1
      },
      "status": "done",
      "summary": "A data source that centralizes user information and names for personalized interactions and analysis.",
      "summary_keywords": [
        "User Information"
      ],
      "table_relationship": {},
      "tables_sample_data": {
        "user": {
          "sample_data_str": "[{\"id\": \"1\", \"name\": \"koiping\"}, {\"id\": \"2\", \"name\": \"kameping\"}]",
          "table_name": "user"
        }
      }
    },
    "status": "done"
  }
}

次に/v2/chat2dataで対話によりSQLを生成します。

curl --digest --user ${PUBLIC_KEY}:${PRIVATE_KEY} --request POST 'https://ap-northeast-1.data.tidbcloud.com/api/v1beta/app/chat2query-IjyQxRxx/endpoint/v2/chat2data'\
 --header 'content-type: application/json'\
 --data-raw '{
  "cluster_id": "10755440417080778301",
  "database": "test",
  "raw_question": "tell me all data of user table"
}'

以下のようなJSONが戻りますので、再度/v2/jobs/{job_id}でステータスを確認します。

{
  "code": 200,
  "msg": "",
  "result": {
    "data_summary_id": 284800,
    "job_id": "ad6e1748b44643c0867dfdb7e9a70de6",
    "session_context_id": 284801,
    "session_id": "d9dcf038b8d94e7f8a04b5d8c16d379f"
  }
}
{
  "code": 200,
  "msg": "",
  "result": {
    "ended_at": 1714461645,
    "job_id": "ad6e1748b44643c0867dfdb7e9a70de6",
    "reason": "",
    "result": {
      "feedback": "",
      "question_id": "865847e2-330e-40f0-8734-c4d3fc469bea",
      "raw_question": "tell me all data of user table",
      "session_context_id": 284801,
      "task_tree": {
        "0": {
          "assumptions": [],
          "breakdown_type": "Resolve",
          "chartOptions": {},
          "clarified_task": "Retrieve all data from the user table.",
          "columns": [
            {
              "col": "id"
            },
            {
              "col": "name"
            }
          ],
          "created_at": 1714461644,
          "description": "",
          "level": 0,
          "parent_task": "",
          "parent_task_id": "",
          "possibleExplanations": "",
          "reason": "no proxy needed for task",
          "recommendations": {},
          "rows": [
            [
              "1",
              "koiping"
            ],
            [
              "2",
              "kameping"
            ]
          ],
          "sequence_no": 0,
          "sql": "SELECT * FROM `user`;",
          "task": "tell me all data of user table",
          "task_id": "0"
        }
      },
      "time_elapsed": 4.1695873737335205
    },
    "status": "done"
  }
}

先ほど同様Statusdoneとなり以下のように生成されたSQLとその実行結果が確認できます。

          "sql": "SELECT * FROM `user`;",
          "task": "tell me all data of user table",
"rows": [
            [
              "1",
              "koiping"
            ],
            [
              "2",
              "kameping"
            ]

まだ作業中の場合以下のJSONが戻りますので少し待って再実行してください。

{
    "code": 400,
    "msg": "Data summary is not ready, please wait for a while and retry",
    "result": {}
}

まとめ

Chat2Query用エンドポイントではAPI経由で自然言語によりSQLを自動生成させ実行します。一方外部SQLファイル用エンドポイントと異なり直接SQLを実行させることはできません。このため運用上は使い分けを行うことになると思います。

Discussion