Cloud SQL の使用

このページでは、App Engine アプリケーションから Cloud SQL インスタンスに接続する方法を説明します。また、App Engine で Cloud SQL を使用する場合のベスト プラクティスについても説明します。

Cloud SQL は、Google Cloud Platform 上のリレーショナル データベースの設定、維持、運用、管理を簡単にできるようにするフルマネージド データベース サービスです。Cloud SQL の詳細については、Cloud SQL のドキュメントをご覧ください。

Cloud SQL を設定する

App Engine は、Cloud SQL for MySQL インスタンスと Cloud SQL for MySQL インスタンスをサポートします。新しい Cloud SQL インスタンスのセットアップ方法については、下記の手順をご覧ください。

Cloud SQL に接続する

App Engine はローカル UNIX ソケット インターフェースを備えていて、App Engine サービス アカウントを使用した自動認証により Cloud SQL インスタンスにアクセスできます。このインターフェースは MySQL インスタンスと PostgreSQL インスタンスの両方で機能します。ソケット インターフェースは、/cloudsql/CLOUDSQL-CONNECTION-NAME ファイル システムパスで使用できます。

Cloud SQL インスタンスが App Engine インスタンスとは異なるリージョンにある場合は、このガイドの最後に記載されている手順に沿って、アプリケーションに Cloud SQL インスタンスへのアクセス権を付与してください。

セキュリティ上の理由から、標準の TCP ソケットを使用して App Engine アプリを Cloud SQL インスタンスに接続することは避けてください。App Engine は Cloud SQL インスタンスへのコネクタをサポートしています。次の例では、パッケージ PyMySQLSQLAlchemy(MySQL の場合)と psycopg2(PostgresSQL の場合)で使用します。

MySQL

import os

from flask import Flask
import pymysql

db_user = os.environ.get('CLOUD_SQL_USERNAME')
db_password = os.environ.get('CLOUD_SQL_PASSWORD')
db_name = os.environ.get('CLOUD_SQL_DATABASE_NAME')
db_connection_name = os.environ.get('CLOUD_SQL_CONNECTION_NAME')

app = Flask(__name__)

@app.route('/')
def main():
    # When deployed to App Engine, the `GAE_ENV` environment variable will be
    # set to `standard`
    if os.environ.get('GAE_ENV') == 'standard':
        # If deployed, use the local socket interface for accessing Cloud SQL
        unix_socket = '/cloudsql/{}'.format(db_connection_name)
        cnx = pymysql.connect(user=db_user, password=db_password,
                              unix_socket=unix_socket, db=db_name)
    else:
        # If running locally, use the TCP connections instead
        # Set up Cloud SQL Proxy (cloud.google.com/sql/docs/mysql/sql-proxy)
        # so that your application can use 127.0.0.1:3306 to connect to your
        # Cloud SQL instance
        host = '127.0.0.1'
        cnx = pymysql.connect(user=db_user, password=db_password,
                              host=host, db=db_name)

    with cnx.cursor() as cursor:
        cursor.execute('SELECT NOW() as now;')
        result = cursor.fetchall()
        current_time = result[0][0]
    cnx.close()

    return str(current_time)

PostgreSQL

import os

from flask import Flask
import psycopg2

db_user = os.environ.get('CLOUD_SQL_USERNAME')
db_password = os.environ.get('CLOUD_SQL_PASSWORD')
db_name = os.environ.get('CLOUD_SQL_DATABASE_NAME')
db_connection_name = os.environ.get('CLOUD_SQL_CONNECTION_NAME')

app = Flask(__name__)

@app.route('/')
def main():
    # When deployed to App Engine, the `GAE_ENV` environment variable will be
    # set to `standard`
    if os.environ.get('GAE_ENV') == 'standard':
        # If deployed, use the local socket interface for accessing Cloud SQL
        host = '/cloudsql/{}'.format(db_connection_name)
    else:
        # If running locally, use the TCP connections instead
        # Set up Cloud SQL Proxy (cloud.google.com/sql/docs/mysql/sql-proxy)
        # so that your application can use 127.0.0.1:3306 to connect to your
        # Cloud SQL instance
        host = '127.0.0.1'

    cnx = psycopg2.connect(dbname=db_name, user=db_user,
                           password=db_password, host=host)
    with cnx.cursor() as cursor:
        cursor.execute('SELECT NOW() as now;')
        result = cursor.fetchall()
    current_time = result[0][0]
    cnx.commit()
    cnx.close()

    return str(current_time)

