DB 괴롭히는 Go 코드를 스키마에서 자동 생성해주는 xo라는 도구를 사용해 보았다.

8968 단어 5PostgreSQL

소개



Go에서 DB를 만지기를 위한 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

폴더 구성은 이런 느낌.


사용해보기



생성된 코드를 사용해 본다.

우선, 패키지명은 생성처의 폴더명이 된다.
// 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 클라이언트에서 확인했다.
데이터 들어간 것 같다.
좋았어요.



생성 파일의 내용



구조체가 만들어졌습니다. 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 라는 것도.

좋은 웹페이지 즐겨찾기