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

时间:2015-08-20 00:03:16

标签: python postgresql psycopg2

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

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

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

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

register_adapter(np.NaN, adapt_nans)

我在这个主题上尝试了很多变化,但没有任何运气。

3 个答案:

答案 0 :(得分:10)

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

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

 psycopg2.extensions.register_adapter(float, nan_to_null)

答案 1 :(得分:3)

此答案是Gregory Arenius's Answer的替代版本。我已经通过简单地检查条件值是否等于其自身来替换条件语句,以处理任何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中详细解释了此方法起作用的原因。

答案 2 :(得分:0)

我相信最简单的方法是:

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

然后,None被“翻译”:导入到Postgres中时变成NULL