3

How to bind data struct with database creation in Golang along with its tags/flags.

For example I have this code:

type User struct {
    ID      int     `sql:"primary_key;AUTO_INCREMENT"`
    Name    string  `sql:"type:varchar(100);unique"`
    Email   string  `sql:"type:varchar(100);unique"`
    Address string  `sql:"type:varchar(100)"`
}

When creating the database which should be based on this struct, I instead manually create it like this:

func (db *DB) CreateUserTable() (sql.Result, error) {

    statement := "CREATE TABLE IF NOT EXISTS %s (%s int, %s varchar, %s varchar, %s varchar)"
    return db.Exec(
        fmt.Sprintf(statement,
            "user",
            "id",
            "name",
            "email",
            "address",
        ),
    )
}

How to bind the struct and its tags(primary key, NULL, etc) in database creation?. Is there best practice for it without using ORM libraries(gorm,etc)?

4
  • 1
    What you seem to be trying to do is mapping a type to the a db relation, if that's what you want you can use an already existing ORM or implement one yourself. From the viewpoint of people who do not like to use an ORM, you should create the db without using Go, use .sql files and shell scripts to initialize your database. The question which one is better, ORM or no-ORM, is in the same category as Vim vs Emacs in that it's opinion based and therefore not something to be asked on SO. Commented Mar 12, 2018 at 13:26
  • ... and in case you decide you want to implement something ORM-ish yourself, use the reflect package to read a struct's field tags and build your query using those. Commented Mar 12, 2018 at 13:32
  • And before you know it, you will have handcrafted your own ORM! Save yourself a lot of trouble, and don't reinvent the wheel if you don't really need to. Commented Mar 12, 2018 at 14:18
  • there is this which seems to do struct tag migrations without the orm bit (not tested though) - github.com/naoina/migu, also no reason you cant use gorm or similar just for migrations Commented Mar 12, 2018 at 17:46

1 Answer 1

5

You can use reflect to examine the struct and use it to construct your database query.

For example:

If you want to read struct's name to use it as table name:

tableName := reflect.TypeOf(your-struct).Name()

If you want to read struct's properties, loop and read it by using:

val := reflect.ValueOf(your-struct)
for i:=0; i < val.NumField(); i++ {
    field := val.Type().Field(i)
    tag := field.Tag

    fieldType := field.Type // get struct's variable type
    fieldName := field.Name //get struct variable's name
    fieldByTag1 := tag.Get("your-tag") // get struct tag's name 
    fieldByTag2 := tag.Get("your-another-tag") // get another struct tag's name(if you have more)
}

Note that struct's tags are the one inside back tick -> `

That's all you need to get from a struct. You should explore more in the documentation.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.