dashboard docs / googleads / field mapping
models.py · 2026-07-30

Engineering overview · Google Ads schema

Google Ads P0 與延伸欄位落地總覽

一次看懂這次新增哪些 DB table/欄位、為什麼需要,以及 dashboard-mcp 與 ad-report-agent 查詢時不能忽略的資料語意。

讀者 dashboard · dashboard-mcp · ad-report-agent 正式依據 models.py Migration 0009–0013
本頁目錄
  1. 總覽
  2. 既有表新增欄位
  3. 新增 rate tables
  4. Rate 查詢規則
  5. 資料正確性補強
  6. 空值與資料時間
  7. Migration 對照
00 / EXECUTIVE SUMMARY

從 P0 欄位到可持續查詢的正式資料層#

本次從 ad-report 原始文件中的 P0 需求出發,不只補齊 schema,也補上實作後確認不可缺少的資料正確性與同步能力。

28 既有 6 張表新增欄位
26 個原始 P0 + 2 個延伸欄位
2 新增邏輯資料表
Campaign 與 Ad group 的 rate-only metrics
5 影音 rate 指標
TrueView + 25%/50%/75%/100%
資料落地與查詢路徑
Google Ads API v24 提供 attributes、daily metrics 與各層級 rate
獨立同步管線 Attributes 更新目前狀態;rate 依日期寫入並可冪等重跑
Dashboard 正式 DB Agent/MCP 直接查詢;不再依賴臨時表或缺欄位
核心差異:屬性是「目前狀態」,metrics 是「每日資料」;兩者可回答的歷史問題不同。
Schema 之外也已完成資料管線

已包含獨立 attributes/rate 同步、每日排程、手動回填與 partition 維護。新增欄位不是只有 DB 結構,而是能持續寫入與重跑。

NULL 是設計的一部分

所有新增欄位都允許 NULL。Google 沒有提供、欄位不適用或實體不存在時,空值不等於同步失敗,也不等於數值 0。

01 / EXISTING TABLES

既有 DB table 新增欄位#

DB table新增欄位範圍主要使用者/原因
googleads__ad_metrics video_trueview_view_rate 原始 P0 Ad Report Agent 需要觀看率;採 Google Ads API v24 正式名稱。
googleads__ad_metrics video_quartile_p25_ratep50p75p100 原始 P0 Agent/MCP 需要 25%~100% 影音觀看率。
googleads__ad_campaign advertising_channel_typeadvertising_channel_sub_type 原始 P0 辨識 Search、Display、PMAX、Demand Gen 等 campaign 類型,取代 dashboard-mcp 的臨時 dim_campaign
googleads__ad_campaign bidding_strategy_typestatus 原始 P0 解釋出價策略與啟用狀態,取代臨時表。
googleads__ad_campaign optimization_score 原始 P0 提供 campaign 層最佳化分數。
googleads__ad_campaign start_date_timeend_date_time 原始 P0 提供投放期間;名稱跟隨 Google Ads API v24。
googleads__ad_campaign budget_amounttarget_cpatarget_roas 原始 P0 分析預算與出價目標。
googleads__ad_campaign budget_id 延伸 · 正確性 共用預算須依 ID 去重;沒有 ID 時,實測直接加總會高估 5.1%。
googleads__ad_group statusgroup_type 原始 P0 提供 ad group 狀態與類型;避免與 ad 的 type 混淆。
googleads__ad_group cpc_bidcpm_bidtarget_cpatarget_roas 原始 P0 提供 ad group 層出價與目標值。
googleads__ad ad_typestatusfinal_urlsad_strength 原始 P0 支援廣告格式、狀態、到達網址及素材強度分析。
googleads__keyword match_type 原始 P0 支援 EXACT/PHRASE/BROAD 關鍵字分析。
googleads__ad_account optimization_score 延伸 · 完整性 帳號層分數依花費加權;API v24 未提供還原權重,不能用 campaign 平均代替。

名稱與型別注意事項#

來源/舊名稱Dashboard DB 名稱查詢注意事項
video_view_ratevideo_trueview_view_ratev24 已不接受舊名稱;值為 0~1,顯示百分比時才乘 100。
start_dateend_datestart_date_timeend_date_timeDB 是 CharField,格式為帳號時區的 YYYY-MM-DD HH:MM:SS
budget_amount_microsbudget_amount已除以 10⁶,保存帳號幣別金額。
target_cpa_microstarget_cpa已除以 10⁶,保存帳號幣別金額。
cpc_bid_microscpm_bid_microscpc_bidcpm_bid已除以 10⁶,保存帳號幣別金額。
ad_group.typegroup_type避免和 googleads__ad.ad_type 混淆。
keyword_match_typematch_type已位於 keyword table,不重複保留 keyword_ 前綴。
final_urlsfinal_urlsPostgreSQL array,不是單一字串。
target_roastarget_roasRatio;例如 4.0 代表 400%。
金額不可再次換算

budget_amounttarget_cpacpc_bidcpm_bid 都已換算成帳號幣別。dashboard-mcp 與 ad-report-agent 不可再次除以 10⁶。

02 / NEW TABLES

新增 campaign/ad group rate-only table#

Rate 的正確值與資料層級綁定。為避免從 ad 明細錯誤聚合回上層,新增兩張只保存 daily rate 的 partition table。

新資料表一筆資料/唯一鍵保存內容新增原因
googleads__ad_campaign_metrics campaign_id × date Campaign 單日的 5 個影音 rate ad × date × device 聚合的誤差實測可達 −64%~+53%。
googleads__ad_group_metrics group_id × date Ad group 單日的 5 個影音 rate Ad group rate 同樣不能由 ad 層可靠還原。
Data model decision

只保存 rate,不複製可加總量

Chosen
新表保存 TrueView 與四段 quartile rate。
Why
這些值無法從 ad 層資料精確還原。
Boundary
Impressions、clicks、cost 仍以 googleads__ad_metrics 為唯一來源。
Write rule
只寫入至少一個影音 rate 有值的實體/日期。

Partition 與欄位#

兩張表都依 date 做 range partition,並對實體 ID + date 設 unique constraint,可安全重跑。Migration 另建立兩張 default partition 子表,讓年度 partition 尚未建立時仍有安全承接區。

資料表欄位用途
googleads__ad_campaign_metricsidcampaign_iddatePrimary key、campaign 關聯與 partition key。
同上video_trueview_view_rate、四個 video_quartile_*Campaign 層單日觀看率。
googleads__ad_group_metricsidgroup_iddatePrimary key、ad group 關聯與 partition key。
同上video_trueview_view_rate、四個 video_quartile_*Ad group 層單日觀看率。

沒有 account rate table:Google 的 account 資源不支援 quartile 欄位。也沒有 search term rate table,因為實測沒有影音資料。

03 / QUERY CONTRACT

各層影音 rate 要查哪裡#

層級正確資料來源可否跨列直接聚合
Adgoogleads__ad_metrics不可;每列是一個 ad 在某日、某裝置的資料。
Campaigngoogleads__ad_campaign_metrics查單日原始值;不可 SUM rate。
Ad groupgoogleads__ad_group_metrics查單日原始值;不可 SUM rate。
AccountCampaign rate + 可取得的正確分母,或直接查 Google API不可平均 campaign rate。
不可用 AVG(ad rate)它不等於 campaign/ad group rate。
不可自行以 impressions 或 video views 加權Google Ads API 沒有提供足以還原 quartile rate 的正確分母。
不可直接平均多天的 rate跨日只能做近似分析;精確區間值要直接查 Google API。
Rate 是比率,不是可加總量

資料庫缺少 Google 計算 quartile rate 所需的完整分母。排除 NULL 只能避免把「無資料」當成 0,不能讓簡單平均變成精確上層 rate。

04 / CORRECTNESS

為資料正確性多做的工作#

下列補強不全是原始 P0 欄位,但缺少任何一項,都可能讓 Agent/MCP 產生錯誤答案或讓新欄位停止更新。

