2014年2月14日金曜日

herokuでpythonとかtornadoとかpostgresとか

今更ながらにherokuを使ってみたので色々とメモ。いつもの通りで適当。
herokuはrailsのイメージ強いけど、pythonの気分なので。frameworkは何となくtornadoに。
postgrelsqlのテーブルに入ったデータを参照して表示するだけのアプリを練習がてらに。


Herokuを弄る

Herokuの準備

まずアカウントを作る。と言っても難しいことはない。メールアドレスとパスワード入れるくらい。
次にheroku toolbeltをインストール。下記コマンド実行しただけ。
$ wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh

Tornadoアプリをheroku上に

Tornado-Heroku-Quickstartを使う。スーパーシンプルなアプリをheroku上に上げて起動するためのもの。
$ curl -L 'https://github.com/mikedory/Tornado-Heroku-Quickstart/tarball/master' | tar zx && cd mikedory-Tornado-Heroku-Quickstart-*
$ ./init.sh
これだけで、アプリをアップしてくれて、ブラウザ起動。Hi!というページが開いて成功。簡単。
鍵の登録をしてなかったけれど、このコマンドで鍵の生成から登録までしてくれた模様。

ローカルでアプリ機動

tornado入ってないので入れて、toolbeltのforemanで起動。
$ sudo pip install -r requirements.txt 
$ foreman start
これでローカル環境でもHi!
あとは、開発してデプロイのサイクルか。

Postgresを弄る

インストール

はじめてのPostgresql。herokuだから一応。まずはインストール。
# apt-get install postgresql

DBとユーザー作成

次はとりあえずユーザーとデータベースを作ってみる。
初めのコマンドがあってるか自信ないが、やったことをそのまま。
$ sudo -u postgres psql
psql (9.1.11)
Type "help" for help.

postgres=# create user test with password 'test' createdb
postgres-# ;
CREATE ROLE
postgres=# \du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication | {}
 test      | Create DB                                      | {}

postgres=> create database test;
CREATE DATABASE
postgres=> \l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | postgres | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | 
 template0 | postgres | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 test      | test     | UTF8     | ja_JP.UTF-8 | ja_JP.UTF-8 | 
(4 rows)
ユーザーはできた。ユーザーでログインしてみる。
$ psql -U test -W
Password for user test: 
psql: FATAL:  Peer authentication failed for user "test"
なんだか入れない。下記設定を変え、再起動。したら入れる。
# sudo vi /etc/postgresql/9.1/main/pg_hba.conf
#local   all             all                                     peer
local   all             all                                     password

テーブル作成

とりあえずテーブル作って適当にデータ入れる。
test=> create table test (name varchar(30));
CREATE TABLE
test=> insert into test (name) values ('ほげ'), ('fuga');
INSERT 0 2
test=> select * from test;
 name 
------
 ほげ
 fuga
(2 rows)

Python+Postgre

Heroku Postgresに従ってみます。

psycopg2インストール

# apt-get install python-dev libpq-dev
# pip install psycopg2
requirements.txtにも追記しておく。

接続

あとはmain.pyを修正して、dbの中身参照して表示させる。
まずはinitに下記追加。上記のHerokuのドキュメントとほぼ一緒。
ローカル用の設定をデフォルトになるようにしてるくらい。
urlparse.uses_netloc.append("postgres")
url = urlparse.urlparse(os.environ.get("DATABASE_URL",
                        'postgresql://test:test@localhost/test'))
self.conn = psycopg2.connect(
    database=url.path[1:],
    user=url.username,
    password=url.password,
    host=url.hostname,
    port=url.port
    )

参照

DB参照用のハンドラ。結果をそのままテンプレに。"select *"とかやってるのは気にしない。
# the test page
class TestHandler(tornado.web.RequestHandler):
    def get(self):
        cur = self.application.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
        cur.execute("select * from test")
        rows = cur.fetchall()
        self.render(
            "test.html",
            rows=rows
        )

表示

テンプレも適当に受け取ったrowsを表示するだけ。
結果
    {% for row in rows %}
  • {{ escape(row['name']) }}
  • {% end %}
うむ、DBの中身が無事に表示された。

Herokuにデプロイ

Add-On追加

まずは、add-on追加して、herokuでpostgres使えるようにする。
$ heroku addons:add heroku-postgresql:dev
$ heroku pg:promote HEROKU_POSTGRESQL_COLOR_URL

ローカルデータをプッシュ

先ほどローカルに作ったデータをherokuにpushする。
$ PGUSER=test PGPASSWORD=test heroku pg:push test HEROKU_POSTGRESQL_GREEN_URL --app myapp

herokuにアプリをデプロイ

$ git commit -a -m "postgres test"
$ git push heroku master

Heroku上でも同様にDBの情報を表示できました。
終わり。