以前にGoogle App EngineからNo SQLである
Google Cloud Datastoreを利用する方法を紹介しましたが、当然のことながらRDBMSであるMySQLも利用することができます。Google Cloud PlatformでMySQLを利用するには、Cloud SQLを利用します。
ここではGoogle App Engine (Python 2.7) からCloud SQLの利用手順を紹介します。
環境の準備
ローカル環境においてPythonでMySQLを利用するには、MySQL-pythonが必要です。Windowsを利用している場合は、下記からダウンロード・インストールしてください。
https://www.codegood.com/downloads
どれをダウンロードすればいいかわからない方でも、多くは64bit用で大丈夫でしょう。
MySQL-python-1.2.3.win-amd64-py2.7.exe
プロジェクトへの記述
プロジェクトの設定を行う app.yaml には、ライブラリとしてMySQLdbを利用すること、CloudSQLの必要項目の記述を行います。具体的には下記のように書きます。
application: xxxxxxxxxx
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /static
static_dir: static
- url: /.*
script: main.app
libraries:
- name: ssl
version: latest
- name: MySQLdb
version: latest
env_variables:
CLOUDSQL_CONNECTION_NAME: xxxxxxxxxx:asia-northeast1:xxxx
CLOUDSQL_USER: xxxx
CLOUDSQL_PASSWORD: xxxxxxxxxx
「libraries」項目にMySQLdb (16, 17行目) を追加しています。また「env_variables」項目に接続名・ユーザ・パスワードを記述しています。
MySQLへの接続
私はローカル環境でテストするときは、ローカルで動作しているMySQLを利用しています。そのため、接続はGCP環境とローカル環境で次のように分けています。(全ソースコードは末尾に記します。)
import os
import MySQLdb
CLOUDSQL_CONNECTION_NAME = os.environ.get('CLOUDSQL_CONNECTION_NAME')
CLOUDSQL_USER = os.environ.get('CLOUDSQL_USER')
CLOUDSQL_PASSWORD = os.environ.get('CLOUDSQL_PASSWORD')
def connect_to_cloudsql():
if os.getenv('SERVER_SOFTWARE', '').startswith('Google App Engine/'):
cloudsql_unix_socket = os.path.join(
'/cloudsql', CLOUDSQL_CONNECTION_NAME)
db = MySQLdb.connect(
unix_socket=cloudsql_unix_socket,
user=CLOUDSQL_USER,
passwd=CLOUDSQL_PASSWORD,
charset="utf8")
else:
db = MySQLdb.connect(
host='127.0.0.1',
user=CLOUDSQL_USER,
passwd=CLOUDSQL_PASSWORD,
charset="utf8"
)
return db
CloudSQLに接続するには unix_socket の設定が必要になります。そのため11行目のように cloudsql_unix_socket を用意しています。
データ抽出
MySQLサーバへ接続できれば、あとは通常に利用方法と同じです。WebフレームワークFlaskで利用する一例を下記に記します。
@app.route('/mysql')
def mysql():
db = connect_to_cloudsql()
cursor = db.cursor()
sql = 'SELECT * FROM papi.users'
cursor.execute(sql)
output = ''
for row in cursor.fetchall():
output += '{}\n'.format(row)
db.close()
return output
先程の接続情報を db 変数を用い、cursorを取得します。
クエリ文を実行するにはexecuteメソッドを実行します。実行結果を取得するにはfetchallメソッドを用います。
そして最後に db 変数に対してcloseメソッドを実行してください。
注意
Flaskで利用する場合、間違っても db 変数をグローバル変数にしないでください。1つ1つのリクエストに対して db 変数を用意しないと、同時に複数のリクエストが発生したときエラーになります。
まとめ
Google App EngineでCloud SQL (MySQL) を利用する場合、app.yaml の libraries 項目に MySQLdb を記述します。また unix_socket に接続先を設定します。これだけで普段通りにMySQLを扱うことができます。
main.py
# coding: UTF-8
import os
from flask import Flask
import MySQLdb
app = Flask(__name__, static_url_path='/static')
CLOUDSQL_CONNECTION_NAME = os.environ.get('CLOUDSQL_CONNECTION_NAME')
CLOUDSQL_USER = os.environ.get('CLOUDSQL_USER')
CLOUDSQL_PASSWORD = os.environ.get('CLOUDSQL_PASSWORD')
def connect_to_cloudsql():
"""
Cloud SQLへ接続
:return: コネクション
"""
if os.getenv('SERVER_SOFTWARE', '').startswith('Google App Engine/'):
cloudsql_unix_socket = os.path.join(
'/cloudsql', CLOUDSQL_CONNECTION_NAME)
db = MySQLdb.connect(
unix_socket=cloudsql_unix_socket,
user=CLOUDSQL_USER,
passwd=CLOUDSQL_PASSWORD,
charset="utf8")
else:
db = MySQLdb.connect(
host='127.0.0.1',
user=CLOUDSQL_USER,
passwd=CLOUDSQL_PASSWORD,
charset="utf8"
)
return db
@app.route('/mysql')
def mysql():
"""
Cloud SQLへの接続テスト
:return:
"""
db = connect_to_cloudsql()
cursor = db.cursor()
sql = 'SELECT * FROM papi.users'
cursor.execute(sql)
output = ''
for row in cursor.fetchall():
# print(row[1])
output += '{}\n'.format(row)
db.close()
return output