Executar instruções SQL usando a API Data do Cloud SQL

Nesta página, descrevemos como executar instruções SQL em bancos de dados em instâncias do Cloud SQL usando a API Data. Com a API Data, você usa a API Cloud SQL Admin e a CLI gcloud para executar instruções SQL em qualquer instância em que você tenha ativado o acesso à API Data.

É possível usar a API Data com instâncias que usam endereços IP públicos, acesso a serviços particulares ou Private Service Connect. A API Data oferece suporte a todos os tipos de instruções SQL, incluindo linguagem de manipulação de dados (DML), linguagem de definição de dados (DDL) e linguagem de consulta de dados (DQL). A API Data é adequada para executar instruções administrativas pequenas e rápidas, como criar papéis ou usuários de banco de dados e fazer pequenas atualizações de esquema.

Antes de começar

Antes de executar instruções SQL em uma instância, siga estas etapas.

Configurar o usuário do banco de dados

A API Data precisa ser autenticada como um usuário do banco de dados para executar instruções SQL.

Para autenticar como um usuário integrado usando a senha, faça o seguinte:

  1. Crie uma conta de usuário com uma senha não vazia. Também é possível usar o usuário padrão sqlserver.
  2. Conceda à conta os papéis ou privilégios necessários para executar instruções SQL. Se o usuário não for sqlserver, conceda o papel db_owner ao usuário.
  3. Use o Gerenciador de secrets para criar um secret regional para armazenar a senha. Por segurança, a API Data pede o nome do recurso do secret em vez da senha na solicitação da API. O secret regional precisa ser armazenado na mesma região da instância do Cloud SQL. Um secret criado usando o endpoint global do Secret Manager não é compatível, mesmo que seja armazenado na mesma região.
  4. Como prática recomendada, defina IAM condições para permitir que um usuário acesse um secret específico, mas não outros secrets no projeto.

Papéis ou permissões necessárias

Por padrão, contas de usuário ou serviço com um dos seguintes papéis têm permissão para executar instruções SQL em uma instância do Cloud SQL (cloudsql.instances.executesql):

  • Cloud SQL Admin (roles/cloudsql.admin)
  • Cloud SQL Instance User (roles/cloudsql.instanceUser)
  • Cloud SQL Studio User (roles/cloudsql.studioUser)

Também é possível definir um papel personalizado do IAM para a conta de usuário ou serviço que inclui a cloudsql.instances.executesql permissão. Essa permissão é suportada em papéis personalizados do IAM.

Ativar ou desativar a API Data

Para usar a API Data, é necessário ativá-la para cada instância. É possível desativar a API Data a qualquer momento.

Console

  1. No Google Cloud console, acesse a página Instâncias do Cloud SQL.

    Acesse "Instâncias do Cloud SQL"

  2. Para abrir a página Visão geral de uma instância, clique no nome da instância.
  3. No menu de navegação SQL, selecione Conexões.
  4. Clique na guia Rede.
  5. Marque a caixa de seleção Permitir API Data.
  6. Clique em Salvar.

gcloud

Para ativar o acesso à API Data em uma instância, use o gcloud sql instances patch comando com a --data-api-access=ALLOW_DATA_API flag:

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

Para desativar o acesso à API Data, use a flag --data-api-access=DISALLOW_DATA_API:

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

Substitua INSTANCE_NAME pelo nome da instância em que a API Data será ativada ou desativada.

Executar uma instrução SQL

É possível executar instruções SQL em bancos de dados na instância do Cloud SQL usando a CLI gcloud ou a API REST.

Autenticar usando a senha

É possível executar instruções SQL usando a autenticação de senha integrada, quando a senha é armazenada como um secret regional com o Secret Manager na mesma região da instância do Cloud SQL.

gcloud

Para executar uma instrução SQL em um banco de dados em uma instância usando a CLI gcloud, use o comando gcloud sql instances execute-sql.

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

Faça as seguintes substituições:

  • INSTANCE_NAME: o nome da instância.
  • DATABASE_NAME: o nome do banco de dados na instância.
  • SQL_STATEMENT: a instrução SQL a ser executada. Se a instrução contiver espaços ou caracteres especiais do shell, ela precisará estar entre aspas.
  • USER: o usuário do banco de dados a ser autenticado como.
  • PASSWORD_SECRET_VERSION: o nome do recurso do Secret Manager que contém a senha do usuário do banco de dados. O secret precisa ser a regional e armazenado na mesma região da instância do Cloud SQL. O formato esperado do nome do recurso é projects/{project}/locations/{location}/secrets/{secret}/versions/{secret_version}.
  • PARTIAL_RESULT_MODE: opcional. Controla como responder quando o resultado está incompleto. Pode ser ALLOW_PARTIAL_RESULT, FAIL_PARTIAL_RESULT ou PARTIAL_RESULT_MODE_UNSPECIFIED. Consulte Modificar o comportamento de truncamento.

