You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python结合BigQuery使用for循环插入数据仅保留最后一行问题咨询

问题根因

1. 中间表覆盖(最高概率)

如果你的<QUERY>逻辑包含CREATE OR REPLACE TABLE <tmp_proc1>/<tmp_proc2>语句,且这两个是指定了所属数据集的永久表,同时你提交BigQuery作业时没有等待前一次作业完成就提交下一次,会导致80个并发作业先后覆盖中间表内容,最终所有INSERT操作读取的都是最后一次覆盖的、对应第80个id的中间表数据,因此目标表仅保留最后一次插入结果。

2. 写入模式配置错误

如果提交查询作业时显式指定了写入模式为WRITE_TRUNCATE,每次插入都会清空目标表再写入当前id的数据,最终仅保留最后一次写入内容。

3. 临时表生命周期问题

如果<tmp_proc1>/<tmp_proc2>是会话级临时表,每次循环提交的独立作业会生成独立会话,作业结束后临时表自动清空,仅有最后一次作业的临时表内容成功插入目标表。

修复方案

  • 方案一(最简修复):每次作业执行后添加等待逻辑,避免并发覆盖,同时确认写入模式为默认追加模式
    代码示例:
    from google.cloud import bigquery
    client = bigquery.Client()
    
    for x in proc_arr:
        query = """
        BEGIN
        <QUERY>
        SELECT * FROM <table1> WHERE  procedureid = {}
        INSERT INTO <table> 
        SELECT procedureid FROM <tmp_proc1>
        UNION ALL
        SELECT procedureid FROM <tmp_proc2>;
        END;
        """.format(x)
        # 等待当前作业执行完成再进入下一次循环
        job = client.query(query)
        job.result()
    
  • 方案二(性能优化):取消循环提交作业,直接把所有id放入IN条件,单次查询完成全部插入,避免并发问题同时大幅提升执行效率
    代码示例:
    proc_ids = ','.join(map(str, proc_arr))
    query = f"""
    INSERT INTO <table>
    SELECT procedureid FROM (
      -- 替换为原<QUERY>中生成tmp_proc1的逻辑,添加IN过滤
      SELECT procedureid FROM <table1> WHERE procedureid IN ({proc_ids})
    )
    UNION ALL
    SELECT procedureid FROM (
      -- 替换为原<QUERY>中生成tmp_proc2的逻辑,添加IN过滤
      SELECT procedureid FROM <table2> WHERE procedureid IN ({proc_ids})
    )
    """
    client.query(query).result()
    
  • 方案三:如果必须保留中间表逻辑,每次循环给中间表设置唯一名称(例如拼接当前id值),避免不同循环的作业共用同一张中间表导致覆盖。

内容的提问来源于stack exchange,提问作者Misscurious

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 06:15:05