使用Python操作Google BigQuery时出现Iterator has already started错误求助
解决Google BigQuery RowIterator "Iterator already started" 错误
问题原因
client.query().result()返回的RowIterator是单向一次性迭代器,只能被遍历一次。你的代码里外层循环每执行一次,就会尝试重新遍历query_job_articles,但第一次遍历后迭代器已经耗尽,第二次触发时就会抛出这个错误。
解决方案
方案1:将查询结果转为列表(简单直接)
把迭代器转换成Python列表,这样可以多次遍历:
# 将结果转为列表,支持多次遍历 query_job_doi = list(client.query(config_doi_sql).result()) query_job_articles = list(client.query(topic_articles_sql).result()) for row in query_job_doi: for row_a in query_job_articles: if row[0] == row_a[0]: print("Success") else: print("DOI Miss match")
注意:如果查询结果数据量极大,转列表会占用较多内存,此时建议用方案2。
方案2:在BigQuery中直接做JOIN(高效推荐)
避免在Python里做嵌套循环,直接通过SQL JOIN让BigQuery处理匹配逻辑,效率更高:
-- 示例JOIN SQL,根据实际表结构调整 SELECT d.doi AS doi_doi, a.doi AS article_doi, CASE WHEN d.doi = a.doi THEN 'Success' ELSE 'DOI Miss match' END AS match_result FROM (你的config_doi_sql对应的子查询) d CROSS JOIN (你的topic_articles_sql对应的子查询) a
然后在Python中直接执行这个JOIN后的查询,遍历结果即可:
join_sql = """ SELECT d.doi AS doi_doi, a.doi AS article_doi, CASE WHEN d.doi = a.doi THEN 'Success' ELSE 'DOI Miss match' END AS match_result FROM (SELECT * FROM your_config_table) d CROSS JOIN (SELECT * FROM your_articles_table) a """ query_job = client.query(join_sql).result() for row in query_job: print(row.match_result)
如果只需要匹配成功的记录,可以改用INNER JOIN替代CROSS JOIN,减少返回的数据量。
内容的提问来源于stack exchange,提问作者Archie
相关产品推荐
相关产品推荐

