fraenky8 / tables-to-go

convert your database tables to structs easily
MIT License
233 stars 42 forks source link
developer-tools go golang golang-application golang-cli golang-sql golang-sql-mapper-util golang-structs

Tables-to-Go

convert your database tables to structs easily

A small and convenient tool supporting development against a changing database schema.

Tables change, run the tool, get your structs!

Go Report Card GoDoc Build & Test Code Coverage

Requirements

Install

This project provides a make file but can also simply be installed with the go-install command.

Get the latest stable release version:

go install github.com/fraenky8/tables-to-go/v2@latest

Get the latest changes from master:

go install github.com/fraenky8/tables-to-go/v2@master

To enable SQLite3 support, clone the repo manually and run the make file:

make sqlite3

See this PR why it's disabled by default.

Getting Started

tables-to-go -v -of ../path/to/my/models

This gets all tables of a local running PostgreSQL database. Therefore, it uses the database postgres, schema public and user postgres with no password. Flag -v is verbose mode, -of is the output file path where the go files containing the structs will get created (default: current working directory).

Features

Examples

Assuming you have the following table definition (PostgreSQL):

CREATE TABLE some_user_info  (
  id SERIAL NOT NULL PRIMARY KEY,
  first_name VARCHAR(20),
  last_name  VARCHAR(20) NOT NULL,
  height DECIMAL
);

Run the following command (default local PostgreSQL instance):

tables-to-go

The following file SomeUserInfo.go with default package dto (data transfer object) will be created:

package dto

import (
    "database/sql"
)

type SomeUserInfo struct {
    ID        int             `db:"id"`
    FirstName sql.NullString  `db:"first_name"`
    LastName  string          `db:"last_name"`
    Height    sql.NullFloat64 `db:"height"`
}

The column id got automatically converted to upper-case to follow the idiomatic go guidelines. See here for more details. Words which gets converted can be found here.
This behaviour can be disabled by providing the command-line flag -no-initialism.

Running on remote database server (eg. Mysql@Docker)

tables-to-go -v -t mysql -h 192.168.99.100 -d testdb -u root -p mysecretpassword

PostgreSQL example with different default schema but default database postgres:

tables-to-go -v -t pg -h 192.168.99.100 -s test -u postgres -p mysecretpassword

Note: since database type pg is default, following command will be equivalent:

tables-to-go -v -h 192.168.99.100 -s test -u postgres -p mysecretpassword

You can also specify the package or prefix and suffix.

tables-to-go -v -t mysql -h 192.168.99.100 -d testdb -u root -p mysecretpassword -pn models -pre model_ -suf _model

With same table given above, following file with Name ModelSomeUserInfoModel.go will be created:

package models

import (
    "database/sql"
)

type ModelSomeUserInfoModel struct {
    ID        int             `db:"id"`
    FirstName sql.NullString  `db:"first_name"`
    LastName  string          `db:"last_name"`
    Height    sql.NullFloat64 `db:"height"`
}

Filter for specific tables via (multiple) -table flags:

tables-to-go -v -of ../path/to/my/models -table foobar -table foo,bar,baz

Where Are The JSON-Tags?

This is a common question asked by contributors and bug reporters.

Fetching data from a database and representation of this data in the end (JSON, HTML template, cli, ...) are two different concerns and should be decoupled. Therefore, this tool will not generate json tags for the structs.

There are tools like gomodifytags which enables you to generate json tags for existing structs. The call for this tool applied to the example above looks like the following:

gomodifytags -file SomeUserInfo.go -w -all -add-tags json

This adds the json tags directly to the file:

type SomeUserInfo struct {
    ID        int             `db:"id" json:"id"`
    FirstName sql.NullString  `db:"first_name" json:"first_name"`
    LastName  string          `db:"last_name" json:"last_name"`
    Height    sql.NullFloat64 `db:"height" json:"height"`
}

Command-line Flags

Print usage with -? or -help

Usage of tables-to-go:
  -?    shows help and usage
  -d string
        database name (default "postgres")
  -f    force; skip tables that encounter errors
  -fn-format value
        format of the filename: camelCase (c, default) or snake_case (s) (default c)
  -format value
        format of struct fields (columns): camelCase (c) or original (o) (default c)
  -h string
        host of database (default "127.0.0.1")
  -help
        shows help and usage
  -no-initialism
        disable the conversion to upper-case words in column names
  -null value
        representation of NULL columns: sql.Null* (sql) or primitive pointers (native|primitive) (default sql)
  -of string
        output file path, default is current working directory (default "/Users/zalora_user/Coding/Go/src/github.com/fraenky8/tables-to-go")
  -p string
        password of user
  -pn string
        package name (default "dto")
  -port string
        port of database host, if not specified, it will be the default ports for the supported databases
  -pre string
        prefix for file- and struct names
  -s string
        schema name (default "public")
  -socket string
        The socket file to use for connection. If specified, takes precedence over host:port.
  -sslmode string
        Connect to database using secure connection. (default "disable")
        The value will be passed as is to the underlying driver.
        Refer to this site for supported values: https://www.postgresql.org/docs/current/libpq-ssl.html
  -structable-recorder
        generate a structable.Recorder field
  -suf string
        suffix for file- and struct names
  -t value
        type of database to use, currently supported: [pg mysql sqlite3] (default pg)
  -table value
        Filter for the specified table(s). Can be used multiple times or with comma separated values without spaces. Example: -table foobar -table foo,bar,baz
  -tags-no-db
        do not create db-tags
  -tags-structable
        generate struct with tags for use in Masterminds/structable (https://github.com/Masterminds/structable)
  -tags-structable-only
        generate struct with tags ONLY for use in Masterminds/structable (https://github.com/Masterminds/structable)
  -u string
        user to connect to the database
  -v    verbose output
  -version
        show version and build information
  -vv
        more verbose output

Contributing

If you find any issues or missing a feature, feel free to contribute or make suggestions! You can fork the repository and use a feature branch too. Feel free to send me a pull request. The PRs have to come with appropriate unit tests, documentation of the added functionality and updated README with optional examples.

To start developing clone via git or use go's get command to fetch this project.

This project uses go modules so make sure when adding new dependencies to update the go.mod file and the vendor directory:

go mod tidy
go mod vendor

Licensing

The code in this project is licensed under MIT license.