谷歌云存储下载账单明细,我踩了分页的坑
月初对账,客户是家做跨境电商的小公司,Google Cloud Storage 里存了 2TB 的产品图,每月出账后老板都要看明细。这个月账单突然涨了 40 美金,我得把 3 月 1 号到 31 号的存储和流量费用全拉下来,按 SKU 前缀分组,看看是哪个目录在烧钱。数据量不大,账单明细大概 12 万行,我用的是 Python 3.11 和 google-cloud-bigquery 3.10.0。
先别急着写脚本,我跟你讲,我第一版就栽在分页上。BigQuery 的 query 方法默认一次只返回 10000 行,我调用 result() 的时候没设 max_results,循环里直接迭代,结果只拿到前 10000 行,后边的全丢了。更坑的是,Google 的客户端库不会报错,它只是默默截断。我一开始没发现,因为汇总金额只比控制台少了几块钱,我以为汇率波动,没当回事。后来拿总行数一对,差得离谱。
改法很简单,但得记牢:用 to_dataframe() 或者显式设 max_results=None,让客户端自动翻页。我贴一段能直接用的:
from google.cloud import bigquery
client = bigquery.Client(project='your-project')
query = """
SELECT
invoice.month,
sku.description,
usage_start_time,
cost,
labels
FROM `your-project.billing.gcp_billing_export_v1_XXXXXX`
WHERE invoice.month = '202403'
AND service.description = 'Cloud Storage'
"""
job = client.query(query)
rows = list(job.result(max_results=None)) # 关键在这里
print(len(rows))
另外,标签里的 SKU 前缀不是现成字段,得从 labels 数组里自己拆。我一开始想用 SQL 的 UNNEST,但 labels 是 RECORD 类型,里头 key 和 value 混着,我图省事在 Python 里循环处理的,12 万行跑了不到两分钟,能接受。你要是数据量大,老老实实写 UNNEST,别学我。
为什么这么干:BigQuery 的计费导出表是按天分区的,查整月不加分区过滤,扫描量会翻倍。我加了 invoice.month 过滤,但更稳的是加 _PARTITIONTIME 的日期范围。代价是代码多一行,但能省扫描费,我吃过亏,有一次忘加,一个月多扫了 80GB,账单上多了几毛钱,不多,但心里膈应。
哪里会失效:第一,导出表不是实时的,通常延迟几小时到一天,你查最近两天的数据可能不全;第二,如果客户开了多个结算账号,你得跨项目查,权限得单独配,我上次就是漏了一个项目,对账对到半夜;第三,labels 里的 key 大小写不统一,有的写 sku,有的写 SKU,得先 lower() 再匹配。
最后留个问题:你们对账的时候,是直接查 BigQuery 导出表,还是用 Cloud Billing 的 API 拉明细?我总觉得 API 返回的字段更全,但文档写得绕,还没试。
0 条评论
还没有评论,写下第一条。