補強項目新增 DB 欄位/表原因
Campaign 新增 budget_id共用預算必須先依 budget_id 去重,不能直接 SUM(budget_amount)
Account 新增 optimization_scoreCampaign 分數平均與帳號真值實測相差 +2.5%/−3.1%,且方向不一致。
Campaign/ad group rate-only table上層 rate 無法從 ad metrics 準確聚合。
target_cpatarget_roas 補巢狀取值避免漏掉 MAXIMIZE_CONVERSIONS/MAXIMIZE_CONVERSION_VALUE 的目標值。
Account ID 同時支援純數字與連字號避免 DB/API ID 格式不同而沒有更新到 attributes。
Attributes 獨立同步與每日排程屬性只保存目前狀態,不是逐日資料,因此獨立於 metrics 流程更新。
Rate 獨立同步與限流Staging 對齊既有 metrics 抓 D2;prod 抓 D0~D7,吸收 Google 近日延遲回填。
新表加入 partition 建立流程是,屬於表結構避免資料長期落入 default partition。
手動 attributes/rate commands支援 staging 驗證、歷史回填與失敗後冪等重跑。

Campaign 預算的正確加總方式#

SQL · deduplicate shared budgets
SELECT sum(budget_amount)
FROM (
  SELECT DISTINCT budget_id, budget_amount
  FROM googleads__ad_campaign
  WHERE account_id = %s
    AND status = 'ENABLED'
    AND budget_id IS NOT NULL
) AS budgets;
05 / DATA SEMANTICS

如何判讀空值與資料時間#

NULL 的意思是「目前沒有可用資料」,可能是不適用、沒有設定或 Google 未提供。驗收同步結果時,不應要求所有欄位 100% 有值;製作報表時,也不可把空值改成數值 0。

哪些空值是正常的#

情況DB 中的正常結果代表的意思
非影音廣告五個影音 rate 為 NULL不適用影音觀看率,不是觀看率為 0%。
PMAX/SMART可能只有 view rate,quartile rate 為 NULLGoogle 沒有提供完整四段觀看率。
PMAX/SMART 偽 ad group/ad屬性可能全部為 NULLDashboard 為維持階層建立實體,但 Google 沒有對應的真實實體。
Demand Gen ad groupgroup_type 可能為 NULL只有類型未提供,不能把整個 ad group 判定為同步失敗。
Campaign 未設定結束日end_date_timeNULLCampaign 沒有指定結束時間。
未使用對應出價策略target_cpatarget_roasNULL該出價目標不適用,不代表目標值為 0。
停用 campaignoptimization_score 可能為 NULLGoogle 可能不提供停用 campaign 的分數。
某實體當天沒有影音資料新 rate table 沒有該列當天沒有可保存的 rate,不代表排程一定失敗。

為什麼 NULL 不能當 0#

資料列Rate實際語意
影音廣告 A50%有影音資料,觀看率是 50%。
非影音廣告 BNULL不適用影音觀看率。
錯誤結果會從 50% 變成 25%

若把廣告 B 的 NULL 當成 0% 再平均,就會憑空建立一個 0% 觀看率並把真實結果拉低。正確做法是排除 B;但若要 campaign/ad group 正式數值,仍應直接查對應層級 rate table。

哪些資料能回查某一天#

Historical · 有 date

Metrics

Ad/campaign/ad group metrics 每天各自保存,可回答某一天的花費、點擊或影音 rate。

Current state · 無每日版本

Attributes

Account/campaign/ad group/ad 每次同步更新同一列,只能回答最近同步時的狀態、預算與出價設定。

例如現在查到 campaign 的 status = 'PAUSED',只能知道最近一次同步時是暫停狀態,不能據此判斷上週是否也暫停。若要分析屬性歷史變化,未來必須另外建立每日快照。

06 / IMPLEMENTATION MAP

Migration 對照#

MigrationDB 變更
0009_add_video_rate_metricsgoogleads__ad_metrics 新增 5 個影音 rate。
0010_add_campaign_and_account_attributesCampaign 新增 11 欄;account 新增 optimization_score
0011_add_adgroup_ad_attributesAd group 新增 6 欄;ad 新增 4 欄。
0012_add_keyword_match_typeKeyword 新增 match_type
0013_add_level_rate_metrics_tables新增 campaign/ad group rate partition table。
實際 schema 的唯一依據

若文件與程式碼出現差異,以 backend/apps/ad/platforms/googleads/models.py 為準。

Google Ads P0 與延伸欄位落地總覽 · 單頁文件 · 最後整理:2026-07-30