LoginSignup
5
4

More than 3 years have passed since last update.

DBいじるためのGoコードをスキーマから自動生成してくれるxoってツールを使ってみた

Last updated at Posted at 2020-12-07

はじめに

GoからDBをさわるためのxoってツールがある。いまいち、使い方がよくわかってなかったので、試してみた。

xo

DBをさわるときに便利なコードを、スキーマから生成してくれるらしい。

xo/xo: Command line tool to generate idiomatic Go code for SQL databases supporting PostgreSQL, MySQL, SQLite, Oracle, and Microsoft SQL Server

xo is a command-line tool to generate Go code based on a database schema or a custom query.

環境

このとき作った環境を使う

Dockerを使ってPostgreSQL+Goの開発環境を作ってみた - Qiita

インストール

READMEにしたがって実行した。

xo/xo: Command line tool to generate idiomatic Go code for SQL databases supporting PostgreSQL, MySQL, SQLite, Oracle, and Microsoft SQL Server

go get -u golang.org/x/tools/cmd/goimports
go get -u github.com/xo/xo

ファイル生成

QuickstartにPostgreSQLのやりかた書かれてた。

modelsフォルダを作る前にやったら、フォルダがないとおこられた。

/go/src/work/xo# xo pgsql://root@db/db1 -o models
error: output path must be a directory and already exist when not writing to a single file

次は、sslが有効になってないとおこられた。PostgreSQL立ち上げるときの設定かな。disableにしといたらいいか。

/go/src/work# xo pgsql://root@db/root -o models
error: pq: SSL is not enabled on the server

これで、modelsフォルダにファイルを生成できた。

xo pgsql://root@db/root?sslmode=disable -o models

フォルダ構成は、こんな感じ。
image.png

使ってみる

生成されたコードを使ってみる。

まず、パッケージ名は生成先のフォルダ名になる。

// Package models contains the types for schema 'public'.
package models

ここを参考にさせてもらった。
DBから直接golangのモデルを生成するxoのご紹介 — そこはかとなく書くよん。

パスは$GOPATHからのパスで指定したらいけた。ここらへん、よくわかってない。


package main

import (
    "database/sql"
    "work/models"

    _ "github.com/lib/pq"
)

func main() {
    db, err := sql.Open("postgres", "host=db port=5432 user=root sslmode=disable")
    defer db.Close()
    if err != nil {
        panic(err)
    }

    e := &models.Employee{
        EmpNumber: sql.NullInt64{
            Int64: 4432,
            Valid: true,
        },
    }

    if err = e.Insert(db); err != nil {
        panic(err)
    }
}

実行してみる。

go run main.go

行けたっぽい。

Posticoで確認

PosticoっていうGUIクライアントで確認した。
データ入ったみたい。
よかったよかった。

image.png

生成ファイルの中身

構造体が作られてる。jsonのタグもある。

// Employee represents a row from 'public.employee'.
type Employee struct {
    EmpID     int           `json:"emp_id"`     // emp_id
    EmpNumber sql.NullInt64 `json:"emp_number"` // emp_number

    // xo fields
    _exists, _deleted bool
}

Insert()の中身はSQLでクエリが書かれてるだけ。

// Insert inserts the Employee to the database.
func (e *Employee) Insert(db XODB) error {
    var err error

    // if already exist, bail
    if e._exists {
        return errors.New("insert failed: already exists")
    }

    // sql insert query, primary key provided by sequence
    const sqlstr = `INSERT INTO public.employee (` +
        `emp_number` +
        `) VALUES (` +
        `$1` +
        `) RETURNING emp_id`

    // run query
    XOLog(sqlstr, e.EmpNumber)
    err = db.QueryRow(sqlstr, e.EmpNumber).Scan(&e.EmpID)
    if err != nil {
        return err
    }

    // set existence
    e._exists = true

    return nil
}

おわりに

雰囲気わかった。思ったよりシンプルやった。
go modとかerrorとかgomockがよくわかってないので、そっちももうちょい試してみたい。sqlxってのも。

5
4
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
5
4