KSQL UDF:DataException:结构模式不匹配

时间:2019-11-10 12:00:49

标签: apache-kafka ksql

我正在尝试创建一个如select(CSAS)的流,该流已成功创建,但是当我尝试推送消息时,出现以下异常。

Expected output shape: (8, 24, 16)
Actual shape: (1, 24, 16)

下面是来自ksql-cli的主要流,持久性流和udf函数的详细信息,不确定为什么该模式不兼容,因为您可以在Caused by: org.apache.kafka.connect.errors.DataException: Struct schemas do not match. at org.apache.kafka.connect.data.ConnectSchema.validateValue(ConnectSchema.java:247) at org.apache.kafka.connect.data.Struct.put(Struct.java:216) at io.confluent.ksql.serde.GenericRowSerDe$GenericRowSerializer.serialize(GenericRowSerDe.java:116) at io.confluent.ksql.serde.GenericRowSerDe$GenericRowSerializer.serialize(GenericRowSerDe.java:93) at org.apache.kafka.common.serialization.Serializer.serialize(Serializer.java:62) at org.apache.kafka.streams.processor.internals.RecordCollectorImpl.send(RecordCollectorImpl.java:162) at org.apache.kafka.streams.processor.internals.RecordCollectorImpl.send(RecordCollectorImpl.java:102) at org.apache.kafka.streams.processor.internals.SinkNode.process(SinkNode.java:89) 流下面看到一个名为{{ 1}}具有与UDF函数返回的值完全相同的架构,我在这里丢失了什么吗?

processed

也在我使用的UDF代码之下

article

2 个答案:

答案 0 :(得分:1)

我试图以同样的方式解决问题,但是我在以下情况下苦苦挣扎:

UDF:

@UdfDescription(name = "ValueUnpacker", description = "..")
public class ValueUnpacker {
    private Schema valueSchema = SchemaBuilder.struct()
            .field("LABEL", Schema.INT32_SCHEMA)
            .build();


    @Udf(description = "Test a string", schema = "struct<LABEL INT>")
    public Struct unpackValue(@UdfParameter(value = "thingType", description = "a thing type") String thingType) {
        Struct ret = new Struct(valueSchema);
        int i = 5;
        ret.put("LABEL", i);
        System.out.println("Ret: " + ret);
        return ret;
    }
}

运行ksqldb并输入:

ksql> SELECT valueunpacker('test') FROM SOME_STREAM EMIT CHANGES;
|{LABEL=5}
|{LABEL=5}  

,效果很好。但是创建流为

CREATE STREAM CONSTANT_STREAM AS SELECT valueunpacker('test') FROM SOME_STREAM;

在没有流输出的情况下发生故障。 ksqldb的日志会导致相同的问题:“ 模式不匹配”。

答案 1 :(得分:0)

我能够找出问题并解决,基本上这是KSQL引擎将架构字段转换为大写的事实,因此,当我发送小写的字段时,它无法匹配它,这不是在文档中清除。

解决方法是我必须拥有:

  1. 以编程方式定义的SCHEMA中的所有字段均以大写形式表示,以及@UDF批注中的schema字段。
  2. 以编程方式定义的架构中的所有字段应与@UDF批注中的架构字段中的所有字段(名称和类型)完全匹配。

代码终于看起来像:

@Udf(description = "test",
                    schema = "struct< _ID VARCHAR, RAW_TITLE VARCHAR, RAW_TEXT VARCHAR, PROCESSED_TITLE VARCHAR, PROCESSED_TEXT VARCHAR>")
    public Struct processDocument(
            @UdfParameter(
                    schema = "struct< _id VARCHAR, title VARCHAR, text VARCHAR, action VARCHAR, url VARCHAR, feed_id VARCHAR, mode VARCHAR, score INTEGER, published_at VARCHAR, retrieved_at VARCHAR>",
                    value = "article",
                    description = "A complete article object") Struct struct) {

        Schema ARTICLE_SCHEMA = SchemaBuilder.struct()
                .field("_ID", Schema.STRING_SCHEMA)
                .field("RAW_TITLE", Schema.STRING_SCHEMA)
                .field("RAW_TEXT", Schema.STRING_SCHEMA)
                .field("PROCESSED_TITLE", Schema.STRING_SCHEMA)
                .field("PROCESSED_TEXT", Schema.STRING_SCHEMA)
                .build();


Struct proStruct = new Struct(ARTICLE_SCHEMA);
        proStruct.put("_ID", "1234");
        proStruct.put("RAW_TITLE", "RAW_TITLE___1234");
        proStruct.put("RAW_TEXT", "RAW_TEXT___1234");
        proStruct.put("PROCESSED_TITLE", "TITLE____1234");
        proStruct.put("PROCESSED_TEXT", "TEXT____1234");
        System.out.println(proStruct);
        return proStruct;

    }