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
。
我有一个网络爬虫,它应该 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
。