この例では次の環境変数を使用しています。

  • CLOUD_SQL_USERNAME
  • CLOUD_SQL_PASSWORD
  • CLOUD_SQL_DATABASE_NAME
  • CLOUD_SQL_CONNECTION_NAME

環境変数はアプリの app.yaml ファイルで設定できます。こうした変数の値を確認するには、次の手順を行います。

  • Cloud SQL ダッシュボードに移動します。
  • 接続するインスタンスをクリックします。
  • インスタンスの接続名が Connect to this instance カードにリスト表示されます。
  • ユーザー認証情報とデータベースが USERS タブと DATABASES タブに表示されます。

Cloud SQL インスタンスの接続名の形式は、YOUR-PROJECT-ID:YOUR-REGION:YOUR-INSTANCE-ID です。gcloud コマンドライン ツールを使用してその値を確認することもできます。

gcloud sql instances describe YOUR-INSTANCE-ID

PostgreSQL では、.s.PGSQL.5432 接尾辞をローカル ソケット インターフェースのパスに追加する必要があります。psycopg2 などの一部のコネクタ ライブラリでは、この接尾辞が自動的に追加されます。他のコネクタの場合、ローカル ソケット インターフェースのフルパスは /cloudsql/YOUR-INSTANCE-CONNECTION/.s.PGSQL.5432 です。

App Engine で Cloud SQL を使用する場合のベスト プラクティス

接続プーリング

最適なパフォーマンスを得るには、接続プーリングをサポートするコネクタ ライブラリを使用することをおすすめします。接続プールを使用すると、アプリで毎回新しい接続を開いて閉じなくても、既存のデータベース接続を再利用できます。また、切断された接続を自動的に再開できます。

スケーリング設定Cloud SQL の割り当てと上限に適した最大接続数を設定して、App Engine アプリが急激なスケールアップ中に接続リソースを消費しないようにする必要があります。

可能であれば、接続オブジェクトをグローバル スコープで割り当てます。接続を閉じられないことはよくあるため、これによりパフォーマンスが改善されるだけでなく、エラーの発生も少なくなります。

接続を閉じる

接続プールを使用する場合

  1. プールから接続をリクエストします。
  2. クエリを送信します。
  3. 接続をプールに戻します。接続を閉じたり破棄したりする必要はありません。

接続プールを使用しない場合や個別の接続を作成する場合は、クエリの完了後に必ず接続を閉じてください。App Engine インスタンスが自動的にスケールダウンされると、すべての接続が自然に閉じられます。

次のコードサンプルは、接続プーリングの例を示しています。

MySQL

import os

from flask import Flask
import sqlalchemy

db_user = os.environ.get('CLOUD_SQL_USERNAME')
db_password = os.environ.get('CLOUD_SQL_PASSWORD')
db_name = os.environ.get('CLOUD_SQL_DATABASE_NAME')
db_connection_name = os.environ.get('CLOUD_SQL_CONNECTION_NAME')

# When deployed to App Engine, the `GAE_ENV` environment variable will be
# set to `standard`
if os.environ.get('GAE_ENV') == 'standard':
    # If deployed, use the local socket interface for accessing Cloud SQL
    unix_socket = '/cloudsql/{}'.format(db_connection_name)
    engine_url = 'mysql+pymysql://{}:{}@/{}?unix_socket={}'.format(
        db_user, db_password, db_name, unix_socket)
else:
    # If running locally, use the TCP connections instead
    # Set up Cloud SQL Proxy (cloud.google.com/sql/docs/mysql/sql-proxy)
    # so that your application can use 127.0.0.1:3306 to connect to your
    # Cloud SQL instance
    host = '127.0.0.1'
    engine_url = 'mysql+pymysql://{}:{}@{}/{}'.format(
        db_user, db_password, host, db_name)

