package main import ( "encoding/json" "errors" "database/sql/driver" "fmt" "github.com/jmoiron/sqlx" _ "github.com/lib/pq" "log" ) var schema = ` CREATE TABLE person ( first_name text, last_name text, contact JSON );` type PersonContact map[string]interface{}; func (pc *PersonContact) Scan(val interface{}) error { switch v := val.(type){ case []byte: json.Unmarshal(v, &pc) return nil case string: json.Unmarshal([]byte(v), &pc) return nil default: return errors.New(fmt.Sprintf("Unsupported type: %T", v)) } } func (pc *PersonContact) Value() (driver.Value, error) { return json.Marshal(pc) } type Person struct { FirstName string `db:"first_name"` LastName string `db:"last_name"` Contact PersonContact `db:"contact"` } func main() { db, err := sqlx.Connect("postgres", "user=test dbname=test password=test") if err != nil { log.Fatalln(err) } defer db.Close() // exec the schema or fail db.MustExec("DROP TABLE IF EXISTS person;") db.MustExec(schema) var person Person contact := map[string]string{"email": "jmoiron@jmoiron.net"} contact_json, _ := json.Marshal(contact) db.MustExec("INSERT INTO person (first_name, last_name, contact) VALUES ($1, $2, $3)", "Jason", "Moiron", contact_json) row := db.QueryRowx("SELECT first_name, last_name, contact FROM person LIMIT 1") err = row.StructScan(&person) if err != nil { panic(err) } fmt.Printf("=> %v\n", person) }