Terraform

É possível usar a API Data no Terraform para provisionar recursos no banco de dados, como bancos de dados, tabelas, extensões, usuários e concessões de privilégios, sem se conectar manualmente à instância. Para executar um script SQL no Terraform, use o google_sql_provision_script recurso do Terraform.

resource "google_sql_user" "built_in_user" {
  name     = "tf-user"
  host     = "%"  # Don't set this field for PostgreSQL and SQL Server.
  instance = google_sql_database_instance.instance.name
  password = "changeme"
  type     = "BUILT_IN"
}

# Create a regional secret. Global secrets are not supported even if
# located in one region only.
resource "google_secret_manager_regional_secret" "secret" {
  secret_id = "db-password"

  # Use the same region as the Cloud SQL instance.
  location = "us-central1"
}

resource "google_secret_manager_regional_secret_version" "secret_version" {
  secret = google_secret_manager_regional_secret.secret.id
  secret_data = "changeme"
}

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"
  user = google_sql_user.built_in_user.name

  # The location should be the same as the Cloud SQL instance's location.
  password_secret_version = "projects/my-project/locations/us-central1/secrets/db-password/versions/latest"

  # The built-in database user and password secret version must be created
  # first. Cloud SQL will retrieve password from Secret Manager
  # and connect to this user account to execute your script.
  depends_on = [
    google_sql_user.built_in_user,
    google_secret_manager_regional_secret_version.secret_version
  ]
}

Aplique as alterações

Para aplicar a configuração do Terraform em um Google Cloud projeto, siga as etapas nas seções a seguir.

Preparar o Cloud Shell

  1. Inicie o Cloud Shell.
  2. Defina o Google Cloud projeto em que você quer aplicar as configurações do Terraform.

    Você só precisa executar esse comando uma vez por projeto, e ele pode ser executado em qualquer diretório.

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    As variáveis de ambiente serão substituídas se você definir valores explícitos no arquivo de configuração do Terraform.

Preparar o diretório

Cada arquivo de configuração do Terraform precisa ter o próprio diretório, também chamado de módulo raiz.

  1. No Cloud Shell, crie um diretório e um novo arquivo dentro dele. O nome do arquivo precisa ter a extensão .tf, por exemplo, main.tf. Neste tutorial, o arquivo é chamado de main.tf.
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. Se você estiver seguindo um tutorial, poderá copiar o exemplo de código em cada seção ou etapa.

    Copie o exemplo de código no main.tf recém-criado.

    Se preferir, copie o código do GitHub. Isso é recomendado quando o snippet do Terraform faz parte de uma solução de ponta a ponta.

  3. Revise e modifique os parâmetros de amostra para aplicar ao seu ambiente.
  4. Salve as alterações.
  5. Inicialize o Terraform. Você só precisa fazer isso uma vez por diretório.
    terraform init

    Opcionalmente, para usar a versão mais recente do provedor do Google, inclua a opção -upgrade:

    terraform init -upgrade

Aplique as alterações

  1. Revise a configuração e verifique se os recursos que o Terraform vai criar ou atualizar correspondem às suas expectativas:
    terraform plan

    Faça as correções necessárias na configuração.

  2. Para aplicar a configuração do Terraform, execute o comando a seguir e digite yes no prompt:
    terraform apply

    Aguarde até que o Terraform exiba a mensagem "Apply complete!".

  3. Abra seu Google Cloud projeto para ver os resultados. No Google Cloud console, navegue até seus recursos na UI para verificar se foram criados ou atualizados pelo Terraform.

Excluir as alterações

A exclusão de um recurso google_sql_provision_script não exclui os recursos no banco de dados que ele criou. Para excluí-los, adicione instruções explicitamente no script, como drop ... if exists, e aplique as alterações.

REST

Para executar uma instrução SQL em um banco de dados em uma instância usando a API REST, envie uma solicitação POST para o endpoint executeSql:

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

O corpo da solicitação precisa conter o nome do banco de dados e a instrução SQL:

{
  "database": "DATABASE_NAME",
  "sqlStatement": "SQL_STATEMENT",
  "user": "USER",
  "passwordSecretVersion": "PASSWORD_SECRET_VERSION",
  "partialResultMode": "PARTIAL_RESULT_MODE"
}

