【问题标题】:Error while using copy_from in psycopg2 while inserting to a postgresql database插入到 postgresql 数据库时在 psycopg2 中使用 copy_from 时出错
【发布时间】:2021-01-10 16:58:42
【问题描述】:

每当我想将 pandas 数据框中的数据插入到 postgresql 数据库中时,我都会收到此错误 error: extra data after last expected column CONTEXT: COPY recommendations, line 1: "0,4070,"[5963, 8257, 9974, 7546, 11251, 5203, 102888, 8098, 101198, 10950]""

数据框由三列组成,第一列和第二列是整数类型,第三列是整数列表。

我使用下面的这个函数在 PostgreSQL 中创建了一个表

def create_table(query: str) -> None:
"""

:param query: A string of the query to create table in the database
:return: None
"""
try:
    logger.info("Creating the table in the database")
    conn = psycopg2.connect(host=HOST, dbname=DATABASE_NAME, user=USER, password=PASSWORD, port=PORT)

    cur = conn.cursor()
    cur.execute(query)
    conn.commit()
    logger.info("Successfully created a table in the database using this query {}".format(query))
    return
except (Exception, psycopg2.Error) as e:
    logger.error("An error occurred while creating a table using the query {} with exception {}".format(query, e))
finally:
    if conn is not None:
        conn.close()
        logger.info("Connection closed!")

传递给这个函数的查询是这样的:

create_table_query = '''CREATE TABLE Recommendations
(id INT NOT NULL,
applicantId INT NOT NULL,
recommendation INTEGER[], 
PRIMARY KEY(id), 
CONSTRAINT applicantId
FOREIGN KEY(applicantId)
REFERENCES public."Applicant"(id)
ON DELETE CASCADE
ON UPDATE CASCADE 
); '''

然后我使用下面的函数将数据框复制到 postgres 中创建的表中。

def copy_from_file(df: pd.DataFrame, table: str = "recommendations") -> None:
    """
    Here we are going save the dataframe on disk as
    a csv file, load the csv file
    and use copy_from() to copy it to the table
    """

    conn = psycopg2.connect(host=HOST, dbname=DATABASE_NAME, user=USER, password=PASSWORD, port=PORT)
    # Save the dataframe to disk
    tmp_df = "./tmp_dataframe.csv"
    df.to_csv(tmp_df, index_label='id', header=False)
    f = open(tmp_df, 'r')
    cursor = conn.cursor()
    try:
        cursor.copy_from(f, table, sep=",")
        conn.commit()
    except (Exception, psycopg2.DatabaseError) as error:
        os.remove(tmp_df)
        logger.error("Error: %s" % error)
        conn.rollback()
        cursor.close()

    logger.info("copy_from_file() done")
    cursor.close()
    os.remove(tmp_df)

然后我仍然得到这个error: extra data after last expected column CONTEXT: COPY recommendations, line 1: "0,4070,"[5963, 8257, 9974, 7546, 11251, 5203, 102888, 8098, 101198, 10950]"" 请任何关于如何解决这个问题的建议?谢谢

【问题讨论】:

  • 您能否提供 CSV 中的示例行?这个:"[5963, 8257, 9974, 7546, 11251, 5203, 102888, 8098, 101198, 10950]"" 看起来不对。报价似乎已关闭。
  • 0,4070,[5963, 8257, 9974, 7546, 11251, 5203, 102888, 8098, 101198, 10950] @AdrianKlaver,上面是csv中的一个样本,“0”是id,接下来是申请者id,list是要传入推荐列的列表数据库
  • 我会检查这个的输出:df.to_csv(tmp_df, index_label='id', header=False)。看起来它没有得到正确的引用。这:"[5963, 8257, 9974, 7546, 11251, 5203, 102888, 8098, 101198, 10950]"" 无法正常工作。
  • 有没有办法可以将引号从中转义以使其成为一个列表?
  • 不确定。该值如何存储在数据框中?

标签: python pandas postgresql psycopg2


【解决方案1】:

copy_from 使用文本格式,而不是 csv 格式。您告诉它使用, 作为分隔符,但这不会改变它尝试使用的保护方法。所以引号内的逗号不被视为受保护,它们被视为字段分隔符,所以它们当然太多了。

我认为您需要使用copy_expert 并告诉它使用csv 格式。

【讨论】:

  • 谢谢!但现在我收到了这个错误Error: malformed array literal: "[2837, 8561, 9174, 103057, 100075, 5029, 8414, 102145]" DETAIL: Missing "]" after array dimensions. CONTEXT: COPY recommendations, line 2, column recommendation: "[2837, 8561, 9174, 103057, 100075, 5029, 8414, 102145]"
  • 对,PostgreSQL 数组的语法使用 {},而不是 []。
  • 既然它已经在数据框中,那么如何实现呢
  • 我对熊猫了解不多。 df 是否知道它正在与 postgresql 讨论数组?您可以将列数据类型更改为文本吗?
  • @RichardOgunyale 如果您的列表改为集合,您将看到生成的 CSV 将是 {} 而不是 []...尽管您可能还有其他一些问题需要解决。最后,使用类似:'{{{}}}'.format(','.join(['"' + item + '"' for item in the_list])) ... 可能最适合您。这应该在调用框架上的to_csv 方法之前完成。这样,CSV 导出将其视为字符串,而 Postgres 将其视为格式正确的数组无论您在该格式字符串中使用" 还是',都取决于您在COPY FROM 中使用的参数
猜你喜欢
  • 2017-02-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-17
  • 1970-01-01
  • 2011-07-21
  • 2016-09-06
  • 2018-08-21
  • 2021-06-13
相关资源
最近更新 更多