繁体   English   中英

将用户定义的对象转换为数据帧并写入RDBMS-如何维护与数据库的映射?

[英]Convert a user defined object into dataframe and write into RDBMS - how to maintain mapping with database?

我在mysql中具有以下表结构:

创建表用户(
id INT NOT NULL,
名称VARCHAR(20)NOT NULL,
年龄INT NOT NULL,
地址VARCHAR(100)NOT NULL);

现在,我想编写一个火花流作业,该作业从Kafka读取数据,进行一些处理和过滤,并写入表“ User”中的RDBMS。

为此,我首先创建了表的POJO表示-

@Data
class User implements Serializable {
private int id;
private String name;
private int age;
private String address;
}

下面,我写了将rdd转换为数据帧的spark作业-

JavaDStream<User> userStream = ... // created this stream with some processing
userStream.foreachRDD(rdd -> {
DataFrame df = sqlContext.createDataFrame(rdd,User.class);
df.write().mode(SaveMode.Append).jdbc(MYSQL_CONNECTION_URL, "user", new java.util.Properties());
});

现在,一旦我执行了这段代码,因为数据帧是以偶然危险的方式形成的,并且不会与数据库架构同步。 因此,它将尝试在“ id”列中插入“地址”,并以sql异常退出。

我不明白如何使数据框架了解数据库的架构并相应地从User对象加载数据。 有什么办法吗? 我认为JavaRDD可以映射到JavaRDD ,但是我不知道该怎么做。

此外,我相信此createDataFrame() API使用反射(必须)进行处理,因此,还存在性能影响的问题。 您能告诉我是否有办法维护POJO和关系数据库之间的映射并插入数据吗?

这样做对我有用。

@Data
class User implements Serializable {
private int id;
private String name;
private int age;
private String address;
private static StructType structType = DataTypes.createStructType(new StructField[] {
        DataTypes.createStructField("id", DataTypes.IntegerType, false),
        DataTypes.createStructField("name", DataTypes.StringType, false),
        DataTypes.createStructField("age", DataTypes.IntegerType, false),
        DataTypes.createStructField("address", DataTypes.StringType, false)
});

public static StructType getStructType() {
    return structType;
}

public Object[] getAllValues() {
    return new Object[]{id, name, age, address};
}

}

火花工作-

JavaDStream<User> userStream = ... // created this stream with some processing
userStream.map(e -> {
            Row row = RowFactory.create(e.getAllValues());
            return row;
        }).foreachRDD(rdd -> {
            DataFrame df = sqlContext.createDataFrame(rdd,User.getStructType());
            df.write().mode(SaveMode.Append).jdbc(MYSQL_CONNECTION_URL, "user", new java.util.Properties());
        });

我认为这是比上一个更好的方法,因为在上一个中,数据帧使用反射将POJO映射到其自己的数据结构中。 这是一个更清洁的方式,因为我已经排火花SQL本身的格式,我已经提数据的插入顺序为数据帧中getAllValues()getStructType列映射()

如果我错了,请纠正我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM