我有一个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)
我在这个主题上尝试了很多变化,但没有任何运气。
答案 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
。