【问题标题】:Python psycopg2 insert NULL in some rows in postgresql tablePython psycopg2 在 postgresql 表的某些行中插入 NULL
【发布时间】:2023-03-21 08:42:02
【问题描述】:

我在某些行中有一个带有 NULL 值的 Python 数据框,在插入到 postgresql 时,datetype 列中的一些 null 变成了 'NaT' 字符串或 'NaN',我喜欢它是一个真正的 NULL ,这没什么细胞。

插入前的示例数据帧

import psycopg2
import pandas as pd
import numpy as np

conn=psycopg2.connect(dbname= 'myDB', host='amazonaws.com', 
port= '2222', user= 'mysuser', password= 'mypass')
cur = conn.cursor()

df= pd.DataFrame({ 'zipcode':[1,np.nan,22,88],'city':['A','h','B',np.nan]})


subset = df[['zipcode', 'city']]
data = [tuple(x) for x in subset.values]
records_list_template = ','.join(['%s'] * len(data)) 
insert_query = 'insert into public.MyTable (zipcode, city) values {}'.format(records_list_template)
cur.execute(insert_query, data)
conn.commit()

生成 postgresql 表

预期结果如下

【问题讨论】:

    标签: python python-3.x postgresql amazon-redshift psycopg2


    【解决方案1】:

    您可以通过这种方式将NaN 转换为None

    df= pd.DataFrame({
        'zipcode':[1,np.nan,22,88],
        'city':['A','h','B',np.nan],
        'date':['2019-01-01','2019-01-02',pd.NaT,pd.NaT]})
    
    df['date'] = [d.strftime('%Y-%m-%d') if not pd.isnull(d) else None for d in df['date']]
    
    subset = df.where((pd.notnull(df)), None)
    

    DataFrame.where

    【讨论】:

    • 我的错,我的实际表包含一个包含一些 NaT 的 datetype 列,df.where((pd.notnull(df)), None) 无法转换 NaT
    • 确实,它不适用于NaT(我认为它应该)。我在特定列中添加了从 NaT 到 None 的转换,请参阅更新后的答案。
    • 顺便问一下,如果我有 100 万行要插入,你知道如何加快这个过程吗?批量插入?
    • 文件中有数据吗?
    • 它在 pandas 数据框中,我可以将其保存为 csv。
    【解决方案2】:

    通过替换为 None 来转换数据框中的所有 NaN 实例,如下所示:

    df = df.replace({pd.np.nan: None})
    

    【讨论】:

    • 如果你这样做,那么在 postgres 数据库中将会有'None'。 OP希望在数据库中有[null]
    猜你喜欢
    • 2011-05-06
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 2012-05-07
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多