【问题标题】:goavro and original Go data structuregoavro 和原始 Go 数据结构
【发布时间】:2021-09-08 10:49:26
【问题描述】:

如何在 Golang 中使用 goavro 重新创建使用 avro 序列化的原始数据结构?

有了这个库https://github.com/hamba/avro,这很容易。

out := SimpleRecord{}
err = avro.Unmarshal(schema, data, &out)

变量输出的类型是 SimpleRecord。

假设我有这个结构和 avro 架构:

type SimpleRecord struct {
    F1           int      `avro:"f1"`
    F2           string   `avro:"f2"`
    F3           string   `avro:"f3"`
    Dependencies []string `avro:"dependencies"`
}

func main() {
    avro_schema_txt := `{
        "type": "record",
        "name": "AvroData",
        "namespace": "data.avro",
        "doc": "docstring",
        "fields": [
            {
                "name": "f1",
                "type": "int"
            },
            {
                "name": "f2",
                "type": "string"
            },
            {
                "name": "f3",
                "type": "string"
            },
            {
                "name": "dependencies",
                "type": {
                    "type": "array",
                    "items": "string"
                }
            }
        ]
    }`
}

然后

codec, err := goavro.NewCodec(avro_schema_txt)
    if err != nil {
        log.Fatal(err.Error())
    }
    out, _, err := codec.NativeFromBinary(data)
    if err != nil {
        log.Fatal(err.Error())
    }
    fmt.Println(out)

其中数据用 avro 编组,out 是 interface{} 类型,那么我怎样才能“制作”它 SimpleRecord?

【问题讨论】:

    标签: go avro


    【解决方案1】:

    有两种方法可以做到这一点,一种是强制转换out 并进行“手动映射”,另一种是使用codec.TextualFromNative。为了完整起见,两种方法都在下面显示,

    方法 1

    outinterface{} 转换为 map[string]interface{} 并检索值

    ...
    simpleMap := out.(map[string]interface{})
    f1 := simpleMap["f1"]
    f2 := simpleMap["f2"] 
    ...
    
    SimpleRecord {
        F1: f1,
        F2: f2,
        ...
    } 
    

    方法 2

    使用TextualFromNative,下面的代码显示了编码解码过程

    var avro_schema_txt = `{
        "type": "record",
        "name": "AvroData",
        "namespace": "data.avro",
        "doc": "docstring",
        "fields": [
            {
                "name": "f1",
                "type": "int"
            },
            {
                "name": "f2",
                "type": "string"
            },
            {
                "name": "f3",
                "type": "string"
            },
            {
                "name": "dependencies",
                "type": {
                    "type": "array",
                    "items": "string"
                }
            }
        ]
    }`
    
    // added json to match field names in avro
    type SimpleRecord struct {
        F1           int      `avro:"f1" json:"f1"`
        F2           string   `avro:"f2" json:"f2"`
        F3           string   `avro:"f3" json:"f3"`
        Dependencies []string `avro:"dependencies" json:"dependencies"`
    }
    
    func encodeDecode() {
    
        data := SimpleRecord{
            F1: 1,
            F2: "tester2",
            F3: "tester3",
            Dependencies: []string { "tester4", "tester5" },
        }
    
        codec, err := goavro.NewCodec(avro_schema_txt)
        if err != nil {
            log.Fatal(err.Error())
        }
    
        // encode
    
        textualIn, err := json2.Marshal(data)
        if err != nil {
            log.Fatal(err.Error())
        }
    
        nativeIn, _, err := codec.NativeFromTextual(textualIn)
        if err != nil {
            log.Fatal(err.Error())
        }
    
        binaryIn, err := codec.BinaryFromNative(nil, nativeIn)
        if err != nil {
            log.Fatal(err.Error())
        }
    
        // decode
    
        nativeOut, _, err := codec.NativeFromBinary(binaryIn)
        if err != nil {
            log.Fatal(err.Error())
        }
    
        textualOut, err := codec.TextualFromNative(nil, nativeOut)
        if err != nil {
            log.Fatal(err.Error())
        }
    
        var out = SimpleRecord{}
        err = json2.Unmarshal(textualOut, &out)
        if err != nil {
            log.Fatal(err.Error())
        }
    
        if !reflect.DeepEqual(data, out) {
            log.Fatal("should be equal")
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-11
      • 1970-01-01
      • 2013-03-22
      • 2017-09-10
      • 2019-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多