首页 > 解决方案 > psycopg2 copy_to 在插入期间将浮点值解释为字符串

问题描述

我有一个熊猫数据框,在打印信息时看起来像这样print(df.info())

Pandas DF 模式

copy_to现在,我正在尝试使用 psycopg2 的函数将其插入到 postgres 中的表中。它看起来像这样

def copy(conn, table, df):
    sio = StringIO()
    
    # Handle NaN
    # Since to_csv writes NaN as empty string, it causes trouble with copy_to since NaN is present in Numeric types
    # So converting NaN in Numeric types to -1
    df = set_empty_defaults_df(df)
        
    sio.write(df.to_csv(index=None, header=None, sep="|"))
    sio.seek(0)
    
    print("Table %s" % (table))
        
    with conn.cursor() as c:    
        c.copy_from(
            file=sio,
            table=table,
            sep="|"
        )
        conn.commit()

当我运行这个时,我得到错误`DataError: invalid input syntax for integer: "0.0" CONTEXT: COPY time, line 1, column hour: "0.0"

错误图像`

很奇怪 psycopg2 将双 0.0 解释为字符串而不是十进制值,因为 pandas 具有正确的数据类型。

我在这里想念什么?

标签: pythonpandaspostgresqlpsycopg2

解决方案


我相信“作为字符串”位是一个红鲱鱼 - 那些引号可能只是为了分隔值。你真正的问题是你试图在一个整数列中存储一个带小数的值。

例如,在psql提示符下尝试以下操作。您将收到相同的错误消息:

db=> create temporary table t (x integer) ;
CREATE TABLE
db=> \copy t(x) from stdin
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself, or an EOF signal.
>> 1.0
>> \.
ERROR:  invalid input syntax for type integer: "1.0"
CONTEXT:  COPY t, line 1, column x: "1.0"

所以你需要让 pandas 打印那些不带小数的列,也许通过将它们转换为整数,或者使用一些花哨的格式化选项to_csv(我不记得有什么)。


推荐阅读