You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:00:45