'Cannot unmarshal array of lists where elements don't have the same type [duplicate]

I'm scraping Binance API for candle price data. The Binance API provides the said data as json array. Each element of the array is a list representing candle and does not contain elements of the same type, however each list contains the same set of types: strings and ints, to be precise. Look at the raw data of this for instance: https://api.binance.com/api/v3/klines?symbol=ZECUSDT&interval=1h&limit=10&startTime=1653001200000

How do I automatically unmarshal such json into struct? Is using reflect the only option here?

package main

import (
    "encoding/json"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
)

type PriceData struct {
    Data map[int]Price
}

type Price struct {
    TradeStart uint64 `json:"0"` // tried without json tags
    PriceOpen  string `json:"1"` 
    PriceHigh  string `json:"2"`
    PriceLow   string `json:"3"`
    PriceClose string `json:"4"`    
    TradeEnd   uint64 `json:"6"`
    // QuoteVolume         string // tried with these fields as well
    // NumberOfTrades      uint64
    // TakerBuyBaseVolume  string
    // TakerBuyQuoteVolume string
}

func main() {
    url := "https://api.binance.com/api/v3/klines?symbol=ZECUSDT&interval=1h&limit=10&startTime=1653001200000" // tried /api/v1 as well

    resp, err := http.Get(url)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    content, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    // var priceData map[int]Price // -- tried
    // var priceData []Price // -- tried
    // var priceData PriceData // -- tried
    // var priceData []interface{} -- works fine, but will need to use reflection
    var priceData []Price
    if err = json.Unmarshal(content, &priceData); err != nil {
        log.Fatal(err)
    }

    interupt := make(chan os.Signal, 1)
    signal.Notify(interupt, syscall.SIGTERM, syscall.SIGINT)
    <-interupt
}



Solution 1:[1]

There's a convenient ER diagram of the Northwind datbase here.

So you have two supplier names 'Exotic Liquids' and 'Tokyo Traders'. Suppliers are in the SUPPLIERS table and their names are in the .companyname column.

To get one supplier is easy:

SELECT * 
FROM   SUPPLIERS 
WHERE  companyname = 'Exotic Liquids';

To get both you can either use an OR clause or an IN(..) function:

SELECT * 
FROM   SUPPLIERS 
WHERE  companyname IN('Exotic Liquids','Tokyo Traders');

Now product names are in the .productname column of the PRODUCTS table. The PRODUCTS table is related to the SUPPLIERS table through the PRODUCTS.supplierid column which points to the SUPPLIERS.supplierid column.

If you already knew the supplier id's for the products that you were interested in you could get their product names like this:

SELECT productname 
FROM   PRODUCTS 
WHERE  supplierid IN(1001,1002);

where 1001 and 1002 are the supplier ids of Exotic Liquids and Tokyo Traders.
However, because we do not know them ahead of time (we just know their company names) we need to combine these two queries like so:

SELECT p.productname, p.supplierid
FROM   PRODUCTS p
WHERE  p.supplierid IN( SELECT s.supplierid
                        FROM   SUPPLIERS s  
                        WHERE  s.companyname IN('Exotic Liquids','Tokyo Traders')
                       );

Which should do what you want.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1