Google App Engine & Goolge Cloud SQL(MySQL 5.5)& Python
色々あるPaaSで無料で試せる(http://http://server.kensapo.com/cloud.html)というとどうしても「Google App Engine」になってしまいます。しかし、DB的にビッグテーブルしかないとなると、相当これまでのコーディングスタイルを変えざるを得ないので、二の足を踏んでいたのですが、よく調べてみると、とっくにGoogle Cloud SQL(MySQL5.5)が使えるようになっているではありませんか(気づくのに遅すぎ!)。しかも2013年の6月まで無料です!
そこで今回、GoogleのTutorial(https://developers.google.com/appengine/training/cloud-sql/application_with_local_mysql?hl=ja)にあるGustbookを作成してみました、その時の備忘録です(というか、ほとんどTutorialそのまんまです)。
- Google App Engine
- Google APIs Console
以上の2つのサイトでそれぞれ、アプリケーションの登録、Google Cloud SQLの登録およびそれをどのアプリケーションの使うのかという設定を行います。
アプリの登録
Googleアカウント等を登録していない人はhttp://symfoware.blog68.fc2.com/blog-entry-252.htmlあたりを見て、まずは登録する必要があります。ちなみに、GoogleのアカウントとGoogle App Engineのアカウントは同じでOKですが、手続きは必要です。
- http://www.mitchy-world.jp/itmemo/gae/15.htmなどを参考にして、アプリを登録します。今回はsqltestfirstという名前で私は登録しました。
Google Cloud SQLのインスタンス作成
- http://libro.tuyano.com/index3?id=1062003(→このサイトではbillingでチャージしなくてはならないようなことが書いていますが、現在はそのような必要はないようです)や本家のhttps://developers.google.com/cloud-sql/docs/before_you_begin?hl=jaに詳しく書いていますので詳細はこちらをご覧ください。概略は次のような感じです。
- https://code.google.com/apis/consoleに行く
- プロジェクトがない場合はプロジェクト名を指定して、プロジェクトを作成します。例えば「myApplication201303」など。
- 左側画面の「service」をクリックして、右側の画面のサービスの画面からGoogle Cloud SQLをONにする
- 左側の「Billing」を選択して、カードの登録をします。無料なのですが、登録だけは必要のようです。登録後数十分待ちます(数時間という人もいます)。私の場合は、何度か試しているうちに(すぐに反映すると勘違いしていたもので・涙)、反映されました。
- 右側のGoogle Cloud SQLのメニューをクリックします。
- 右の方にある「New Instance...」をクリックします。
- Name:データベース名を入力。例えば「sqltest」。
- Size:サイズは無料のD0を選択するのがポイントです。これが無料のサイズだからです(現在は赤い字で無料はD0だよ、って書いてあります)。
- Replication Mode:データ書き出しのモード指定。とりあえず、Synchronousを選択。
- Pricing Plan:D0を選んでいるので、選べないようになっています。
- Authorized Application:上記で登録したGoogle App Engineで登録したアプリを選択(sqltestfirst)。
- Create instanceをクリックして作成。結果、
- その結果、そのGoogle Cloud SQLのインスタンスID(上記の例だと)「myApplication201303::sqltest」となり、後にこれが必要になります。
開発環境の整備
- Pythonは昨年末2.7も利用できるようになったので(http://code.google.com/p/googleappengine/wiki/SdkReleaseNotes)、とりあえずPython2.7をインストールしておきます。バージョンが低かったりしたら、https://github.com/saghul/pythonzをhttp://labs.opentone.co.jp/?p=1432あたりを参考にインストールすると、いくつかのバージョンを切り替えられて便利です。
- 今回はMySQLの試験なので、当然これもインストール(たぶん、自動でインストールされているもの---5.5---があったらそれで大丈夫だと思う)。省略。
- App Engine SDKをダウンロード(https://developers.google.com/appengine/downloads?hl=ja)。ローカルのOSによって違うし、JavaなのかPythonなのかでも違うので要注意。私はCentOSとMacなのとPythonなので、2つをダウンロードしました。
とりあえずローカルでアプリ作成
- ここからは、ほぼhttps://developers.google.com/appengine/training/cloud-sql/?hl=ja(日本語)の通り。
- 次のようにユーザとそのパスワード、DBの作成、テーブルの作成をします。
CREATE USER 'hoge'@'localhost' IDENTIFIED BY 'fuga'; GRANT ALL PRIVILEGES ON *.* TO 'hoge'@'localhost' WITH GRANT OPTION; create database & table create database guestbook charset utf8; use guestbook; CREATE TABLE entries (id int not null auto_increment primary key, guest_name varchar(255), content varchar(255), created_at timestamp) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into entries (guest_name, content) values ('chikkun', 'Myself');
cd mkdir sqltest cd sqltest emacs app.yaml
- app.yamlの中身。application:には先程Google App Engineで登録したアプリ名を入れます。また、今回はpython2.7なのでそれを指定し、pythonのスクリプトはmain.applicationとし、テンプレートにはjinja2を使います。
application: sqltestfirst version: 1 api_version: 1 runtime: python27 threadsafe: true handlers: - url: /.* script: main.application libraries: - name: jinja2 version: latest
- main.pyをトップに作成
import os import logging from google.appengine.api import rdbms from google.appengine.ext import webapp import jinja2 template_path = os.path.join(os.path.dirname(__file__)) jinja2_env = jinja2.Environment( loader=jinja2.FileSystemLoader(template_path) ) CLOUDSQL_INSTANCE = ''#デプロイの時に必要となる。 DATABASE_NAME = 'guestbook' USER_NAME = 'hoge' PASSWORD = 'fuga' def get_connection(): return rdbms.connect(instance=CLOUDSQL_INSTANCE, database=DATABASE_NAME, user=USER_NAME, password=PASSWORD, charset='utf8') class MainHandler(webapp.RequestHandler): def get(self): conn = get_connection() cursor = conn.cursor() cursor.execute('SELECT guest_name, content, created_at FROM entries ' 'ORDER BY created_at DESC limit 20') rows = cursor.fetchall() conn.close() template_values = {"rows": rows} template = jinja2_env.get_template('index.html') self.response.out.write(template.render(template_values)) class GuestBook(webapp.RequestHandler): def post(self): conn = get_connection() cursor = conn.cursor() cursor.execute('INSERT INTO entries (guest_name, content) ' 'VALUES (%s, %s)', (self.request.get('guest_name'), self.request.get("content"))) conn.commit() conn.close() self.redirect("/") application = webapp.WSGIApplication( [ ("/", MainHandler), ("/sign", GuestBook), ], debug=True )
- 「index.html」という名前の jinja2テンプレートをトップに作成。
<!DOCTYPE html> <html> <head> <title>CloudSQL Tutorial</title> </head> <body> <h2>Guestbook</h2> <form action="sign" method="POST"> Name: <input name="guest_name"><br> <textarea name="content" rows="3" cols="60"></textarea><br> <input type="submit" value="Sign Guestbook"> </form> <hr> {% for row in rows %} <p>{{ row[0]|e }} wrote: <blockquote> {{ row[1]|e }} </blockquote> at {{ row[2]|e }} </p> <hr> {% endfor %}
- 開発ウェブサーバの起動(mysqlのオプションは自分の環境で要変更)
展開ディレクトリ/google_appengine/dev_appserver.py --mysql_socket=/var/lib/mysql/mysql.sock
- アプリの確認
ローカルにあるアプリのデプロイ
- Google Cloud SQLのインスタンスは作ったけれど、まだTableを作成していないので(ユーザなんかも)、上記のローカルで行ったSQLを行う。それには下のように、左のGoogle Cloud SQL→SQL Promptタブの中のTextAreaで行う。
- ローカルのapp.yaml内のCLOUDSQL_INSTANCEを実際のものに書き換えます。他もローカルと違う場合は変更します。
CLOUDSQL_INSTANCE = 'myApplication201303::sqltest' DATABASE_NAME = 'guestbook' USER_NAME = 'hoge' PASSWORD = 'fuga'
Googleへデプロイ
appcfg.pyでデプロイします。
- コマンドを叩く
cd .. 展開ディレクトリ/google_appengine/appcfg.py update guestbook/
- メールアドレスとパスワードを入力。メールアドレスはGoogle App Engineを登録した際のGoogleのアカウント用のメールアドレスです。パスワードをも同様。
これで終了です。
http://sqltestfirst.appspot.com/
で確認できます(はず(^_^;)。