LoginSignup
2
3

More than 5 years have passed since last update.

[Go] RevelのサンプルアプリBookingのDBをPostgreSQLにしてHerokuにデプロイする

Last updated at Posted at 2015-11-07

はじめに

RevelのBookingという公式サンプルアプリケーションはDBがSqlite。
これをPostgreSQLにしてHerokuにデプロイしようという話。

ひとまず動いたものは下記に置いておいた。
https://github.com/shunsugai/revel-sample-booking-postgres

変更点

まず、Bookingというサンプルアプリを用意しておく。下記のもの。
https://revel.github.io/samples/booking.html

変更点は下記。

  1. conf/app.confをPostgreSQL用に変える
  2. gorp.PostgresDialect{}に変える
  3. プレースホルダを変える
  4. Userの名前変える
  5. LIMIT句を修正

1. conf/app.confをPostgreSQL用に変える

conf/app.conf
 log.warn.prefix  = "WARN  "
 log.error.prefix = "ERROR "

-db.import = github.com/mattn/go-sqlite3
-db.driver = sqlite3
-db.spec   = :memory:
+db.import = github.com/lib/pq
+db.driver = postgres
+db.spec   = ${DATABASE_URL}

 build.tags=gorp

2. gorp.PostgresDialect{}に変える

app/controllers/gorp.go
 func InitDB() {
    db.Init()
-   Dbm = &gorp.DbMap{Db: db.Db, Dialect: gorp.SqliteDialect{}}
+   Dbm = &gorp.DbMap{Db: db.Db, Dialect: gorp.PostgresDialect{}}

    setColumnSizes := func(t *gorp.TableMap, colSizes map[string]int) {
        for col, size := range colSizes {

3. プレースホルダを変える

PostgreSQLはプレースホルダが\$1, \$2という感じなので"?"をこれに変える。
下記はその一例。

app/controllers/hotels.go
    var hotels []*models.Hotel
    if search == "" {
        hotels = loadHotels(c.Txn.Select(models.Hotel{},
-           `select * from Hotel limit ?, ?`, (page-1)*size, size))
+           `select * from Hotel limit $1, $2`, (page-1)*size, size))
    } else {
        search = strings.ToLower(search)

4. Userの名前変える

3まででイケるかと思いきや、デプロイすると下記のようなエラーが出た。

panic: No ColumnMap in table User type User with field userid

下記によるとuserというテーブル名が良くないらしい。
https://groups.google.com/forum/#!topic/revel-framework/fi7q2rT21NU

I found out the reason for my final error: since there is a User model object, gorp creates a "user" (lowercase for unexplained reasons) table in postgres. When you query that table with "select * from user", postgres thinks you are talking about a built-in user object (containing one column, current_user_name).

というわけで下記のように名前を変えてみた。

app/models/user.go
    "regexp"
 )

-type User struct {
+type HotelUser struct {
    UserId             int
    Name               string
    Username, Password string

Userを参照している箇所はすべて置換してください。

5. LIMIT句を修正

4まででイケるかと思いきや、デプロイして/hotelsにアクセスしてもホテル名の一覧が出てこない。
ログを見ると下記のエラーが出ていた。

ERROR 2015/11/07 08:07:07 panic.go:30: pq: LIMIT #,# syntax is not supported

LIMIT句の書き方が違うよと。あまりにも無知。

app/controllers/hotels.go
    var hotels []*models.Hotel
    if search == "" {
        hotels = loadHotels(c.Txn.Select(models.Hotel{},
-           `select * from Hotel limit $1, $2`, (page-1)*size, size))
+           `select * from Hotel offset $1 limit $2`, (page-1)*size, size))
    } else {
        search = strings.ToLower(search)
        hotels = loadHotels(c.Txn.Select(models.Hotel{},
            `select * from Hotel where lower(Name) like $1 or lower(City) like $2
- limit $3, $4`, "%"+search+"%", "%"+search+"%", (page-1)*size, size))
+ offset $3 limit $4`, "%"+search+"%", "%"+search+"%", (page-1)*size, size))
    }

    return c.Render(hotels, search, size, page, nextPage)

これでコードの修正は完了。

Herokuにデプロイする。

詳細は下記。
golang - [Go] HerokuにRevelでつくったアプリをデプロイする - Qiita
.godirまで用意したものとして進めます。
まずherokuのインスタンス作成。

$ heroku create -b https://github.com/revel/heroku-buildpack-go-revel.git

次にポスグレのaddon追加
https://elements.heroku.com/addons/heroku-postgresql

$ heroku addons:create heroku-postgresql:hobby-dev

最後にdeploy

$  git push heroku master

終わったらブラウザで確認。

heroku open

Screen Shot 2015-11-07 at 21.45.21.png

いぇーい。

InitDB()呼ばれるたびにレコード増えてくけど気にしない気にしない。
詳しくは下記を見てください。
https://github.com/shunsugai/revel-sample-booking-postgres

参考記事

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3