Cloud SQL Data API を使用して SQL ステートメントを実行する

このページでは、Data API を使用して Cloud SQL インスタンスのデータベースに対して SQL ステートメントを実行する方法について説明します。Data API を使用すると、Cloud SQL Admin API と gcloud CLI を使用して、Data API アクセスを有効にしたインスタンスで SQL ステートメントを実行できます。

パブリック IP アドレス、プライベート サービス アクセス、または Private Service Connect を使用するインスタンスで Data API を使用できます。Data API は、データ操作言語(DML)、データ定義言語(DDL)、データクエリ言語(DQL)など、すべてのタイプの SQL ステートメントをサポートしています。Data API は、データベースのロールやユーザーの作成、スキーマの小規模な更新など、小規模で迅速な管理ステートメントの実行に適しています。Data API を使用して PostgreSQL 拡張機能を有効にすることもできます。

始める前に

インスタンスで SQL ステートメントを実行する前に、次の手順を行います。

データベース ユーザーを構成する

Data API は、SQL ステートメントを実行するためにデータベース ユーザーとして認証する必要があります。組み込みユーザー、IAM ユーザー、IAM サービス アカウント、IAM グループとして認証できます。

IAM を使用して認証するには、次の操作を行います。

  1. IAM データベース認証用にインスタンスを構成します。
  2. インスタンスに IAM ユーザー、サービス アカウント、またはグループを追加します。
  3. SQL ステートメントを実行するために必要なロールまたは権限をアカウントに付与します。データベース ロールは、アカウントの作成時またはアカウントの更新時に割り当てることができます。最小権限のカスタム データベース ロールを作成した場合は、アカウントに割り当てます。それ以外の場合は、事前定義された cloudsqlsuperuser ロールをアカウントに割り当て、Data API を使用して権限の少ない新しいカスタム データベースロールを作成し、cloudsqlsuperuser の代わりに新しいロールをアカウントに付与します。

パスワードを使用して組み込みユーザーとして認証するには、次の操作を行います。

  1. ユーザーを作成します
  2. Secret Manager を使用して、パスワードを保存するリージョン シークレットを作成します。セキュリティのため、Data API は API リクエストでパスワードではなくシークレットのリソース名を要求します。リージョン シークレットは、Cloud SQL インスタンスと同じリージョンに保存する必要があります。Secret Manager のグローバル エンドポイントを使用して作成されたシークレットは、同じリージョンに保存されていても対象外です。
  3. ベスト プラクティスとして、
  4. 特定のシークレットにはアクセスできるが、プロジェクト内の他のシークレットにはアクセスできないように、オプションの IAM 条件を定義します。

必要なロールまたは権限

デフォルトでは、次のいずれかのロールを持つユーザーまたはサービス アカウントに、Cloud SQL インスタンスで SQL ステートメントを実行する権限(cloudsql.instances.executesql)が付与されます。

  • Cloud SQL Adminroles/cloudsql.admin
  • Cloud SQL Instance Userroles/cloudsql.instanceUser
  • Cloud SQL Studio Userroles/cloudsql.studioUser

また、cloudsql.instances.executesql 権限を持つユーザーまたはサービス アカウントの IAM カスタムロールを定義することもできます。この権限は、IAM カスタムロールでサポートされています

Data API を有効または無効にする

Data API を使用するには、インスタンスごとに有効にする必要があります。Data API はいつでも無効にできます。

コンソール

  1. Google Cloud コンソールで、Cloud SQL の [インスタンス] ページに移動します。

    Cloud SQL の [インスタンス] に移動

  2. インスタンスの [概要] ページを開くには、インスタンス名をクリックします。
  3. SQL ナビゲーション メニューから [接続] を選択します。
  4. [ネットワーキング] タブをクリックします。
  5. [Allow Data API] チェックボックスをオンにします。
  6. [保存] をクリックします。

gcloud

インスタンスで Data API アクセスを有効にするには、--data-api-access=ALLOW_DATA_API フラグを指定して gcloud sql instances patch コマンドを使用します。

gcloud sql instances patch INSTANCE_NAME --data-api-access=ALLOW_DATA_API

Data API アクセスを無効にするには、--data-api-access=DISALLOW_DATA_API フラグを使用します。

gcloud sql instances patch INSTANCE_NAME --data-api-access=DISALLOW_DATA_API

INSTANCE_NAME は、Data API を有効または無効にするインスタンスの名前に置き換えます。

SQL ステートメントを実行する

Cloud SQL インスタンスのデータベースに対して SQL ステートメントを実行するには、gcloud CLI または REST API を使用します。

gcloud

gcloud CLI を使用してインスタンスのデータベースに対して SQL ステートメントを実行するには、gcloud sql instances execute-sql コマンドを使用します。

IAM を使用して接続するには:

gcloud sql instances execute-sql INSTANCE_NAME \
--database=DATABASE_NAME \
--sql=SQL_STATEMENT \
--partial-result-mode=PARTIAL_RESULT_MODE

