如何将 numpy NaN 对象转换为 SQL 空值?

How do I convert numpy NaN objects to SQL nulls?

我有一个要插入到 SQL 数据库中的 Pandas 数据框。我正在使用 Psycopg2 直接与数据库对话,而不是 SQLAlchemy,所以我不能使用 Pandas 内置的 to_sql 函数。几乎一切都按预期工作,除了 numpy np.NaN 值被转换为 NaN 文本并插入到数据库中。它们确实应该被视为 SQL 空值。

所以,我正在尝试制作自定义适配器以将 np.NaN 转换为 SQL null,但我尝试的所有操作都会导致在数据库中插入相同的 NaN 字符串。

我目前正在尝试的代码是:

def adapt_nans(null):
    a = adapt(None).getquoted()
    return AsIs(a)

register_adapter(np.NaN, adapt_nans)

我尝试了很多关于这个主题的变体,但都没有成功。

我之前尝试的代码失败了,因为它假设 np.Nan 是它自己的类型,而实际上它是一个浮点数。以下代码 courtesy of Daniele Varrazzo on the psycopg2 mailing list 正确完成了工作。

def nan_to_null(f,
        _NULL=psycopg2.extensions.AsIs('NULL'),
        _Float=psycopg2.extensions.Float):
    if not np.isnan(f):
        return _Float(f)
    return _NULL

 psycopg2.extensions.register_adapter(float, nan_to_null)

此答案是 的替代版本。我通过简单地检查值是否等于自身来替换条件语句以处理任何 Nan 值。

def nan_to_null(f,
         _NULL=psycopg2.extensions.AsIs('NULL')
         _Float=psycopg2.extensions.Float)):
    if f != f:
        return _NULL
    else:
         return _Float(f)

 psycopg2.extensions.register_adapter(float, nan_to_null)

如果你检查一个 nan 值是否等于它本身,你会得到 False。 Stephen Canon's answer.

中详细解释了为什么这样做的原因

我认为最简单的方法是:

df.where(pd.notnull(df), None)

然后 None 被“翻译”:导入到 Postgres 时 NULL

如果您尝试将 Pandas 数据帧数据插入 PostgreSQL 并收到 NaN 的错误,您所要做的就是:

import psycopg2

output_df = output_df.fillna(psycopg2.extensions.AsIs('NULL'))

#Now insert output_df data in the table