Flink sql 基本api操作二
一、将表(Table)转换成流(DataStream)
1. 调用 toDataStream()方法
将一个Table 对象转换成DataStream 非常简单,只要直接调用表环境的方法 toDataStream() 就可以。
public class TableToDataStream { public static void main(String[] args) throws Exception { StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); DataStreamSource<Event> source = env.fromElements(new Event("Alice", "./home", 1000L), new Event("Bob", "./cart", 1000L), new Event("Alice", "./prod?id=1", 5 * 1000L), new Event("Cary", "./home", 60 * 1000L), new Event("Bob", "./prod?id=3", 90 * 1000L), new Event("Alice", "./prod?id=7", 105 * 1000L)); /** * 获取表环境 */ StreamTableEnvironment streamTableEnv = StreamTableEnvironment.create(env); /** * 通过流,stream往上转换到table表结构层 */ Table table = streamTableEnv.fromDataStream(source); Table result = streamTableEnv.sqlQuery("select user,timeMillis from " + table); streamTableEnv.toDataStream(result).print("sql->"); env.execute("tableToDataStream"); } }
2. 调用 toChangelogStream()方法
将 Table类型转换成流打印输出是很简单的;然而,如果我们同样希望将"用户点击次数统计"表 urlCountTable 进行打印输出,就会抛出一个TableException 异常:
Exception in thread “main” org.apache.flink.table.api.TableException: Table sink
‘default_catalog.default_database.Unregistered_DataStream_Sink_1’ doesn’t support consuming update changes …
这表示当前的TableSink 并不支持表的更新(update)操作。这是什么意思呢?
因为 print 本身也可以看作一个 Sink 操作,所以这个异常就是说打印输出的 Sink 操作不支持对数据进行更新。具体来说,urlCountTable 这个表中进行了分组聚合统计,所以表中的每一行是会"更新"的。也就是说,Alice 的第一个点击事件到来,表中会有一行(Alice, 1); 第二个点击事件到来,这一行就要更新为(Alice, 2)。但之前的(Alice, 1)已经打印输出了,“覆水难收”,我们怎么能对它进行更改呢?所以就会抛出异常。
解决的思路是,对于这样有更新操作的表,我们不要试图直接把它转换成DataStream 打印输出,而是记录一下它的"更新日志"(change log)。这样一来,对于表的所有更新操作,就变成了一条更新日志的流,我们就可以转换成流打印输出了。
代码中需要调用的是表环境的 toChangelogStream()方法:
public class TableToDataStreamForLog { public static void main(String[] args) throws Exception { StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); DataStreamSource<Event> source = env.fromElements( new Event("Alice", "./home", 1000L), new Event("Alice", "./home", 1000L), new Event("Bob", "./cart", 1000L), new Event("Alice", "./prod?id=1", 5 * 1000L), new Event("Cary", "./home", 60 * 1000L), new Event("Bob", "./prod?id=3", 90 * 1000L), new Event("Alice", "./prod?id=7", 105 * 1000L) ); StreamTableEnvironment tableEnvironment = StreamTableEnvironment.create(env); /** * 通过流,stream往上转换到table表结构层 */ Table table = tableEnvironment.fromDataStream(source); /** * 创建视图 */ tableEnvironment.createTemporaryView("eventTable", table); Table result = tableEnvironment.sqlQuery("select user,count(url) from eventTable group by user"); tableEnvironment.toChangelogStream(result).print("sql->"); env.execute("dataToStream"); } }
浙公网安备 33010602011771号