次のように置き換えます。

  • INSTANCE_NAME: インスタンスの名前。
  • DATABASE_NAME: インスタンス内のデータベースの名前。
  • SQL_STATEMENT: 実行する SQL ステートメント。ステートメントにスペースまたはシェル特殊文字が含まれている場合は、引用符で囲む必要があります。
  • PARTIAL_RESULT_MODE: 省略可。結果が不完全な場合の対応方法を制御します。ALLOW_PARTIAL_RESULTFAIL_PARTIAL_RESULTPARTIAL_RESULT_MODE_UNSPECIFIED のいずれかです。切り捨て動作の変更をご覧ください。

必要に応じて --project=PROJECT_ID フラグを指定することもできます。

パスワードを使用して組み込みユーザーとして接続するには:

gcloud sql instances execute-sql INSTANCE_NAME \
--database=DATABASE_NAME \
--sql=SQL_STATEMENT \
--user=USER \
--password-secret-version=PASSWORD_SECRET_VERSION \
--partial-result-mode=PARTIAL_RESULT_MODE

次のように置き換えます。

  • USER: 認証するデータベース ユーザー。
  • PASSWORD_SECRET_VERSION: データベース ユーザーのパスワードを保持する Secret Manager シークレットのリソース名。シークレットはリージョン シークレットであり、Cloud SQL インスタンスと同じリージョンに保存する必要があります。リソース名の形式は projects/{project}/locations/{location}/secrets/{secret}/versions/{secret_version} です。

Terraform

Terraform で Data API を使用すると、インスタンスに手動で接続しなくても、データベース、テーブル、拡張機能、ユーザー、権限付与などのデータベース内リソースをプロビジョニングできます。Terraform で SQL スクリプトを実行するには、 google_sql_provision_script Terraform リソースを使用します。

resource "google_sql_database_instance" "instance" {
  name             = "my-instance"
  database_version = "POSTGRES_17"

  settings {
    tier            = "db-perf-optimized-N-2"
    data_api_access = "ALLOW_DATA_API"  # This allows the use of Data API.
    database_flags {
      name  = "cloudsql.iam_authentication"
      value = "on"
    }
  }
}

/*
 * Create a database user for your account and grant roles so it has privilege to
 * access the database. Set the type to CLOUD_IAM_USER for huamn account or
 * CLOUD_IAM_SERVICE_ACCOUNT for service account. If a service account is used
 * and the instance is Postgres, trim the ".gserviceaccount.com"
 * suffix to avoid exceeding the username length limit.
*/
resource "google_sql_user" "iam_user" {
  name     = "account-used-to-apply-this-config@example.com"
  instance = google_sql_database_instance.instance.name
  type     = "CLOUD_IAM_USER"

  # Roles granted to the user. For least privilege, you can create smaller roles
  # and then assign them to this user in place of `cloudsqlsuperuser`.
  database_roles = ["cloudsqlsuperuser"]
}

resource "google_sql_database" "database" {
  name     = "my-database"
  instance = google_sql_database_instance.instance.name
}

resource "google_sql_provision_script" "script" {
  # You can inline the script or import from a file like script  = file("${path.module}/script.sql")
  # When modified, the whole script will be executed again. It's recommended to
  # make the script idempotent with patterns like create if not exists ... or
  # if not exists (select ...) then ... end if.
  script  = "CREATE TABLE IF NOT EXISTS table1 ( col VARCHAR(16) NOT NULL );"

  instance = google_sql_database_instance.instance.name
  database = google_sql_database.database.name
  description = "sql script to create tables"

  # The identity account used to apply your Terraform config must exist as an
  # IAM user or IAM service account in the instance. Terraform connects to the
  # instance via IAM database authentication to execute the script.
  depends_on = [google_sql_user.iam_user]
}

変更を適用する

Google Cloud プロジェクトで Terraform 構成を適用するには、次のセクションの手順を完了します。

Cloud Shell を準備する

  1. Cloud Shell を起動します。
  2. Terraform 構成を適用するデフォルトの Google Cloud プロジェクトを設定します。

    このコマンドは、プロジェクトごとに 1 回だけ実行する必要があります。これは任意のディレクトリで実行できます。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    Terraform 構成ファイルに明示的な値を設定すると、環境変数がオーバーライドされます。

ディレクトリを準備する

Terraform 構成ファイルには独自のディレクトリ(ルート モジュールとも呼ばれます)が必要です。

  1. Cloud Shell で、ディレクトリを作成し、そのディレクトリ内に新しいファイルを作成します。ファイル名の拡張子は .tf にする必要があります(例: main.tf)。このチュートリアルでは、このファイルを main.tf とします。
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. チュートリアルを使用している場合は、各セクションまたはステップのサンプルコードをコピーできます。

    新しく作成した main.tf にサンプルコードをコピーします。

    必要に応じて、GitHub からコードをコピーします。Terraform スニペットがエンドツーエンドのソリューションの一部である場合は、この方法をおすすめします。

  3. 環境に適用するサンプル パラメータを確認し、変更します。
  4. 変更を保存します。
  5. Terraform を初期化します。これは、ディレクトリごとに 1 回だけ行います。
    terraform init

    最新バージョンの Google プロバイダを使用する場合は、-upgrade オプションを使用します。

    terraform init -upgrade

