psycopg2 - 列表索引超出 html(大字符串)字段的范围

psycopg2 - List index out of range for html (large string) field

我有一个网络爬虫,它应该 save/insert 将 html 页面内容与一些其他元数据字段一起发送到 PostgreSQL 数据库。

使用 mogrify 插入 html 内容字段时,我会收到错误消息 List index out of range。如果我为 html 内容使用静态虚拟文本,例如“Hello World ö ü ä ß”(我正在处理德语字符集)插入工作正常。

这是我的功能:

def batch_insert(df, table, no_cols, conn=None, upsert_qry=""):
    """
    Using cursor.mogrify() to build the bulk insert query
    then cursor.execute() to execute the query
    """
    if conn is None:
        conn = get_connection()

    col_str = "(" + (no_cols-1)*"%s," + "%s)"
    # Create a list of tuples from the dataframe values
    tuples = [tuple(x) for x in df.to_numpy()]
    # Comma-separated dataframe columns
    cols = ','.join(list(df.columns))
    # SQL quert to execute
    cursor = conn.cursor()

    values = [cursor.mogrify(col_str, tup).decode('utf8') for tup in tuples]

    query = "INSERT INTO %s(%s) VALUES " % (table, cols) + ",".join(values) + upsert_qry
        #" ON CONFLICT (hk_portal_pid) DO UPDATE SET crawled_last=" + str(datetime.now())
        
    try:
        cursor.execute(query, tuples)
        conn.commit()
    except (Exception, psycopg2.DatabaseError) as error:
        print("Error: %s" % error)
        conn.rollback()
        cursor.close()
        return 1
    print("execute_mogrify() done")
    cursor.close()
    conn.close()

postgres 列字段声明为 text,如 this post 中所建议。我的 html 内容平均长度为 40.000 个字符,因此不应该有任何存储问题。

我还检查了函数中生成的元组是否因为转义字符等而针对 html 内容字段进行了拆分。但情况似乎并非如此。

>>>>[len(a) for a in tuples]
    [9, 9, 9, 9] # 4 rows / 9 columns

第 8 列 (page_content) 的数据类型是字符串:

>>>>type(tuples[0][7])
<class 'str'>

批量插入的目标 table:

CREATE TABLE public.as_portal_parent_content (
    hk_page varchar(100) NULL,
    hk_offer varchar(100) NULL,
    portal_id varchar(3) NULL,
    pid varchar(10) null,
    page_category varchar(30) null,
    page_link bpchar(300) null,
    status varchar(3) null,
    page_content text null,
    last_crawled timestamp null
);

非常感谢任何帮助!

Added/Edit:

回溯:

Traceback (most recent call last):
  File "C:/Users/PycharmProjects/pythonProject/project/playground.py", line 5, in <module>
    test.save_to_db(table='as_portal_parent_content')
  File "C:/Users/PycharmProjects/pythonProject/project/util/crawl.py", line 163, in save_to_db
    batch_insert(self.df, table)
  File "C:/Users/PycharmProjects/pythonProject/project/util/db.py", line 60, in batch_insert
    cursor.execute(query, tuples)
IndexError: list index out of range

Process finished with exit code 1

您不应该在 cursor.execute(query, tuples) 中使用 tuples
当您使用 mogrify 时,您基本上是在生成 sql 查询的后 VALUES 部分。因此,无需再次将查询参数(tuples 在您的情况下)传递给 cur.execute