工作笔记 - 记一次PG数据导入和清理

概述

此文是作为笔者在实际工作中遇到和解决的一个数据库的问题的记录。

大概的情况是这样的,笔者需要对一批原始业务数据进行处理,基于一些导入的数据,进行关联和信息的更新。数据库使用Postgres,导入的数据的原始形式是Excel,数据库管理工具使用dbeaver。导入的过程,笔者基于方便,直接使用dbeaver的"高级粘贴",在一个临时表中,直接复制了Excel中的表格数据,进行了粘贴录入。

数据导入的过程看起来还是比较顺利的,但进行关联更新的时候,出现了问题,就是无法将原始数据信息和导入进行进行联合查询,明明是相同的信息,就是无法查询出有效记录,当然也无法根据数据关联进行更新操作。

本文的主要内容,就是记录和分析这个问题发生的原因和处理过程,事后总结时发现,这个问题应该还是有代表性的,所以就记录下来分享。

问题和处理

  • 问题表现

遇到这个问题后,笔者最初的想法,就是构造一个和更新操作相同条件的查询,来检查一下,是否能够正常查询。

这里出现了一个有趣的现象。记录集查询的时候,是有结果的,表明查询语法和执行没有问题。但查询的结果集和预期不符,要少好多条。这个操作的查询条件之一,是中国居民身份证号码的匹配,经过对结果数据的分析发现查询的结果集中,只包括了身份证末尾为"X"的记录。

这个情况就非常奇怪了,从理论上而言,这些记录好像和别的记录应该也没有什么区别。但再想到数据录入的过程,笔者怀疑在录入(复制粘贴)的过程中,对于居民身份证号码的处理是有差异的?再检查数据,验证了笔者的想法(图):

发现问题了吗? 好像这两种记录类型的显示好像有点不一样,第一条记录前面有"东西(空格)"啊?所以有理由怀疑,当从Excel文档中复制粘贴数据的时候,粘贴程序可能会将全数字的身份证号码,当作了"数字"进行处理,并且加入了某些不可见字符;而对于尾字符为"X"的记录,就是正常的字符串了。

了解到这个情况,解决方法就很简单,再做一遍数据处理,记录的前后空格去掉就行了。

  • 去除空格和制表符

在postgres中,提供了trim函数,可以用于处理字段值前后的空格:

update t set "IDNO" = trim("IDNO") where ....;

但是,操作完成后,仍然不能正确的查询和更新,说明一个问题,那个看起来是空格的"空格",其实不是空格。但如何手动编辑并更新,就是正确的。说明确实是一个不可见字符。

那有可能是制表符吗,那就要使用替换函数了:

update t set "IDNO" = replace("IDNO", '\t','') where ....;

结果仍然不对!这时候,笔者就觉得事情不是那么简单了。

  • 识别不可见字符

所以笔者想要看看这到底是一个什么东西。笔者找了一个"在线隐藏字符检测及去除工具",所幸的是,这个信息是可以复制粘贴的,粘贴检测后,得到了这么一个结果:

这里看得很清楚,就是在字符串前面,有一个UTF8类型的水平制表符。 前面笔者可能犯了一个错误,就是替换的时候直接使用"\t",但实际上,在这里要表示制表符,应该使用转义,在Postgres中是 E'\t', 所以其实并没有正确的处理。

  • 去除制表符和扩展

如果只是处理这个水平制表符的问题,那也很简单,就是使用增强的替换方式:

update t set "IDNO" = replace("IDNO", E'\t','') where ....;

但让我们稍微扩展一下,如果想要查询并且去除所有的前后缀不可见字符,甚至字符串中间的不可见字符,就需要使用更高级的正则替换方式了:

js 复制代码
// 查询异常记录
SELECT idno,  regexp_replace(idno, E'([\\x00-\\x1F\\x7F])', '<\\1>', 'g' ) AS visualized
FROM t
WHERE idno  ~ E'[\\x00-\\x1F\\x7F\\u200B-\\u200F\\uFEFF]';

// 更新数据
update t set idno = regexp_replace( idno, E'([\\x00-\\x1F\\x7F])','','g') ... 

简单的解释一下:

  • regexp_replace可以使用正则检索
  • 四个参数分别是搜索字段,替换搜索,替换结果,选项标识
  • \\x00-\\x1F\\x7F\],捕获匹配ASCII 码从0到31的控制字符(不可打印字符)和127(DEL)

  • g 标签,替换所有匹配

至此,这个问题算是比较完善的解决了,也有很强的通用性。

小结

本文从笔者在工作中遇到的一个数据处理问题出发,讨论了在使用Excel进行数据导入可能遇到的数据格式转换中可能遇到的问题,包括问题的表现,可能的原因和对应的解决和技术处理方案和操作。

相关推荐
有来技术14 小时前
Spring Boot 4 + Vue3 企业级多租户 SaaS:从共享 Schema 架构到商业化套餐设计
java·vue.js·spring boot·后端
东东51615 小时前
学院个人信息管理系统 (springboot+vue)
vue.js·spring boot·后端·个人开发·毕设
三水不滴15 小时前
Redis缓存更新策略
数据库·经验分享·redis·笔记·后端·缓存
小邓吖16 小时前
自己做了一个工具网站
前端·分布式·后端·中间件·架构·golang
大爱编程♡17 小时前
SpringBoot统一功能处理
java·spring boot·后端
好好研究19 小时前
总结SSM设置欢迎页的方式
xml·java·后端·mvc
小马爱打代码20 小时前
Spring Boot:第三方 API 调用的企业级容错设计
java·spring boot·后端
晚风_END20 小时前
postgresql数据库|pgbouncer连接池压测和直连postgresql数据库压测对比
数据库·postgresql·oracle·性能优化·宽度优先
csdn2015_21 小时前
springboot task
java·spring boot·后端
czlczl2002092521 小时前
Spring Boot :如何高性能地在 Filter 中获取响应体(Response Body)
java·spring boot·后端