Python从第三方API批量写入Firestore问题求助
问题解决:Firestore仅写入最后一条赛事数据及实现更新/新增逻辑
问题根源
- 原代码中Firestore写入逻辑在for循环外部,循环结束后仅保留最后一场赛事的变量值,导致只写入最后一条数据
- 使用
document()生成随机ID的文档,无法通过赛事唯一标识(event_id)匹配已有文档,无法实现更新逻辑 - 函数参数错误:调用
bluebet_nba_odds时传入了函数自身,属于无效参数
修复方案及代码
以下是修正后的完整代码,包含核心逻辑优化:
import requests from google.cloud import firestore client = firestore.Client(project='PROJECTNAME') def bluebet_nba_odds(): # API 请求:直接用response.json()解析,无需手动转字符串再loads link = 'https://xxxxxxxxxx.com.au/json/reply/MasterCategoryRequest?EventTypeID=107&WithLevelledMarkets=true&WithLevelledMarkets=true' nbadata = requests.get(link).json() # 遍历每场赛事,将写入逻辑放在循环内部 for nba_odds in nbadata['MasterCategories'][2]['Categories'][0]['MasterEvents']: # 提取单场赛事数据 competition = nba_odds['CategoryName'] event_id = nba_odds['MasterEventId'] event_title = nba_odds['MasterEventName'] start_time = nba_odds['MaxAdvertisedStartTime'] home_team = nba_odds['Markets'][0]['OutcomeName'] home_team_win_odds = nba_odds['Markets'][0]['Price'] away_team = nba_odds['Markets'][1]['OutcomeName'] away_team_win_odds = nba_odds['Markets'][1]['Price'] # 构造要写入的数据 event_data = { 'competition': competition, 'event_id': event_id, 'event_title': event_title, 'start_time': start_time, 'home_team': home_team, 'home_team_win_odds': home_team_win_odds, 'away_team': away_team, 'away_team_win_odds': away_team_win_odds, } # 关键:用event_id作为文档ID,实现"存在则更新,不存在则新增" # merge=True确保只更新变化的字段(可选,默认set也会覆盖,但merge更安全) doc_ref = client.collection('bluebet_nba_season_odds').document(str(event_id)) doc_ref.set(event_data, merge=True) if __name__ == "__main__": bluebet_nba_odds()
关键改动说明
- 循环内写入数据:将Firestore的写入操作移到for循环内部,确保每场赛事的数据都被处理
- 用event_id作为文档ID:赛事的
MasterEventId是唯一标识,用它作为文档ID可以精准匹配已有赛事,实现更新逻辑 - merge=True参数:调用
set时添加该参数,会仅更新数据中变化的字段,保留原有文档中未修改的内容(如果不需要保留其他字段,可以去掉,默认set会覆盖整个文档) - 移除全局变量:循环内直接处理单场数据,避免全局变量被多次覆盖导致的错误
- 优化API解析:使用
requests.get(link).json()直接解析响应,简化代码 - 修复函数调用:移除无效的函数参数,直接调用
bluebet_nba_odds()
内容的提问来源于stack exchange,提问作者DrewS
相关产品推荐
相关产品推荐

