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

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

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

始める前に

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

必要なロールまたは権限

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

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

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

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

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

コンソール

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

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

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

gcloud

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

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 ステートメントを実行する

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

gcloud

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

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 フラグを含めることもできます。

Terraform

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

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

  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.
 */
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. Smaller roles are preferred, if exist.
  # This field doesn't support MySQL 5.6 and 5.7.
  database_roles = ["cloudsqlsuperuser"]
}

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 DATABASE pets;"
  instance = google_sql_database_instance.instance.name

  # Some of your queries may require a database. You can create and use a
  # database in the script or explicitly create and reference a database
  # like database = google_sql_database.database.name.

  description = "sql script to create DBs"

  # 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_RESULT または ALLOW_PARTIAL_RESULT を指定できます。切り捨て動作を変更するをご覧ください。

切り捨て動作を変更する

SQL の実行時に大きな結果を処理する方法を制御できます。

  • リクエストに "partialResultMode" フィールドを含めます。このフィールドには次の値を指定できます。
    • FAIL_PARTIAL_RESULT: 結果が 10 MB を超える場合、または部分的な結果しか取得できない場合は、エラーをスローします。結果は返されません。
    • ALLOW_PARTIAL_RESULT: 結果が 10 MB を超える場合、またはエラーにより部分的な結果しか取得できない場合は、切り捨てられた結果を返し、partial_result を true に設定します。エラーはスローされません。

制限事項

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