チュートリアル: リモート関数を使用してオブジェクト テーブルを分析する

このチュートリアルでは、花のデータセットの画像に基づいてオブジェクト テーブルを作成し、Cloud Vision API を使用して画像にラベルを付けるリモート関数を作成し、リモート関数を使用してオブジェクト テーブル内の画像を分析する方法を説明します。

必要な権限

  • データセットを作成するには、bigquery.datasets.create 権限が必要です。
  • 接続リソースを作成するには、次の権限が必要です。

    • bigquery.connections.create
    • bigquery.connections.get
  • 接続のサービス アカウントに権限を付与するには、次の権限が必要です。

    • resourcemanager.projects.setIamPolicy
  • オブジェクト テーブルを作成するには、次の権限が必要です。

    • bigquery.tables.create
    • bigquery.tables.update
    • bigquery.connections.delegate
  • リモート関数を作成するには、Cloud Functions デベロッパーのロールに関づけられた権限が必要です。

  • リモート関数を呼び出すには、Cloud Run 起動元のロールが必要です。

  • リモート関数を使用してオブジェクト テーブルを分析するには、オブジェクト テーブルに対する bigquery.tables.getData 権限が必要です。

料金

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

  • BigQuery: BigQuery で作成したテーブルのストレージ費用が発生します。
  • Cloud Functions: リモート関数の呼び出しの費用と、リモート関数が使用するコンピューティング リソース(Cloud Vision API の呼び出しを含む)の費用が発生します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

Cloud Storage の料金設定の詳細については、Cloud Storage の料金のページをご覧ください。

BigQuery ストレージの料金について詳しくは、BigQuery のドキュメントのストレージの料金をご覧ください。

Cloud Functions の料金設定の詳細については、Cloud Functions の料金ページをご覧ください。

Vision API の料金設定の詳細については、Vision ドキュメントの Cloud Vision の料金をご覧ください。

始める前に

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  3. Google Cloud プロジェクトで課金が有効になっていることを確認します

  4. BigQuery, BigQuery Connection API, and Cloud Functions API を有効にします。

    API を有効にする

  5. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  6. Google Cloud プロジェクトで課金が有効になっていることを確認します

  7. BigQuery, BigQuery Connection API, and Cloud Functions API を有効にします。

    API を有効にする

Cloud Functions の関数を作成する

関数を作成する手順は次のとおりです。

  1. [Cloud Functions] ページに移動します。

    Cloud Functions に移動

  2. [関数の作成] をクリックします。

  3. [環境] には、[第 2 世代] を選択します。

  4. [関数名] に「vision-ai」と入力します。

  5. [次へ] をクリックします。

  6. [ランタイム] には、[Python 3.9] を選択します。

  7. [エントリ ポイント] に「label_detection」と入力します。

  8. [main.py] を選択します。次のコードをコピーして貼り付けます。

    Python

    import urllib.request
    
    import flask
    import functions_framework
    from google.cloud import vision
    
    @functions_framework.http
    def label_detection(request: flask.Request) -> flask.Response:
        """BigQuery remote function to label input images.
        Args:
            request: HTTP request from BigQuery
            https://cloud.google.com/bigquery/docs/reference/standard-sql/remote-functions#input_format
        Returns:
            HTTP response to BigQuery
            https://cloud.google.com/bigquery/docs/reference/standard-sql/remote-functions#output_format
        """
        try:
            client = vision.ImageAnnotatorClient()
            calls = request.get_json()["calls"]
            replies = []
            for call in calls:
                content = urllib.request.urlopen(call[0]).read()
                results = client.label_detection({"content": content})
                replies.append(vision.AnnotateImageResponse.to_dict(results))
            return flask.make_response(flask.jsonify({"replies": replies}))
        except Exception as e:
            return flask.make_response(flask.jsonify({"errorMessage": str(e)}), 400)
    
    

  9. [requirements.txt] を選択します。以下のテキストをコピーして貼り付けます。

    Flask==2.2.2
    functions-framework==3.3.0
    google-cloud-vision==3.4.2
    Werkzeug==2.3.7
    

  10. [デプロイ] をクリックします。

  11. 関数のデプロイが完了したら、[トリガー] タブをクリックします。

  12. [トリガー URL] の値をコピーして、任意の場所に保存します。この情報は、リモート関数を作成するときに必要になります。

データセットを作成する

remote_function_test という名前のデータセットを作成します。

