How do I deal with JSONB types while code generation? #215
-
Hi guys, thanks for the great library. I am however unable to figure out how to deal with JSONB types while generating the types with Jet. I am trying to port an existing application which uses a postgres DB. I have dozens of tables, and most of the tables have a column called private_metadata which is a JSONB type. When I try to generate the models for this schema, that column is decoded as If anyone could provide me with a runnable example, I'd greatly appreciate it. Thank you! |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
For instance, I am trying this: package main
import (
"fmt"
"strings"
"github.com/go-jet/jet/v2/generator/metadata"
"github.com/go-jet/jet/v2/generator/postgres"
"github.com/go-jet/jet/v2/generator/template"
postgres2 "github.com/go-jet/jet/v2/postgres"
_ "github.com/lib/pq"
)
func main() {
err := postgres.Generate("./jet_gen", postgres.DBConnection{
Host: "localhost",
Port: 5432,
User: "username",
Password: "password",
DBName: "db",
SslMode: "disable",
},
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseSQLBuilder(template.DefaultSQLBuilder().
UseTable(func(table metadata.Table) template.TableSQLBuilder {
return template.DefaultTableSQLBuilder(table).
UseColumn(func(column metadata.Column) template.TableSQLBuilderColumn {
fmt.Println(column.Name)
defaultColumn := template.DefaultTableSQLBuilderColumn(column)
if strings.Contains(defaultColumn.Name, "metadata") {
defaultColumn.Type = "map[string]interface{}"
}
return defaultColumn
})
}),
)
}),
)
if err != nil {
panic(err)
}
}
Even though the DB has many tables. Infact, using the
But I can't customize types using this. What am I doing wrong? |
Beta Was this translation helpful? Give feedback.
-
Hi @vamshiaruru-virgodesigns , I could spot a couple of mistakes:
// for any JSON types
type JsonType map[string]interface{}
func (m *JsonType) Scan(value interface{}) error {
return json.Unmarshal(value.([]byte), m)
}
func (m JsonType) Value() (driver.Value, error) {
return json.Marshal(m)
} Or even better you can define a specific type-safe struct for each json column: type ColumnJson1 struct {
A int
B string
}
func (m *ColumnJson1) Scan(value interface{}) error {
return json.Unmarshal(value.([]byte), m)
}
func (m ColumnJson1) Value() (driver.Value, error) {
return json.Marshal(m)
} |
Beta Was this translation helpful? Give feedback.
Hi @vamshiaruru-virgodesigns ,
I could spot a couple of mistakes:
SchemaName
inDBConnection
. That's probably why no tables are found.map[string]interface{}
does not implementScanner
andValuer
interface, so scan would not work for this type. You need to define a new type: