Python向Teradata表插入Null值异常:Excel空列显示为NaN
解决Python向Teradata插入Null时显示为NaN的问题
这个问题的核心是pandas读取Excel空值后生成的numpy.nan没有被Teradata驱动正确转换为SQL NULL,而是被识别成了字符串"NaN"或者保留了pandas的NaN标识。下面给你两种解决方案,先解决当前的逐行插入问题,再推荐更高效的批量插入方法。
一、修复逐行插入的代码
你需要先把pandas数据中的NaN替换为Python原生的None,因为Teradata的参数化查询会自动将None映射为SQL的NULL。另外注意你的代码里有个小错误:dataset是读取的DataFrame,但循环里用了df.values[row],应该改成dataset.values[row]。
修改后的代码如下:
import pandas as pd import teradata import numpy as np dataset = pd.read_excel("Filepath", skiprows=[0]) # 将所有NaN替换为None,Teradata会识别为NULL dataset = dataset.replace({np.nan: None}) host, username, password = 'hostname', 'username', 'password' # 创建连接 udaExec = teradata.UdaExec(appName="test", version="1.0", logConsole=False) session = udaExec.connect(driver='Teradata', method="odbc", system=host, username=username, password=password) for row in range(dataset.shape[0]): col = list(dataset.values[row]) # 处理BIRTH_DT的格式,确保空值也能正确处理(如果有的话) birth_dt_val = '/'.join([str(i).zfill(2) for i in col[1].split('/')]) if col[1] is not None else None session.execute(""" INSERT INTO PRSNA_STG(PRSNA_ID,BIRTH_DT,DEATH_DT,GNDR_TYPE_CD,ETHCTY_TYPE_CD,NTLTY_CD,MARITAL_CD) VALUES(?, CAST(? AS DATE FORMAT 'MM/DD/YYYY'), ?, ?, ?, ?, ?) """, (col[0], birth_dt_val, col[2], col[3], col[4], col[5], col[6]))
关键改动:
- 新增
dataset = dataset.replace({np.nan: None}),把pandas的NaN替换为Python的None - 修复了变量名错误(
df改为dataset) - 给BIRTH_DT的处理加了空值判断,避免如果BIRTH_DT为空时出现报错
二、更高效的批量插入方案
逐行插入5000条记录效率比较低,推荐用teradata库的批量插入能力,或者利用pandas的to_sql结合Teradata的ODBC驱动来实现,速度会快很多。这里给你to_sql的实现示例:
import pandas as pd import numpy as np from sqlalchemy import create_engine dataset = pd.read_excel("Filepath", skiprows=[0]) dataset = dataset.replace({np.nan: None}) # 构建SQLAlchemy连接字符串 conn_str = f"teradata://{username}:{password}@{host}/?driver=Teradata&odbc_autotranslate=yes" engine = create_engine(conn_str) # 批量插入,if_exists='append'表示追加数据 dataset.to_sql( name='PRSNA_STG', con=engine, if_exists='append', index=False, chunksize=1000 # 分块插入,避免内存问题 )
这种方法不需要手动写INSERT语句,pandas会自动处理参数映射,而且批量插入的效率远高于逐行循环。
为什么之前的代码会出现NaN?
因为Excel中的空值被pandas读取后变成了numpy.nan,当你直接把这个值传给Teradata的execute方法时,驱动没有将其转换为SQL的NULL,而是把它当作一个普通的Python对象传递,最终在Teradata中显示为NaN。而Python的None是参数化查询中标准的NULL占位符,Teradata驱动能正确识别并转换为SQL NULL。
内容的提问来源于stack exchange,提问作者Swaroop
相关产品推荐
相关产品推荐