Faça as seguintes substituições:

  • PROJECT_ID: o ID do projeto.
  • INSTANCE_NAME: o nome da instância.
  • DATABASE_NAME: o nome do banco de dados na instância.
  • SQL_STATEMENT: a instrução SQL a ser executada.
  • USER: o usuário do banco de dados a ser autenticado como.
  • PASSWORD_SECRET_VERSION: o nome do recurso do Secret Manager que contém a senha do usuário do banco de dados. O secret precisa ser a regional e armazenado na mesma região da instância do Cloud SQL. O formato esperado do nome do recurso é projects/{project}/locations/{location}/secrets/{secret}/versions/{secret_version}.
  • PARTIAL_RESULT_MODE: opcional. Controla como a API responde quando o resultado excede 10 MB. Pode ser FAIL_PARTIAL_RESULT, ALLOW_PARTIAL_RESULT ou PARTIAL_RESULT_MODE_UNSPECIFIED. Consulte Modificar o comportamento de truncamento.

Modificar o comportamento de truncamento

É possível controlar como os resultados grandes são processados ao executar o SQL, incluindo o "partialResultMode" campo na solicitação. Esse campo aceita os seguintes valores:

  • FAIL_PARTIAL_RESULT: padrão. Gere um erro se o resultado exceder 10 MB ou se apenas um resultado parcial puder ser recuperado. Não retorne o resultado.
  • ALLOW_PARTIAL_RESULT: retorne um resultado truncado e defina partial_result como verdadeiro se o resultado exceder 10 MB ou se apenas um resultado parcial puder ser recuperado devido a um erro. Não gere um erro.
  • PARTIAL_RESULT_MODE_UNSPECIFIED: modo não especificado, efetivamente o mesmo que FAIL_PARTIAL_RESULT.

Limitações

  • O limite de tamanho para uma resposta é de 10 MB. Os resultados que excedem esse tamanho são truncados se partialResultMode estiver definido como ALLOW_PARTIAL_RESULT. Caso contrário, um erro será gerado.
  • As solicitações são limitadas a 0,5 MB.
  • Só é possível executar instruções SQL para instâncias do Cloud SQL para SQL Server em execução.
  • O Cloud SQL não oferece suporte ao uso da API Data com instâncias configuradas para replicação de servidor externo.
  • As solicitações que levam mais de 30 segundos são canceladas. Não é possível definir um tempo limite de instrução maior usando SET LOCK_TIMEOUT.
  • O Cloud SQL limita o número de solicitações executeSql simultâneas por instância para evitar sobrecarga. Se o limite for atingido, as solicitações subsequentes falharão e retornarão um dos seguintes erros:

    • At most 'x' concurrent queries may be run on this instance. Try again later.
    • Maximum concurrent reads 'x' reached.

    O limite (x) é de 5 consultas para instâncias com menos de 10 GB de memória total e 10 consultas para instâncias com pelo menos 10 GB de memória total.

  • Cada resposta pode conter no máximo 10 mensagens ou avisos de banco de dados.

  • Se houver um erro de sintaxe ou execução da instrução, nenhum resultado será retornado.

  • A API Data não pode autenticar como usuários integrados com senhas vazias.

  • A API Data pode ser bloqueada temporariamente para fins de integridade de dados quando determinadas operações de manutenção estão em andamento na instância. Tente novamente mais tarde se isso acontecer.

  • O comando GO não é compatível. Esse comando é usado nos utilitários do Microsoft SQL Server para indicar que um lote de instruções foi encerrado e pode ser enviado ao SQL Server.
  • Se uma consulta incluir uma coluna binária, a API Data não poderá mostrá-la. Converta valores binários em uma string.

    Por exemplo, substitua:

    SELECT my_binary_column from my_table2;
    

    por:

    SELECT CONVERT(NVARCHAR(4000), my_binary_column, 1) from my_table2;
    
  • Quando várias consultas são executadas e uma delas falha, o primeiro erro encontrado é retornado. Algumas das instruções do lote antes do erro podem ter sido executadas com sucesso. É possível unir várias consultas em uma instrução transaction para evitar esse problema:

    BEGIN TRANSACTION
        YOUR_SQL_STATEMENTS
    COMMIT;
    

    Substitua:

    • YOUR_SQL_STATEMENTS: as instruções que você quer executar como parte dessa consulta
  • O script SQL e a resposta de execução podem transitar por locais intermediários entre o cliente e o local da instância de destino. Por esse motivo, as solicitações vão falhar com o erro "não compatível com instâncias em determinadas pastas de pacotes de controle do Assured Workloads" para determinados projetos do Assured Workloads e para projetos com constraints/sql.restrictNoncompliantResourceCreation aplicados manualmente.