# The Engine object returned by create_engine() has a QueuePool integrated
# See https://docs.sqlalchemy.org/en/latest/core/pooling.html for more
# information
engine = sqlalchemy.create_engine(engine_url, pool_size=3)

app = Flask(__name__)

@app.route('/')
def main():
    cnx = engine.connect()
    cursor = cnx.execute('SELECT NOW() as now;')
    result = cursor.fetchall()
    current_time = result[0][0]
    # If the connection comes from a pool, close() will send the connection
    # back to the pool instead of closing it
    cnx.close()

    return str(current_time)

PostgreSQL

import os

from flask import Flask
import psycopg2.pool

db_user = os.environ.get('CLOUD_SQL_USERNAME')
db_password = os.environ.get('CLOUD_SQL_PASSWORD')
db_name = os.environ.get('CLOUD_SQL_DATABASE_NAME')
db_connection_name = os.environ.get('CLOUD_SQL_CONNECTION_NAME')

# When deployed to App Engine, the `GAE_ENV` environment variable will be
# set to `standard`
if os.environ.get('GAE_ENV') == 'standard':
    # If deployed, use the local socket interface for accessing Cloud SQL
    host = '/cloudsql/{}'.format(db_connection_name)
else:
    # If running locally, use the TCP connections instead
    # Set up Cloud SQL Proxy (cloud.google.com/sql/docs/mysql/sql-proxy)
    # so that your application can use 127.0.0.1:3306 to connect to your
    # Cloud SQL instance
    host = '127.0.0.1'

db_config = {
    'user': db_user,
    'password': db_password,
    'database': db_name,
    'host': host
}

cnxpool = psycopg2.pool.ThreadedConnectionPool(minconn=1, maxconn=3,
                                               **db_config)

app = Flask(__name__)

@app.route('/')
def main():
    cnx = cnxpool.getconn()
    with cnx.cursor() as cursor:
        cursor.execute('SELECT NOW() as now;')
        result = cursor.fetchall()
    current_time = result[0][0]
    cnx.commit()
    cnxpool.putconn(cnx)

    return str(current_time)

Cloud SQL と App Engine を別々のプロジェクトで実行する

App Engine アプリと Google Cloud Platform プロジェクトの Cloud SQL インスタンスでは、App Engine アプリを表すサービス アカウントに Cloud SQL インスタンスへのアクセス権を付与する必要があります。

  1. App Engine アプリケーションに関連付けられたサービス アカウントを特定します。デフォルトの App Engine サービス アカウント名は [PROJECT-ID]@appspot.gserviceaccount.com です。

    App Engine サービス アカウントは [IAM 権限] ページで確認できます。プロジェクトは Cloud SQL インスタンスにではなく、必ず App Engine アプリケーションに対して選択してください。

    IAM 権限ページに移動

  2. Google Cloud Platform Console の [IAM と管理] ページに移動します。

    [IAM と管理] ページに移動

  3. Cloud SQL インスタンスを含むプロジェクトを選択します。
  4. サービス アカウント名を検索します。
  5. サービス アカウントがすでに存在し、cloudsql.instances.connect 権限を含む役割が割り当てられている場合は、このセクションの残りの部分をスキップできます。

    役割 Cloud SQL ClientCloud SQL EditorCloud SQL Admin は、従来のプロジェクト役割 EditorOwner と同様に、必要な権限を提供します。

  6. それ以外の場合、[追加] をクリックしてサービス アカウントを追加します。
  7. [メンバーの追加] ダイアログで、サービス アカウントの名前を指定し、cloudsql.instances.connect 権限を含む役割を選択します(Cloud SQL の事前定義された役割のうち、閲覧者以外の役割はこの条件に当てはまります)。

    [Project] > [編集者] の順に選択して、基本の役割である編集者を使用することもできますが、編集者の役割には Google Cloud Platform 全体に対する権限が含まれます。

    こうした役割が表示されない場合、Google Cloud Platform ユーザーに resourcemanager.projects.setIamPolicy 権限がない可能性があります。権限を確認するには、Google Cloud Platform Console の [IAM] ページにアクセスし、自分のユーザー ID を検索します。

  8. [追加] をクリックします。

    これで、指定した役割を持つサービス アカウントが表示されます。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Python 3 の App Engine スタンダード環境