使用flask_sqlalchemy将新闻爬虫数据存入PostgreSQL报错如何解决?
问题根因
从报错和代码可以定位到4个核心错误:
- 数据类型不匹配:爬虫获取的
Title/Link/Date/Image都是列表类型,而News模型对应字段均为字符串类型,直接将整个列表写入字符串字段会触发SQL类型错误 - 外键定义错误:
Type表的主键字段为id,但News表的外键配置指向了不存在的type.type_id字段,关联逻辑完全失效 - 分类重复创建:每次循环分类都会新建
Type实例,相同分类会重复入库,不符合一对多的设计逻辑 - 执行顺序错误:
app.py中先导入执行爬虫、后创建表结构,表未初始化时写入数据会报错
修复方案
1. 修正模型外键配置
修改models.py中News类的外键定义,匹配Type表的主键字段:
# 原错误代码:type_id = db.Column(db.Integer, db.ForeignKey('type.type_id')) # 替换为: type_id = db.Column(db.Integer, db.ForeignKey('Type.id'))
同时可根据实际爬取的内容长度,调大字段限制避免超长报错:
title = db.Column(db.String(500)) link = db.Column(db.String(1000)) img = db.Column(db.String(1000))
2. 修正爬虫存储逻辑
修改scrape.py,先判断分类是否存在,再遍历单条新闻逐个创建实例:
for i in [2, 4, 5]: url = f'https://www.ninanews.com/Website/News/List?key={i}' current_type = get_url_type(url)[0] # 分类去重,不存在再新建 type_obj = Type.query.filter_by(type_name=current_type).first() if not type_obj: type_obj = Type(type_name=current_type) db.session.add(type_obj) db.session.commit() titles = get_title(i, pages) links = get_link(i, pages) dates = get_date(i, pages) imgs = get_images(i, pages) # 遍历单条新闻逐个入库 for title, link, date, img in zip(titles, links, dates, imgs): news_obj = News( title=title, link=link, date=date, img=img ) news_obj.type_id = type_obj.id db.session.add(news_obj) # 单个分类所有新闻处理完后统一提交 db.session.commit()
3. 修正app.py执行顺序
先创建表结构,再执行爬虫逻辑:
if __name__ == '__main__': with app.app_context(): # 先建表 db.create_all() # 后执行爬虫 import News.scrape_ninanews app.run()
内容的提问来源于stack exchange,提问作者Mohammed Al-fathi
相关产品推荐
相关产品推荐