SQL

  1. [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. [エディタ] ペインで、次の SQL ステートメントを実行します。

    CREATE SCHEMA `PROJECT_ID.remote_function_test`;
    

    PROJECT_ID は、実際のプロジェクト ID に置き換えます。

bq

  1. Google Cloud コンソールで、「Cloud Shell をアクティブにする」をクリックします。

    Cloud Shell をアクティブにする

  2. bq mk コマンドを実行してリソースを作成します。

      bq mk --dataset --location=us PROJECT_ID:remote_function_test
      

    PROJECT_ID は、実際のプロジェクト ID に置き換えます。

接続を作成する

lake-connection という名前の接続を作成します。

コンソール

  1. [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. [ データを追加] をクリックし、[外部データソース] をクリックします。

  3. [接続タイプ] リストで、[BigLake とリモート関数(クラウド リソース)] を選択します。

  4. [接続 ID] フィールドに「lake-connection」と入力します。

  5. [接続を作成] をクリックします。

  6. [接続情報] ペインで、[サービス アカウント ID] フィールドの値をコピーし、任意の場所に保存します。接続のサービス アカウントに権限を付与するには、この情報が必要です。

bq

  1. Cloud Shell で bq mk コマンドを実行して、接続を作成します。

    bq mk --connection --location=us --connection_type=CLOUD_RESOURCE \
    lake-connection
    
  2. bq show コマンドを実行して、接続に関する情報を取得します。

    bq show --connection us.lake-connection
    
  3. properties 列から serviceAccountId プロパティの値をコピーし、任意の場所に保存します。接続のサービス アカウントに権限を付与するには、この情報が必要です。

Cloud Storage バケットを作成する

花のデータセットを格納するCloud Storage バケットを作成します。

接続のサービス アカウントに権限を付与する

サービス アカウントに権限を付与する手順は次のとおりです。

  1. [IAM と管理] ページに移動します。

    [IAM と管理] に移動

  2. [アクセス権を付与] をクリックします。

    [プリンシパルを追加] ダイアログが開きます。

  3. [新しいプリンシパル] フィールドに、前の手順でコピーしたサービス アカウント ID を入力します。

  4. [ロールを選択] フィールドで [Cloud Run] を選択し、[Cloud Run 起動元] を選択します。

  5. [別のロールを追加] をクリックします。

  6. [ロールを選択] フィールドで、[Cloud Storage] を選択し、続いて [Storage オブジェクト閲覧者] を選択します。

  7. [保存] をクリックします。

データセットを Cloud Storage にアップロードする

データセット ファイルを取得して、Cloud Storage で使用できるようにします。

  1. ローカルマシンに花のデータセットをダウンロードします。
  2. 前の手順で作成したバケットにデータセットをアップロードします。

オブジェクト テーブルを作成する

アップロードした花のデータセットに基づいて、sample_images という名前のオブジェクト テーブルを作成します。

SQL

  1. [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. [エディタ] ペインで、次の SQL ステートメントを実行します。

    CREATE EXTERNAL TABLE remote_function_test.sample_images
    WITH CONNECTION `us.lake-connection`
    OPTIONS(
      object_metadata = 'SIMPLE',
      uris = ['gs://BUCKET_NAME/*']);
    

    BUCKET_NAME は、さきほど作成したバケットの名前に置き換えます。

bq

Cloud Shell で bq mk コマンドを実行して、接続を作成します。

bq mk --table \
--external_table_definition=gs:"//BUCKET_NAME/*@us.lake-connection" \
--object_metadata=SIMPLE \
remote_function_test.sample_images

BUCKET_NAME は、作成したバケットの名前に置き換えます。

BigQuery リモート関数を作成する

label_detection という名前のリモート関数を作成します。

  1. BigQuery ページに移動します。

    [BigQuery] に移動

  2. [エディタ] ペインで、次の SQL ステートメントを実行します。

    CREATE OR REPLACE FUNCTION `remote_function_test.label_detection` (signed_url_ STRING) RETURNS JSON
    REMOTE WITH CONNECTION `us.lake-connection`
    OPTIONS(
    endpoint = 'TRIGGER_URL',
    max_batching_rows = 1
    );
    

    TRIGGER_URL は、前に保存したトリガー URL に置き換えます。URL は https://vision-ai-1abcd2efgh-uc.a.run.app のような形式になります。

リモート関数を呼び出す

sample_images オブジェクト テーブルに対して label_detection リモート関数を呼び出します。

  1. BigQuery ページに移動します。

    [BigQuery] に移動

  2. [エディタ] ペインで、次の SQL ステートメントを実行します。

    SELECT uri, remote_function_test.label_detection(signed_url)
    FROM EXTERNAL_OBJECT_TRANSFORM(
    TABLE remote_function_test.sample_images,
    ["SIGNED_URL"]
    )
    LIMIT 100;
    

    結果は次のようになります。

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    | uri                                                           | f0_                                                                                                            |
    —---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    |  gs://bq_huron_demo/flowers/daisy/100080576_f52e8ee070_n.jpg  |  {"face_annotations":[],"label_annotations":[{"confidence":0.0,"description":"Flower",                         |
    |                                                               |  "locale":"","locations":[],"mid":"/m/0c9ph5","properties":[],"score":0.9785631,"topicality":0.9785631},       |
    |                                                               |  {"confidence":0.0,"description":"Plant","locale":"","locations":[],"mid":"/m/05s2s","properties":[],          |
    |                                                               |  "Score":0.9635679,"topicality":0.9635679},{"confidence":0.0,"description":"camomile","locale":"",             |
    |                                                               |  "locations":[],"mid":"/m/011bc8hg","properties":[],"score":0.9110366,"topicality":0.9110366},                 |
    |                                                               |  {"confidence":0.0,"description":"Petal","locale":"","locations":[],"mid":"/m/016q19","properties":[],         |
    |                                                               |  "score":0.8927441,"topicality":0.8927441},{"confidence":0.0,"description":"Chamaemelum nobile","locale":"",   |
    |                                                               |  "locations":[],"mid":"/m/05cmcg","properties":[],"score":0.8460995,"topicality":0.8460995},                   |
    |                                                               |   {"confidence":0.0,"description":"Flowering plant","locale":"","locations":[],"mid":"/m/04sjm",               |
    |                                                               |  "properties":[],"score":0.7642974,"topicality":0.7642974},{"confidence":0.0,"description":"Annual plant",     |
    |                                                               |  "locale":"","locations":[],"mid":"/m/0jqb","properties":[],"score":0.7478164,                                 |
    |                                                               |  "topicality":0.7478164},{"confidence":0.0,"description":"Close-up","locale":"","locations":[],                |
    |                                                               |  "mid":"/m/02cqfm","properties":[],"score":0.7207553,"topicality":0.7207553},{"confidence":0.0,                |
    |                                                               |  "description":"Oxeye daisy","locale":"","locations":[],"mid":"/m/02qvnf","properties":[],                     |
    |                                                               |  "score":0.71786934,"topicality":0.71786934},{"confidence":0.0,"description":"Daisy family","locale":"",       |
    |                                                               |  "locations":[],"mid":"/m/0l5r","properties":[],"score":0.7164383,"topicality":0.7164383}],                    |
    |                                                               |  "landmark_annotations":[],"localized_object_annotations":[],"logo_annotations":[],"text_annotations":[]}      |
    —---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    | gs://bq_huron_demo/flowers/daisy/10140303196_b88d3d6cec.jpg   |  {"face_annotations":[],"label_annotations":[{"confidence":0.0,"description":"Flower","locale":"",             |
    |                                                               |  "locations":[],"mid":"/m/0c9ph5","properties":[],"score":0.9770426,"topicality":0.9770426},                   |
    |                                                               |  {"confidence":0.0,"description":"Plant","locale":"","locations":[],"mid":"/m/05s2s",                          |
    |                                                               |  "Properties":[],"score":0.95798975,"topicality":0.95798975},{"confidence":0.0,                                |
    |                                                               |  "description":"Petal","locale":"","locations":[],"mid":"/m/016q19","properties":[],                           |
    |                                                               |  "score":0.88984144,"topicality":0.88984144},{"confidence":0.0,"description":"Yellow",                         |
    |                                                               |  "locale":"","locations":[],"mid":"/m/088fh","properties":[],"score":0.84456813,                               |
    |                                                               |  "Topicality":0.84456813},{"confidence":0.0,"description":"camomile","locale":"",                              |
    |                                                               |  "locations":[],"mid":"/m/011bc8hg","properties":[],"score":0.7926449, "topicality":0.7926449},                |
    |                                                               |  {"confidence":0.0,"description":"Annual plant","locale":"","locations":[],"mid":"/m/0jqb",                    |
    |                                                               |  "Properties":[],"score":0.75020844, "topicality":0.75020844},{"confidence":0.0,                               |
    |                                                               |  "description":"Flowering plant","locale":"","locations":[],"mid":"/m/04sjm",                                  |
    |                                                               |  "Properties":[],"score":0.7403478,"topicality":0.7403478},{"confidence":0.0,                                  |
    |                                                               |  "description":"Chamaemelum nobile","locale":"","locations":[],"mid":"/m/05cmcg",                              |
    |                                                               |  "Properties":[],"score":0.7264577,"topicality":0.7264577},{"confidence":0.0,                                  |
    |                                                               |  "description":"Close-up","locale":"","locations":[],"mid":"/m/02cqfm","properties":[],                        |
    |                                                               |  "score":0.721242,"topicality":0.721242},{"confidence":0.0,"description":"Daisy family",                       |
    |                                                               |  "locale":"","locations":[],"mid":"/m/0l5r","properties":[],"score":0.7012979,                                 |
    |                                                               |  "Topicality":0.7012979}],"landmark_annotations":[],"localized_object_annotations":[],                         |
    |                                                               |  "logo_annotations":[],"text_annotations":[]}                                                                  |
    —------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------
    
    

クリーンアップ

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.