问题描述
我有一个网络爬虫,它应该将 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()
按照this post 中的建议,postgres 列字段声明为text
。在我的案例中,html 内容的平均长度为 40.000 个字符,因此不应该有任何存储问题。
我还检查了函数中生成的元组是否因转义字符等原因被拆分为 html 内容字段。但似乎并非如此。
>>>>[len(a) for a in tuples]
[9,9,9] # 4 rows / 9 columns
第 8 列(page_content)的数据类型是字符串:
>>>>type(tuples[0][7])
<class 'str'>
批量插入的目标表:
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
);
非常感谢任何帮助!
添加/编辑:
追溯:
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
解决方法
您不应在 tuples
中使用 cursor.execute(query,tuples)
。
当您使用 mogrify
时,您基本上是在生成 sql 查询的 after-VALUES 部分。因此,无需再次将查询参数(在您的情况下为 tuples
)传递给 cur.execute
。