Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

ゴール

  • 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の記事じゃなかった...

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away