package clickhouse_api import ( "context" "encoding/json" "fmt" "time" "github.com/ClickHouse/clickhouse-go/v2" ) type ProductPricing struct { Price int64 `json:",omitempty"` Currency string `json:",omitempty"` } type Product struct { ID clickhouse.Dynamic `json:"id"` Name string `json:"name"` Tags []string `json:"tags"` Pricing ProductPricing `json:"pricing"` Metadata map[string]any `json:"metadata"` CreatedAt time.Time `json:"created_at" chType:"DateTime64(3)"` } func NewExampleProduct() *Product { return &Product{ ID: clickhouse.NewDynamicWithType(uint64(1234), "UInt64"), Name: "Book", Tags: []string{"library", "fiction"}, Pricing: ProductPricing{ Price: 750, Currency: "usd", }, Metadata: map[string]any{ "region": "us", "page_count": int64(852), }, CreatedAt: time.Now().UTC().Truncate(time.Millisecond), } } func JSONStructExample() error { ctx := context.Background() conn, err := GetNativeConnection(clickhouse.Settings{ "allow_experimental_json_type": true, "output_format_native_use_flattened_dynamic_and_json_serialization": true, }, nil, nil) if err != nil { return err } if !CheckMinServerVersion(conn, 25, 6, 0) { fmt.Print("unsupported clickhouse version for JSON type") return nil } err = conn.Exec(ctx, "DROP TABLE IF EXISTS go_json_example") if err != nil { return err } err = conn.Exec(ctx, ` CREATE TABLE go_json_example (product JSON) ENGINE=Memory `) if err != nil { return err } batch, err := conn.PrepareBatch(ctx, "INSERT INTO go_json_example (product)") if err != nil { return err } insertProduct := NewExampleProduct() if err = batch.Append(insertProduct); err != nil { return err } if err = batch.Send(); err != nil { return err } var selectedProduct Product if err = conn.QueryRow(ctx, "SELECT product FROM go_json_example").Scan(&selectedProduct); err != nil { return err } insertProductBytes, err := json.Marshal(insertProduct) if err != nil { return err } selectedProductBytes, err := json.Marshal(&selectedProduct) if err != nil { return err } fmt.Printf("inserted product: %s\n", string(insertProductBytes)) fmt.Printf("selected product: %s\n", string(selectedProductBytes)) fmt.Printf("inserted product matches selected product: %t\n", string(insertProductBytes) == string(selectedProductBytes)) return nil }