Jagan Nalla
02/19/2023, 11:17 PMJagan Nalla
02/19/2023, 11:18 PMJagan Nalla
02/19/2023, 11:23 PMJagan Nalla
02/19/2023, 11:24 PMDian Fu
02/20/2023, 3:18 AMop column:
• +I : insert a new row
• -U : Remove the old row
• +U : Insert a new row
From the output you have posted, it means that for group ml , the count is firstly 1 and then becomes 2 .Dian Fu
02/20/2023, 3:19 AMDian Fu
02/20/2023, 3:24 AMJagan Nalla
02/20/2023, 12:55 PMJagan Nalla
02/20/2023, 12:57 PMJagan Nalla
02/20/2023, 12:58 PMJagan Nalla
02/20/2023, 1:04 PMJagan Nalla
02/20/2023, 1:04 PMJagan Nalla
02/20/2023, 1:16 PMJagan Nalla
02/20/2023, 1:16 PMJagan Nalla
02/20/2023, 1:16 PM@timestamp BIGINT,
ts as TO_TIMESTAMP(FROM_UNIXTIME(@timestamp)),
id BIGINT,
data TINYINT
) WITH (
'connector' = 'kafka',
'topic' = 'user_behavior_source',
'properties.bootstrap.servers' = 'localhost:9092',
'properties.group.id' = 'testGroup',
'scan.startup.mode' = 'earliest-offset',
'format' = 'json'
)
""")
table = table_env.from_path("random_source")
table_env.execute_sql("""
CREATE TABLE sink_table (
one_minute_window timestamp,
id BIGINT,
data_count TINYINT
) WITH (
'connector' = 'upsert-kafka',
'topic' = 'user_behavior_sink',
'properties.bootstrap.servers' = 'localhost:9092',
'properties.group.id' = 'testGroup',
'format' = 'json'
)
""")
sink_table = table_env.from_path("sink_table")
#table.execute().print()
result = table\
.window(Tumble.over(lit(1).minutes).on(col('ts')).alias("one_minute_window"))\
.group_by(col("one_minute_window"),col("id"))\
.select(col("one_minute_window"),col("id"), col("data").count.alias('data_count'))
# develop code to sink with another kafka topic
result.execute().print() # for now print the results and see.
#result1 = result.execute_insert("sink_table")Jagan Nalla
02/20/2023, 11:39 PMDian Fu
02/21/2023, 3:24 AMDian Fu
02/21/2023, 3:27 AMThe code works perfectly. But only the problem it sinks old records also op=-UYes, this is by design as -U message is also part of the changelog. Maybe you could try upsert-kafka: https://nightlies.apache.org/flink/flink-docs-release-1.16/docs/connectors/table/upsert-kafka/
Jagan Nalla
02/21/2023, 3:34 PMJagan Nalla
02/21/2023, 3:36 PMJagan Nalla
02/22/2023, 1:45 AMJagan Nalla
02/22/2023, 1:46 AMJagan Nalla
02/22/2023, 1:46 AMJagan Nalla
02/22/2023, 1:46 AMJagan Nalla
02/22/2023, 1:47 AMJagan Nalla
02/22/2023, 1:49 AMJagan Nalla
02/22/2023, 1:51 AMJagan Nalla
02/22/2023, 1:51 AMJagan Nalla
02/22/2023, 1:53 AMJagan Nalla
02/22/2023, 1:53 AMJagan Nalla
02/22/2023, 1:54 AMJagan Nalla
02/22/2023, 1:56 AMDian Fu
02/22/2023, 5:10 AMcol('one_minute_window').start or col('one_minute_window').end , instead of col('one_minute_window') .Dian Fu
02/22/2023, 5:57 AMimport json
import pandas as pd
from pyflink.common import Configuration
from pyflink.table import EnvironmentSettings, TableEnvironment, DataTypes
# create a batch TableEnvironment
from pyflink.table.expressions import col
from pyflink.table.udf import udaf
conf = Configuration()
env_settings = EnvironmentSettings.in_batch_mode()
table_env = TableEnvironment.create(env_settings)
table = table_env.from_elements(
[(1, 'apple', 200, "a"),
(2, 'samsung', 300, "s"),
(3, 'nokia', 400, "n"),
(1, 'apple', 300, "a1"),
(2, 'samsung', 400, "s1"),
(3, 'nokia', 500, "n1"),
(1, 'apple', 100, "a2")
],
['id', 'company', 'price', 'category'])
@udaf(result_type=DataTypes.STRING(), func_type="pandas")
def metadata(price: pd.Series, category: pd.Series):
result = {
'count': price.size,
'price': price.tolist(),
'category': category.tolist()
}
return str(json.dumps(result))
@udaf(result_type=DataTypes.BIGINT(), func_type="pandas")
def total(price: pd.Series):
return int(price.sum())
table = table.group_by(col('id'), col('company')) \
.select(col('company'),
total(col('price')).alias('total'),
col('id'),
metadata(col('price'), col('category')).alias('metadata'))
table.execute().print()
# with table.execute().collect() as results:
# for result in results:
# print(result)Dian Fu
02/22/2023, 5:57 AMDian Fu
02/22/2023, 5:59 AMJagan Nalla
02/22/2023, 2:13 PMJagan Nalla
02/22/2023, 2:13 PMJagan Nalla
02/22/2023, 2:18 PMJagan Nalla
02/22/2023, 2:18 PMJagan Nalla
02/22/2023, 2:18 PMJagan Nalla
02/22/2023, 2:18 PMJagan Nalla
02/22/2023, 2:22 PMJagan Nalla
02/22/2023, 2:23 PMJagan Nalla
02/22/2023, 2:24 PMJagan Nalla
02/22/2023, 2:25 PMJagan Nalla
02/22/2023, 2:26 PMJagan Nalla
02/22/2023, 2:27 PMJagan Nalla
02/22/2023, 2:27 PMJagan Nalla
02/22/2023, 2:30 PMJagan Nalla
02/22/2023, 10:11 PMJagan Nalla
02/22/2023, 10:12 PMDian Fu
02/23/2023, 2:21 AMtable.exec.source.idle-timeout or set the parallelism to 1 to work around it during testing.
[1] https://nightlies.apache.org/flink/flink-docs-release-1.16/docs/connectors/table/kafka/#source-per-partition-watermarksJagan Nalla
02/23/2023, 2:26 AMDian Fu
02/23/2023, 2:32 AMPandas UDAFs are not supported in streaming mode currently. :
There are three types of aggregation:
• GroupBy Aggregation: https://nightlies.apache.org/flink/flink-docs-release-1.16/docs/dev/table/tableapi/#groupby-aggregation
• GroupBy Window Aggregation: https://nightlies.apache.org/flink/flink-docs-release-1.16/docs/dev/table/tableapi/#groupby-window-aggregation
• Over Window Aggreagation: https://nightlies.apache.org/flink/flink-docs-release-1.16/docs/dev/table/tableapi/#over-window-aggregation
Pandas UDF could only be used in the latter two in streaming mode: GroupBy Window Aggregation and Over Window Aggreagation . The reason is that the data is unbounded in streaming mode, for the first kind of aggregation GroupBy Aggregation, we could not collect all the data belonging to one group and so not able to construct pandas.Series for the input parameters of Pandas UDAF.
For GroupBy Window Aggregation and Over Window Aggreagation , window could be used to separate the unbounded data into a series of bounded data batch and so Pandas UDAF could be used.Jagan Nalla
02/23/2023, 2:46 AMJagan Nalla
02/23/2023, 3:00 AMJagan Nalla
02/23/2023, 3:00 AMDian Fu
02/23/2023, 3:00 AMJagan Nalla
02/23/2023, 3:01 AMJagan Nalla
02/23/2023, 3:04 AMJagan Nalla
02/23/2023, 3:04 AMJagan Nalla
02/23/2023, 3:06 AMJagan Nalla
02/23/2023, 3:06 AMJagan Nalla
02/23/2023, 3:06 AMDian Fu
02/23/2023, 3:08 AMcol('flowid').count with pandas UDAF.Jagan Nalla
02/23/2023, 3:20 AMJagan Nalla
02/23/2023, 3:20 AMJagan Nalla
02/23/2023, 3:21 AMJagan Nalla
02/23/2023, 3:22 AMJagan Nalla
02/23/2023, 3:24 AMDian Fu
02/23/2023, 3:28 AMBut at the same time when there is any error it is getting more default to trace it out. Because few errors are not well described or I am not up to level to understand at this point.Yes, this is something which should be improved. However, it may need to take a very long time as it’s not very easy because it’s quite different for batch and streaming underlying.
Jagan Nalla
02/23/2023, 3:30 AMJagan Nalla
02/23/2023, 3:31 AMDian Fu
02/23/2023, 3:31 AMIt prints the above results. For the last column, the results are truncated. There is a JIRA to improve this which allows to configure the max display column width: https://issues.apache.org/jira/browse/FLINK-30025This is because currently the maximum display column width is by default 30 and there is no way to change it. For testing, I guess you could collect the data to client and print it yourself:
with table.execute().collect() as results:
for result in results:
print(result)Dian Fu
02/23/2023, 3:32 AMJagan Nalla
02/23/2023, 3:34 AMDian Fu
02/23/2023, 3:34 AMprint and will not be a problem if you send out data to other storage.Jagan Nalla
02/23/2023, 3:34 AMDian Fu
02/23/2023, 3:49 AMprint issue is only a display issue and won’t be a problem when you write data to Kafka / DB.