Flink | 1.14 |
Doris | 1.2.4 |
flinksql通过jdbc中MySQL协议读取doris表数据计算后写入到另一个doris表
单表写入可行(不用声明主键),多表join写入时报错(flink强制声明主键并将语法转换成upsert)
FlinkDDL读取表做为源表:
CREATE TABLE ODS_CBS_SO_MASTER_TS (
SO_PERIOD INT
,SO_DATE INT
,SO_NO VARCHAR
,ID BIGINT
,SO_TYPE VARCHAR
,SO_STORE_NO VARCHAR
,SO_DOC_NO VARCHAR
,SO_DOC_STATUS VARCHAR
,SO_PROM_FLAG VARCHAR
,SO_WHOLE_PROM_CODE VARCHAR
,SO_ENTRY_CLASS VARCHAR
,SO_ENTRY_TIME TIMESTAMP(6)
,SO_ENTRY_BY VARCHAR
,APP_ERROR_STATUS VARCHAR
,ORDER_DEALER_NO VARCHAR
,ORDER_DEALER_NAME VARCHAR
,ORDER_TYPE VARCHAR
,REF_SO_NO VARCHAR
,REF_SO_PERIOD INT
,REF_SO_DATE INT
,TOTAL_SALE_AMT DECIMAL(22, 6)
,TOTAL_SALE_PRODUCT_AMT DECIMAL(22, 6)
,TOTAL_SALE_NON_PRODUCT_AMT DECIMAL(22, 6)
,TOTAL_SALE_MKP_COUPON_01 DECIMAL(22, 6)
,TOTAL_SALE_MKP_COUPON_02 DECIMAL(22, 6)
,TOTAL_SALE_SALARY_COUPON DECIMAL(22, 6)
,TOTAL_SALE_NET_AMT DECIMAL(22, 6)
,IS_CALC_FIRST_SO INT
,CALC_PERIOD VARCHAR
,CALC_POINT DECIMAL(22, 6)
,CALC_DISCOUNT_POINT DECIMAL(22, 6)
,CALC_REBATE DECIMAL(22, 6)
,COMMENTS VARCHAR
,LAST_UPDATED_TIME TIMESTAMP(6)
,LAST_UPDATED_BY VARCHAR
,PRE_ORDER_DEALER_NO VARCHAR
,TOTAL_SALE_DISCOUNT_AMT DECIMAL(22, 6)
,COMPANY_NO VARCHAR
,PO_PROCESS_CODE VARCHAR
,CUSTOMER_NO VARCHAR
,CALC_REBATE_DS DECIMAL(22, 6)
,TOTAL_REBATE_DIS_AMT DECIMAL(22, 6)
,IS_COMBINE INT
,TOTAL_PRICE_FRACTION DECIMAL(22, 6)
,SO_UNION_NO VARCHAR
,TOTAL_TRANSPORT_AMT DECIMAL(22, 6)
,TOTAL_TRANSPORT_COUPON_AMT DECIMAL(22, 6)
,PAYMENT_DISCOUNT_AMT DECIMAL(22, 6)
,CALC_DISCOUNT_POINT_MKP DECIMAL(22, 6)
,ETL_TIME TIMESTAMP(6)
-- ,PRIMARY KEY (`SO_PERIOD`, `SO_DATE`, `SO_NO`, `ID`) NOT ENFORCED
)
WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://doris.com.cn:19030/ODS_RT?',
'table-name' = 'ODS_CBS_SO_MASTER_TS',
'username' = 'name',
'password' = '加密内容1',
'scan.partition.column' = 'SO_DATE', -- 分区扫描列名
'scan.partition.num' = '1', -- 分区数量
'scan.partition.lower-bound' = '20240521', -- 首个分区的最小值
'scan.partition.upper-bound' = '20240521', -- 最后一个分区的最大值
'scan.fetch-size' = '1' -- 每次从数据库读取时,批量获取的行数
);
写入的SINK表:
CREATE TABLE DWD_TRD_SO_MASTER_TS (
`SO_PERIOD` INT COMMENT '统计月份',
`SO_NO` STRING COMMENT '销售单号',
`SO_TYPE` STRING COMMENT '销售类型',
`SO_DATE` DATE COMMENT '销售日期',
`SO_STORE_NO` STRING COMMENT '销售店铺',
`ORDER_DEALER_NO` STRING COMMENT '购货人卡号',
`ORDER_TYPE` STRING COMMENT '购货类型',
`REF_SO_NO` STRING COMMENT '参考订货单号',
`REF_SO_DATE` DATE COMMENT '参考源订货单日期',
`CUSTOMER_NO` STRING COMMENT '顾客号',
`IS_APP_ORDER` INT COMMENT '是否办卡单',
`IS_RETURN_ORDER` INT COMMENT '是否退货',
`IS_ONLINE_PURCHASE` INT COMMENT '是否在线购货',
`SO_ENTRY_TIME` timestamp(6) COMMENT '单据输入时间',
`SO_ENTRY_CLASS` STRING COMMENT '单据输入类型',
`SO_ENTRY_BY` STRING COMMENT '单据输入人',
`DELIVERY_STORE_NO` STRING COMMENT '配送店铺',
`IS_ONLINE_PURCHASE_BY_ORIGINAL` INT COMMENT '是否在线购货(根据原单)',
`PRE_ORDER_DEALER_NO` STRING COMMENT '预购货人卡号',
`PO_PROCESS_CODE` STRING COMMENT '订货流程代码',
`DELIVERY_TYPE` STRING COMMENT '配送类型',
`CALC_POINT` DECIMAL(22,6) COMMENT '计分合计总点数',
`CALC_DISCOUNT_POINT` DECIMAL(22,6) COMMENT '计分合计折扣点数',
`TOTAL_SALE_AMT` DECIMAL(22,6) COMMENT '整单总金额',
`TOTAL_SALE_NON_PRODUCT_AMT` DECIMAL(22,6) COMMENT '整单非产品金额',
`TOTAL_SALE_PRODUCT_AMT` DECIMAL(22,6) COMMENT '整单产品金额',
`TOTAL_SALE_DISCOUNT_AMT` DECIMAL(22,6) COMMENT '整单折让金额',
`TOTAL_SALE_MKP_COUPON_01` DECIMAL(22,6) COMMENT '整单抵扣现金券01',
`TOTAL_SALE_MKP_COUPON_02` DECIMAL(22,6) COMMENT '整单抵扣现金券02',
`TOTAL_SALE_SALARY_COUPON` DECIMAL(22,6) COMMENT '整单抵扣电子礼券',
`TOTAL_SALE_NET_AMT` DECIMAL(22,6) COMMENT '整单订货净金额',
`LAST_UPDATED_TIME` TIMESTAMP(6) COMMENT '最后更新时间',
`ETL_TIME` timestamp(6) COMMENT '数据更新时间'
,PRIMARY KEY (SO_NO) NOT ENFORCED
) WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://doris.com.cn:19030/BIGDATA_PRE?',
'table-name' = 'DWD_TRD_SO_MASTER_TS_TEST05',
-- 'database-name'='ADS_RT',
'username' = 'name',
'password' = '加密内容4',
'scan.partition.column' = 'SO_PERIOD', -- 分区扫描列名
'scan.partition.num' = '1', -- 分区数量
'scan.partition.lower-bound' = '202405', -- 首个分区的最小值
'scan.partition.upper-bound' = '202405', -- 最后一个分区的最大值
'scan.fetch-size' = '1' -- 每次从数据库读取时,批量获取的行数
);
插入语句:
--内容过多不详细展示
insert into DWD_TRD_SO_MASTER_TS
SELECT *
from A
LEFT JOIN B
ON ……
本地调试时有结果:
写入时报错:
开始我以为是数据重复导致,排查了数据发现并无重复,并且试了下插入语句时limit 1 还是报相同错误,本地调试有结果说明sql语法没错,那么问题大概出在插入语句上。
Flink官网显示DDL中定义主键时会将语法转换成MySQL的upsert方式:
两种原因:
1. 大概是因为这种upsert语法只支持MySQL,Doris并不支持INSERT .. ON DUPLICATE KEY UPDATE中携带select的方式
2. Doris本身的唯一键冲突,在插入时doris底层自己会转换成自己的upsert语法,与flink转换后的语法突
我试了将SINK表中的PRIMARY KEY () NOT ENFORCED主键去掉但是报错了:
原因是两张表join后写入另一张表时,SINK表必须开启PRIMARY KEY () NOT ENFORCED主键的声明,所以现在陷入了死胡同,本人小白一枚不会写flink代码,请各位大佬给出出主意,万分感谢!!!【抱拳】