変更を適用する

  1. 構成を確認して、Terraform が作成または更新するリソースが想定どおりであることを確認します。
    terraform plan

    必要に応じて構成を修正します。

  2. 次のコマンドを実行します。プロンプトで「yes」と入力して、Terraform 構成を適用します。
    terraform apply

    Terraform に「Apply complete!」というメッセージが表示されるまで待ちます。

  3. Google Cloud プロジェクトを開いて結果を表示します。 Google Cloud コンソールの UI でリソースに移動して、Terraform によって作成または更新されたことを確認します。

変更を削除する

google_sql_provision_script リソースを削除しても、作成されたデータベース内リソースは削除されません。削除するには、drop ... if exists などのステートメントをスクリプトに明示的に追加し、変更を適用します。

REST

REST API を使用してインスタンスのデータベースに対して SQL ステートメントを実行するには、executeSql エンドポイントに POST リクエストを送信します。

POST https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_NAME/executeSql

リクエストの本文には、データベース名と SQL ステートメントを含める必要があります。

{
  "database": "DATABASE_NAME",
  "sqlStatement": "SQL_STATEMENT",
  "partialResultMode": "PARTIAL_RESULT_MODE"
  "autoIamAuthn": true
}

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID。
  • INSTANCE_NAME: インスタンスの名前。
  • DATABASE_NAME: インスタンス内のデータベースの名前。
  • SQL_STATEMENT: 実行する SQL ステートメント。
  • PARTIAL_RESULT_MODE: 省略可。結果が 10 MB を超えた場合に API がどのように応答するかを制御します。FAIL_PARTIAL_RESULTALLOW_PARTIAL_RESULTPARTIAL_RESULT_MODE_UNSPECIFIED のいずれかです。切り捨て動作の変更をご覧ください。

切り捨ての動作を変更する

SQL の実行時に大きな結果を処理する方法を制御するには、リクエストに "partialResultMode" フィールドを含めます。このフィールドでは次の値を指定できます。

  • FAIL_PARTIAL_RESULT: デフォルト。結果が 10 MB を超える場合、または結果の一部しか取得できない場合は、エラーをスローします。結果を返さないでください。
  • ALLOW_PARTIAL_RESULT: 結果が 10 MB を超える場合、またはエラーにより部分的な結果しか取得できない場合は、切り捨てられた結果を返し、partial_result を true に設定します。エラーをスローしない。
  • PARTIAL_RESULT_MODE_UNSPECIFIED: 未指定モード。事実上 FAIL_PARTIAL_RESULT と同じです。

制限事項

  • レスポンスのサイズの上限は 10 MB です。partialResultModeALLOW_PARTIAL_RESULT に設定されている場合、このサイズを超える結果は切り捨てられます。それ以外の場合は、エラーがスローされます。
  • リクエストは 0.5 MB に制限されています。
  • SQL ステートメントは、実行中の Cloud SQL for PostgreSQL インスタンスに対してのみ実行できます。
  • Cloud SQL は、外部サーバー レプリケーション用に設定されたインスタンスでの Data API の使用をサポートしていません。
  • 30 秒を超えるリクエストはキャンセルされます。SET STATEMENT_TIMEOUT を使用してステートメント タイムアウトを長く設定することはできません。
  • Cloud SQL では、各ユーザーの同時 executeSql リクエストの数がインスタンスあたり 10 個に制限されています。この上限に達すると、後続のリクエストは「このインスタンスで実行できる同時クエリは最大 10 個です。後でやり直してください。」または「同時読み取りの最大数 10 に達しました。」
  • 各レスポンスには、最大 10 個のデータベース メッセージまたは警告を含めることができます。
  • ステートメントの構文エラーまたは実行エラーがある場合、結果は返されません。
  • 大量のメモリを消費するステートメントは、メモリ不足エラーを引き起こす可能性があります。これらのエラーを回避する方法について詳しくは、メモリ使用量を管理するためのベスト プラクティスをご覧ください。メモリ使用率が高いデータベース インスタンスを実行すると、パフォーマンスの問題や機能の停止、さらにはデータベース停止の原因となることがよくあります。
  • インスタンスで特定のメンテナンス オペレーションが進行中の場合、データの完全性を確保するために Data API が一時的にブロックされることがあります。その場合は、しばらくしてからもう一度お試しください。
  • SQL スクリプトとその実行レスポンスは、クライアントとターゲット インスタンスのロケーション間の中間ロケーションを通過する可能性があります。このため、特定の Assured Workloads プロジェクトと constraints/sql.restrictNoncompliantResourceCreation が手動で適用されているプロジェクトでは、リクエストが失敗し、「特定の Assured Workloads コントロール パッケージ フォルダのインスタンスではサポートされていません」というエラーが返されます。