LoginSignup
10
9

More than 5 years have passed since last update.

Go言語でRedshiftとつなぐ(というかただのPostgreSQL)

Posted at

ゴール

  • Go言語からRedshiftにつないでクエリとかする

Redshiftとは

Redshiftへの接続およびクエリはPostgresだと思ってだいたい問題ないっぽいです。(一度、ISNULL使っててRedshiftにはISNULL無いのでCOALESCE使う、みたいなつまずきがありましたが...)

Go言語からPostgresにつなぐ

どこにでもあるGoでsql使うサンプルです

package main

import (
    "database/sql"
    "log"

    _ "github.com/lib/pq"
)

// User 適当に
type User struct {
    Name string `sql:"username"`
}

func main() {
    db, err := sql.Open("postgres", "postgres://user:pass@host:port/dbname")
    if err != nil {
        log.Fatalln("つなぐの", err)
    }
    defer db.Close()

    row, err := db.Query("SELECT username FROM users WHERE username LIKE $1 LIMIT $2", "otiai%", 10)
    if err != nil {
        log.Fatalln("クエリするの", err)
    }

    for row.Next() { // 行があるまでtrue
        user := new(User)
        err := row.Scan(&user.Name)
        if err != nil {
            log.Fatalln("結果をスキャンするの", err)
        }

        log.Printf("%+v\n", user)
    }
    if err := row.Err(); err != nil {
        log.Fatalln("イテレーション中の", err)
    }
}

上記の、postgres://user:pass@host:port/dbnameに該当するところを、お使いの(RDSなり)Redshiftのインスタンスであるところのfoo.bar.region.redshift.amazonaws.com:5439とかにすれば、普通に動くはずです。

めんどいのでORMつかおう

もはやRedshift関係無いんですが、Goのdatabase/sql十分可愛いけど、row.Nextとかrow.Scanとかめんどいので、そのへんもいい感じにマッピングしてくれるやつ使う。

今回はgormで

 package main

 import (
-   "database/sql"
    "log"

+   "github.com/jinzhu/gorm"
    _ "github.com/lib/pq"
 )

 // User 適当に
 type User struct {
-   Name string `sql:"username"`
+   Name string `gorm:"column:username"`
 }

 func main() {
-   db, err := sql.Open("postgres", "postgres://user:pass@host:port/dbname")
+   db, err := gorm.Open("postgres", "postgres://user:pass@host:port/dbname")
    if err != nil {
        log.Fatalln("つなぐの", err)
    }
    defer db.Close()

-   row, err := db.Query("SELECT username FROM users WHERE username LIKE $1", "otiai%")
+   users := []User{}
+   err = db.Where("username LIKE ?", "otiai%").Limit(10).Find(&users).Error
    if err != nil {
-       log.Fatalln("クエリするの", err)
-   }
-
-   for row.Next() { // 行があるまでtrue
-       user := new(User)
-       err := row.Scan(&user.Name)
-       if err != nil {
-           log.Fatalln("結果をスキャンするの", err)
-       }
-
-       log.Printf("%+v\n", user)
-   }
-   if err := row.Err(); err != nil {
-       log.Fatalln("イテレーション中の", err)
+       log.Fatalln("クエリしてスキャンするの", err)
    }
+   log.Printf("%+v\n", users)
 }

すげー楽。gormが、Findとかで渡すstructのtype名見て、この場合勝手にusersというテーブル名を入れます。発行されるSQLを生で見たい場合は

db.LogMode(true)

と、どっかにはさめばstdoutに出ます。

というか

ぜんぜんRedshiftの記事じゃなかった...

10
9
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
10
9