datax 操作pg,支持insert和update

1.如果需要pg支持update,则需pg版本在9.5以上

可用select version()查看。

可熟悉语法:ON CONFLICT ,PostgreSQL的ON CONFLICT

关键词:如果不存在则插入,存在则更新

t_hdj_test3的联合主键是id,name;

INSERT INTO "warning_event"."t_hdj_test3" (id,name,sex) VALUES('1'::int4,'aaa'::varchar,'女'::varchar) ON CONFLICT  ( id ,name )  DO  UPDATE SET sex=excluded.sex

修改 PostgresqlWriter.java

删除限制:

 

修改WriterUtil.java

添加postgresql 数据插入类型转换:​​​​​​​

 

public static String getWriteTemplate(List<String> columnHolders, List<String> valueHolders, String writeMode, DataBaseType dataBaseType, boolean forceUseUpdate) {
        boolean isWriteModeLegal = writeMode.trim().toLowerCase().startsWith("insert")
                || writeMode.trim().toLowerCase().startsWith("replace")
                || writeMode.trim().toLowerCase().startsWith("update");

        if (!isWriteModeLegal) {
            throw DataXException.asDataXException(DBUtilErrorCode.ILLEGAL_VALUE,
                    String.format("您所配置的 writeMode:%s 错误. 因为DataX 目前仅支持replace,update 或 insert 方式. 请检查您的配置并作出修改.", writeMode));
        }
        // && writeMode.trim().toLowerCase().startsWith("replace")
        String writeDataSqlTemplate;
        if (forceUseUpdate ||
                ((dataBaseType == DataBaseType.MySql || dataBaseType == DataBaseType.Tddl) && writeMode.trim().toLowerCase().startsWith("update"))
                ) {
            //update只在mysql下使用

            writeDataSqlTemplate = new StringBuilder()
                    .append("INSERT INTO %s (").append(StringUtils.join(columnHolders, ","))
                    .append(") VALUES(").append(StringUtils.join(valueHolders, ","))
                    .append(")")
                    .append(onDuplicateKeyUpdateString(columnHolders))
                    .toString();
        } else {
            if (dataBaseType == DataBaseType.PostgreSQL) {

                        StringBuilder sb = new StringBuilder().append("INSERT INTO %s (")
                        .append(StringUtils.join(columnHolders, ","))
                        .append(") VALUES(").append(StringUtils.join(valueHolders, ","))
                        .append(")");
                        if(writeMode.trim().toLowerCase().startsWith("update")){
                            sb.append(onConFlictDoString(writeMode, columnHolders));
                        }
                writeDataSqlTemplate = sb.toString();
            } else {
                //这里是保护,如果其他错误的使用了update,需要更换为replace
                if (writeMode.trim().toLowerCase().startsWith("update")) {
                    writeMode = "replace";
                }
                writeDataSqlTemplate = new StringBuilder().append(writeMode)
                        .append(" INTO %s (").append(StringUtils.join(columnHolders, ","))
                        .append(") VALUES(").append(StringUtils.join(valueHolders, ","))
                        .append(")").toString();
            }

        }

        return writeDataSqlTemplate;
    }

增加onConFlictDoString方法:

public static String onConFlictDoString(String conflict, List<String> columnHolders) {
        conflict = conflict.replace("update", "");
        StringBuilder sb = new StringBuilder();
        sb.append(" ON CONFLICT ");
        sb.append(conflict);
        sb.append(" DO ");
        if (columnHolders == null || columnHolders.size() < 1) {
            sb.append("NOTHING");
            return sb.toString();
        }
        String[] conflictFields = conflict.replace("(","").replace(")","").replace(" ","").split(",");
        Set<String> conflictFieldsSet = Sets.newHashSet(conflictFields);
        sb.append(" UPDATE SET ");
        boolean first = true;
        for (String column : columnHolders) {
            if(conflictFieldsSet.contains(column)){
                continue;
            }
            if (!first) {
                sb.append(",");
            } else {
                first = false;
            }
            sb.append(column);
            sb.append("=excluded.");
            sb.append(column);
        }
        return sb.toString();
    }

效果Json

{

  "job": {

    "setting": {

        "speed": {

            "channel": 1

        }

    },

    "content": [

      {

        "reader": {

          "name":"postgresqlreader",
	  "parameter":{
		"username":"111",
		"password":"222",
		"splitPk":"",
		"connection":[
			{
				"querySql":["select id ,name,sex from warning_event.t_hdj_test2"],
				"jdbcUrl":[
					"jdbc:postgresql://333"
				]
			}
		]

	  }

        },

        "writer": {

          "name": "postgresqlwriter",

          "parameter": {
		"writeMode": "update (id,name)",
		"username":"111",
		"password":"222",
		"column":["id","name","sex"],
		"preSql":[
		    
		],
		"connection":[
		{ 
		    "table":["\"warning_event\".\"t_hdj_test3\""],
		    "jdbcUrl":"jdbc:postgresql://333"
		}
		]

          }

        }

      }

    ]

  }

 

}

Datax运行日志:

此错误是pg库版本在9.5以下,

生成sql如下:INSERT INTO "warning_event"."t_hdj_test3" (id,name,sex) VALUES('1'::int4,'aaa'::varchar,'女'::varchar) ON CONFLICT  ( id ,name )  DO  UPDATE SET sex=excluded.sex

 没有"writeMode": "update (id,name)", 则正常插入

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DataX是一个开源的数据同步工具,它在默认情况下不支持Hive的Decimal数据类型。然而,根据引用\[2\]中的信息,我们可以通过修改DataX的源码来增强它的功能,以支持Hive的Decimal数据类型。 具体来说,我们可以在DataX的代码中使用Hive的API来将数据转换为期望的精度和标度DECIMAL(precision, scale)。这可以通过使用org.apache.hadoop.hive.serde2.typeinfo.HiveDecimalUtils#enforcePrecisionScale()和org.apache.hadoop.hive.common.type.HiveDecimal#enforcePrecisionScale这两个API来实现。这样,我们就可以在DataX中使用Decimal数据类型了。 需要注意的是,DataX有自己的数据类型,如long/Double/String/Date/Boolean/Bytes等。引用\[3\]中提到,DataX的Double类型在内部使用java.math.BigDecimal来存储数据,因此不会损失数据精度。为了支持Hive的Decimal数据类型,我们可以在DataX的代码中进行相应的转换。 总结起来,要使DataX支持Decimal数据类型,我们需要在DataX的源码中进行二次开发和增强,使用Hive的API来进行数据转换。这样,我们就可以在DataX中使用Hive的Decimal数据类型了。 #### 引用[.reference_title] - *1* *3* [如何更改 datax支持hive 的 DECIMAL 数据类型?](https://blog.csdn.net/MichaelLi916/article/details/127631212)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Datax-HdfsWriter如何实现支持decimal类型数据写入](https://blog.csdn.net/SOFT2030/article/details/124344172)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值