[{"data":1,"prerenderedAt":2706},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fit\u002Fdata\u002Fdbt-bigquery-modern-data-stack-marketing":13},{"i18nKey":4,"paths":5},"data-002-2026-08",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Fdata\u002Fdbt-bigquery-moderner-marketing-data-stack","\u002Fen\u002Fdata\u002Fdbt-bigquery-modern-marketing-data-stack","\u002Fes\u002Fdata\u002Fdbt-bigquery-modern-marketing-data-stack","\u002Ffr\u002Fdata\u002Fdbt-bigquery-modern-pazarlama-data-stack","\u002Fit\u002Fdata\u002Fdbt-bigquery-modern-data-stack-marketing","\u002Fru\u002Fdata\u002Fdbt-bigquery-modern-pazarlama-veri-yigini","\u002Ftr\u002Fdata\u002Fdbt-bigquery-ile-modern-pazarlama-data-stack",{"_path":10,"_dir":14,"_draft":15,"_partial":15,"_locale":16,"title":17,"description":18,"publishedAt":19,"modifiedAt":19,"category":14,"i18nKey":4,"tags":20,"readingTime":26,"author":27,"body":28,"_type":2700,"_id":2701,"_source":2702,"_file":2703,"_stem":2704,"_extension":2705},"data",false,"","dbt + BigQuery con Data Stack Moderno per il Marketing","Source mapping, modeling layer, semantic layer, exposures — l'architettura che collega i dati di marketing al processo decisionale e l'implementazione pratica di dbt.","2026-08-02",[21,22,23,24,25],"dbt","bigquery","data-stack","semantic-layer","marketing-analytics",9,"Roibase",{"type":29,"children":30,"toc":2688},"root",[31,39,46,60,284,297,316,652,665,671,682,1332,1337,1355,1362,1367,1608,1621,1627,1639,1902,1907,1917,1927,1933,1938,2099,2112,2138,2144,2157,2448,2469,2479,2485,2490,2529,2534,2555,2561,2566,2660,2677,2682],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36],{"type":37,"value":38},"text","I team di marketing non utilizzano più i report predefiniti di Google Analytics, ma pipeline dati che scrivono e controllano direttamente. Nel 2026, il data stack moderno per il marketing si compone di tre livelli: sorgenti raw, modeling layer, semantic layer. Questo articolo spiega come costruire questi tre livelli con dbt + BigQuery, quali errori si commettono a ogni stadio e come strutturare un'architettura sostenibile in produzione.",{"type":32,"tag":40,"props":41,"children":43},"h2",{"id":42},"source-mapping-caricare-dati-in-bigquery-non-basta",[44],{"type":37,"value":45},"Source mapping: caricare dati in BigQuery non basta",{"type":32,"tag":33,"props":47,"children":48},{},[49,51,58],{"type":37,"value":50},"Hai caricato GA4, Meta Ads, sGTM event in BigQuery — ma è solo l'inizio. Source mapping significa trasformare le tabelle raw in contract significativi. In dbt, le definizioni di source vivono in file ",{"type":32,"tag":52,"props":53,"children":55},"code",{"className":54},[],[56],{"type":37,"value":57},".yml",{"type":37,"value":59},":",{"type":32,"tag":61,"props":62,"children":66},"pre",{"className":63,"code":64,"language":65,"meta":16,"style":16},"language-yaml shiki shiki-themes github-dark","sources:\n  - name: raw_ga4\n    database: roibase-prod\n    schema: analytics_123456789\n    tables:\n      - name: events_*\n        identifier: events_*\n        loaded_at_field: event_timestamp\n        freshness:\n          warn_after: {count: 12, period: hour}\n","yaml",[67],{"type":32,"tag":52,"props":68,"children":69},{"__ignoreMap":16},[70,88,113,131,149,162,184,201,219,231],{"type":32,"tag":71,"props":72,"children":75},"span",{"class":73,"line":74},"line",1,[76,82],{"type":32,"tag":71,"props":77,"children":79},{"style":78},"--shiki-default:#85E89D",[80],{"type":37,"value":81},"sources",{"type":32,"tag":71,"props":83,"children":85},{"style":84},"--shiki-default:#E1E4E8",[86],{"type":37,"value":87},":\n",{"type":32,"tag":71,"props":89,"children":91},{"class":73,"line":90},2,[92,97,102,107],{"type":32,"tag":71,"props":93,"children":94},{"style":84},[95],{"type":37,"value":96},"  - ",{"type":32,"tag":71,"props":98,"children":99},{"style":78},[100],{"type":37,"value":101},"name",{"type":32,"tag":71,"props":103,"children":104},{"style":84},[105],{"type":37,"value":106},": ",{"type":32,"tag":71,"props":108,"children":110},{"style":109},"--shiki-default:#9ECBFF",[111],{"type":37,"value":112},"raw_ga4\n",{"type":32,"tag":71,"props":114,"children":116},{"class":73,"line":115},3,[117,122,126],{"type":32,"tag":71,"props":118,"children":119},{"style":78},[120],{"type":37,"value":121},"    database",{"type":32,"tag":71,"props":123,"children":124},{"style":84},[125],{"type":37,"value":106},{"type":32,"tag":71,"props":127,"children":128},{"style":109},[129],{"type":37,"value":130},"roibase-prod\n",{"type":32,"tag":71,"props":132,"children":134},{"class":73,"line":133},4,[135,140,144],{"type":32,"tag":71,"props":136,"children":137},{"style":78},[138],{"type":37,"value":139},"    schema",{"type":32,"tag":71,"props":141,"children":142},{"style":84},[143],{"type":37,"value":106},{"type":32,"tag":71,"props":145,"children":146},{"style":109},[147],{"type":37,"value":148},"analytics_123456789\n",{"type":32,"tag":71,"props":150,"children":152},{"class":73,"line":151},5,[153,158],{"type":32,"tag":71,"props":154,"children":155},{"style":78},[156],{"type":37,"value":157},"    tables",{"type":32,"tag":71,"props":159,"children":160},{"style":84},[161],{"type":37,"value":87},{"type":32,"tag":71,"props":163,"children":165},{"class":73,"line":164},6,[166,171,175,179],{"type":32,"tag":71,"props":167,"children":168},{"style":84},[169],{"type":37,"value":170},"      - ",{"type":32,"tag":71,"props":172,"children":173},{"style":78},[174],{"type":37,"value":101},{"type":32,"tag":71,"props":176,"children":177},{"style":84},[178],{"type":37,"value":106},{"type":32,"tag":71,"props":180,"children":181},{"style":109},[182],{"type":37,"value":183},"events_*\n",{"type":32,"tag":71,"props":185,"children":187},{"class":73,"line":186},7,[188,193,197],{"type":32,"tag":71,"props":189,"children":190},{"style":78},[191],{"type":37,"value":192},"        identifier",{"type":32,"tag":71,"props":194,"children":195},{"style":84},[196],{"type":37,"value":106},{"type":32,"tag":71,"props":198,"children":199},{"style":109},[200],{"type":37,"value":183},{"type":32,"tag":71,"props":202,"children":204},{"class":73,"line":203},8,[205,210,214],{"type":32,"tag":71,"props":206,"children":207},{"style":78},[208],{"type":37,"value":209},"        loaded_at_field",{"type":32,"tag":71,"props":211,"children":212},{"style":84},[213],{"type":37,"value":106},{"type":32,"tag":71,"props":215,"children":216},{"style":109},[217],{"type":37,"value":218},"event_timestamp\n",{"type":32,"tag":71,"props":220,"children":221},{"class":73,"line":26},[222,227],{"type":32,"tag":71,"props":223,"children":224},{"style":78},[225],{"type":37,"value":226},"        freshness",{"type":32,"tag":71,"props":228,"children":229},{"style":84},[230],{"type":37,"value":87},{"type":32,"tag":71,"props":232,"children":234},{"class":73,"line":233},10,[235,240,245,250,254,260,265,270,274,279],{"type":32,"tag":71,"props":236,"children":237},{"style":78},[238],{"type":37,"value":239},"          warn_after",{"type":32,"tag":71,"props":241,"children":242},{"style":84},[243],{"type":37,"value":244},": {",{"type":32,"tag":71,"props":246,"children":247},{"style":78},[248],{"type":37,"value":249},"count",{"type":32,"tag":71,"props":251,"children":252},{"style":84},[253],{"type":37,"value":106},{"type":32,"tag":71,"props":255,"children":257},{"style":256},"--shiki-default:#79B8FF",[258],{"type":37,"value":259},"12",{"type":32,"tag":71,"props":261,"children":262},{"style":84},[263],{"type":37,"value":264},", ",{"type":32,"tag":71,"props":266,"children":267},{"style":78},[268],{"type":37,"value":269},"period",{"type":32,"tag":71,"props":271,"children":272},{"style":84},[273],{"type":37,"value":106},{"type":32,"tag":71,"props":275,"children":276},{"style":109},[277],{"type":37,"value":278},"hour",{"type":32,"tag":71,"props":280,"children":281},{"style":84},[282],{"type":37,"value":283},"}\n",{"type":32,"tag":33,"props":285,"children":286},{},[287,289,295],{"type":37,"value":288},"Questa definizione realizza tre cose: (1) Data lineage — quale modello utilizza quale tabella raw, (2) Freshness check — se l'ultimo event è più vecchio di 12 ore, un alert viene generato, (3) Contract — se manca la colonna ",{"type":32,"tag":52,"props":290,"children":292},{"className":291},[],[293],{"type":37,"value":294},"event_timestamp",{"type":37,"value":296},", il build fallisce.",{"type":32,"tag":33,"props":298,"children":299},{},[300,306,308,314],{"type":32,"tag":301,"props":302,"children":303},"strong",{},[304],{"type":37,"value":305},"L'errore più comune:",{"type":37,"value":307}," usare lo schema raw così com'è. Scrivere SQL senza flatten l'array ",{"type":32,"tag":52,"props":309,"children":311},{"className":310},[],[312],{"type":37,"value":313},"event_params",{"type":37,"value":315}," di GA4, ogni query diventa 200+ righe. La logica di unnest deve vivere in un'unica posizione durante il source mapping:",{"type":32,"tag":61,"props":317,"children":321},{"className":318,"code":319,"language":320,"meta":16,"style":16},"language-sql shiki shiki-themes github-dark","-- models\u002Fstaging\u002Fstg_ga4_events.sql\nwith source as (\n  select * from {{ source('raw_ga4', 'events_*') }}\n),\n\nflattened as (\n  select\n    event_date,\n    event_timestamp,\n    user_pseudo_id,\n    (select value.string_value from unnest(event_params) where key = 'session_id') as session_id,\n    (select value.int_value from unnest(event_params) where key = 'ga_session_number') as session_number\n  from source\n)\n\nselect * from flattened\n","sql",[322],{"type":32,"tag":52,"props":323,"children":324},{"__ignoreMap":16},[325,334,358,400,408,417,433,441,449,457,465,537,600,614,623,631],{"type":32,"tag":71,"props":326,"children":327},{"class":73,"line":74},[328],{"type":32,"tag":71,"props":329,"children":331},{"style":330},"--shiki-default:#6A737D",[332],{"type":37,"value":333},"-- models\u002Fstaging\u002Fstg_ga4_events.sql\n",{"type":32,"tag":71,"props":335,"children":336},{"class":73,"line":90},[337,343,348,353],{"type":32,"tag":71,"props":338,"children":340},{"style":339},"--shiki-default:#F97583",[341],{"type":37,"value":342},"with",{"type":32,"tag":71,"props":344,"children":345},{"style":84},[346],{"type":37,"value":347}," source ",{"type":32,"tag":71,"props":349,"children":350},{"style":339},[351],{"type":37,"value":352},"as",{"type":32,"tag":71,"props":354,"children":355},{"style":84},[356],{"type":37,"value":357}," (\n",{"type":32,"tag":71,"props":359,"children":360},{"class":73,"line":115},[361,366,371,376,381,386,390,395],{"type":32,"tag":71,"props":362,"children":363},{"style":339},[364],{"type":37,"value":365},"  select",{"type":32,"tag":71,"props":367,"children":368},{"style":339},[369],{"type":37,"value":370}," *",{"type":32,"tag":71,"props":372,"children":373},{"style":339},[374],{"type":37,"value":375}," from",{"type":32,"tag":71,"props":377,"children":378},{"style":84},[379],{"type":37,"value":380}," {{ source(",{"type":32,"tag":71,"props":382,"children":383},{"style":109},[384],{"type":37,"value":385},"'raw_ga4'",{"type":32,"tag":71,"props":387,"children":388},{"style":84},[389],{"type":37,"value":264},{"type":32,"tag":71,"props":391,"children":392},{"style":109},[393],{"type":37,"value":394},"'events_*'",{"type":32,"tag":71,"props":396,"children":397},{"style":84},[398],{"type":37,"value":399},") }}\n",{"type":32,"tag":71,"props":401,"children":402},{"class":73,"line":133},[403],{"type":32,"tag":71,"props":404,"children":405},{"style":84},[406],{"type":37,"value":407},"),\n",{"type":32,"tag":71,"props":409,"children":410},{"class":73,"line":151},[411],{"type":32,"tag":71,"props":412,"children":414},{"emptyLinePlaceholder":413},true,[415],{"type":37,"value":416},"\n",{"type":32,"tag":71,"props":418,"children":419},{"class":73,"line":164},[420,425,429],{"type":32,"tag":71,"props":421,"children":422},{"style":84},[423],{"type":37,"value":424},"flattened ",{"type":32,"tag":71,"props":426,"children":427},{"style":339},[428],{"type":37,"value":352},{"type":32,"tag":71,"props":430,"children":431},{"style":84},[432],{"type":37,"value":357},{"type":32,"tag":71,"props":434,"children":435},{"class":73,"line":186},[436],{"type":32,"tag":71,"props":437,"children":438},{"style":339},[439],{"type":37,"value":440},"  select\n",{"type":32,"tag":71,"props":442,"children":443},{"class":73,"line":203},[444],{"type":32,"tag":71,"props":445,"children":446},{"style":84},[447],{"type":37,"value":448},"    event_date,\n",{"type":32,"tag":71,"props":450,"children":451},{"class":73,"line":26},[452],{"type":32,"tag":71,"props":453,"children":454},{"style":84},[455],{"type":37,"value":456},"    event_timestamp,\n",{"type":32,"tag":71,"props":458,"children":459},{"class":73,"line":233},[460],{"type":32,"tag":71,"props":461,"children":462},{"style":84},[463],{"type":37,"value":464},"    user_pseudo_id,\n",{"type":32,"tag":71,"props":466,"children":468},{"class":73,"line":467},11,[469,474,479,484,489,494,498,503,508,513,518,523,528,532],{"type":32,"tag":71,"props":470,"children":471},{"style":84},[472],{"type":37,"value":473},"    (",{"type":32,"tag":71,"props":475,"children":476},{"style":339},[477],{"type":37,"value":478},"select",{"type":32,"tag":71,"props":480,"children":481},{"style":256},[482],{"type":37,"value":483}," value",{"type":32,"tag":71,"props":485,"children":486},{"style":84},[487],{"type":37,"value":488},".",{"type":32,"tag":71,"props":490,"children":491},{"style":256},[492],{"type":37,"value":493},"string_value",{"type":32,"tag":71,"props":495,"children":496},{"style":339},[497],{"type":37,"value":375},{"type":32,"tag":71,"props":499,"children":500},{"style":84},[501],{"type":37,"value":502}," unnest(event_params) ",{"type":32,"tag":71,"props":504,"children":505},{"style":339},[506],{"type":37,"value":507},"where",{"type":32,"tag":71,"props":509,"children":510},{"style":339},[511],{"type":37,"value":512}," key",{"type":32,"tag":71,"props":514,"children":515},{"style":339},[516],{"type":37,"value":517}," =",{"type":32,"tag":71,"props":519,"children":520},{"style":109},[521],{"type":37,"value":522}," 'session_id'",{"type":32,"tag":71,"props":524,"children":525},{"style":84},[526],{"type":37,"value":527},") ",{"type":32,"tag":71,"props":529,"children":530},{"style":339},[531],{"type":37,"value":352},{"type":32,"tag":71,"props":533,"children":534},{"style":84},[535],{"type":37,"value":536}," session_id,\n",{"type":32,"tag":71,"props":538,"children":540},{"class":73,"line":539},12,[541,545,549,553,557,562,566,570,574,578,582,587,591,595],{"type":32,"tag":71,"props":542,"children":543},{"style":84},[544],{"type":37,"value":473},{"type":32,"tag":71,"props":546,"children":547},{"style":339},[548],{"type":37,"value":478},{"type":32,"tag":71,"props":550,"children":551},{"style":256},[552],{"type":37,"value":483},{"type":32,"tag":71,"props":554,"children":555},{"style":84},[556],{"type":37,"value":488},{"type":32,"tag":71,"props":558,"children":559},{"style":256},[560],{"type":37,"value":561},"int_value",{"type":32,"tag":71,"props":563,"children":564},{"style":339},[565],{"type":37,"value":375},{"type":32,"tag":71,"props":567,"children":568},{"style":84},[569],{"type":37,"value":502},{"type":32,"tag":71,"props":571,"children":572},{"style":339},[573],{"type":37,"value":507},{"type":32,"tag":71,"props":575,"children":576},{"style":339},[577],{"type":37,"value":512},{"type":32,"tag":71,"props":579,"children":580},{"style":339},[581],{"type":37,"value":517},{"type":32,"tag":71,"props":583,"children":584},{"style":109},[585],{"type":37,"value":586}," 'ga_session_number'",{"type":32,"tag":71,"props":588,"children":589},{"style":84},[590],{"type":37,"value":527},{"type":32,"tag":71,"props":592,"children":593},{"style":339},[594],{"type":37,"value":352},{"type":32,"tag":71,"props":596,"children":597},{"style":84},[598],{"type":37,"value":599}," session_number\n",{"type":32,"tag":71,"props":601,"children":603},{"class":73,"line":602},13,[604,609],{"type":32,"tag":71,"props":605,"children":606},{"style":339},[607],{"type":37,"value":608},"  from",{"type":32,"tag":71,"props":610,"children":611},{"style":84},[612],{"type":37,"value":613}," source\n",{"type":32,"tag":71,"props":615,"children":617},{"class":73,"line":616},14,[618],{"type":32,"tag":71,"props":619,"children":620},{"style":84},[621],{"type":37,"value":622},")\n",{"type":32,"tag":71,"props":624,"children":626},{"class":73,"line":625},15,[627],{"type":32,"tag":71,"props":628,"children":629},{"emptyLinePlaceholder":413},[630],{"type":37,"value":416},{"type":32,"tag":71,"props":632,"children":634},{"class":73,"line":633},16,[635,639,643,647],{"type":32,"tag":71,"props":636,"children":637},{"style":339},[638],{"type":37,"value":478},{"type":32,"tag":71,"props":640,"children":641},{"style":339},[642],{"type":37,"value":370},{"type":32,"tag":71,"props":644,"children":645},{"style":339},[646],{"type":37,"value":375},{"type":32,"tag":71,"props":648,"children":649},{"style":84},[650],{"type":37,"value":651}," flattened\n",{"type":32,"tag":33,"props":653,"children":654},{},[655,657,663],{"type":37,"value":656},"Questo modello viene ora richiamato downstream come ",{"type":32,"tag":52,"props":658,"children":660},{"className":659},[],[661],{"type":37,"value":662},"ref('stg_ga4_events')",{"type":37,"value":664}," — la sintassi raw di event_params è isolata upstream. Il freshness check gira ogni giorno, errori di schema modification vengono catturati automaticamente.",{"type":32,"tag":40,"props":666,"children":668},{"id":667},"modeling-layer-definisci-la-metrica-una-volta-usala-cento-volte",[669],{"type":37,"value":670},"Modeling layer: definisci la metrica una volta, usala cento volte",{"type":32,"tag":33,"props":672,"children":673},{},[674,676,681],{"type":37,"value":675},"Dopo il layer di staging, viene il modeling layer. Qui si separano i modelli intermedi (business logic) dai mart models (aggregazione). Nel data stack di marketing, il modello critico è il join ",{"type":32,"tag":301,"props":677,"children":678},{},[679],{"type":37,"value":680},"session → transaction",{"type":37,"value":59},{"type":32,"tag":61,"props":683,"children":685},{"className":318,"code":684,"language":320,"meta":16,"style":16},"-- models\u002Fmarts\u002Fmrt_session_metrics.sql\nwith sessions as (\n  select * from {{ ref('int_sessions') }}\n),\n\ntransactions as (\n  select * from {{ ref('int_transactions') }}\n),\n\njoined as (\n  select\n    s.session_id,\n    s.session_date,\n    s.traffic_source,\n    s.medium,\n    s.campaign,\n    t.transaction_id,\n    t.revenue,\n    t.transaction_timestamp\n  from sessions s\n  left join transactions t\n    on s.session_id = t.session_id\n)\n\nselect\n  session_date,\n  traffic_source,\n  medium,\n  campaign,\n  count(distinct session_id) as sessions,\n  count(distinct transaction_id) as transactions,\n  sum(revenue) as total_revenue,\n  safe_divide(count(distinct transaction_id), count(distinct session_id)) as conversion_rate\nfrom joined\ngroup by 1, 2, 3, 4\n",[686],{"type":32,"tag":52,"props":687,"children":688},{"__ignoreMap":16},[689,697,718,747,754,761,777,805,812,819,835,842,864,884,904,924,944,966,987,1004,1021,1035,1075,1083,1091,1100,1109,1118,1127,1136,1172,1202,1225,1277,1291],{"type":32,"tag":71,"props":690,"children":691},{"class":73,"line":74},[692],{"type":32,"tag":71,"props":693,"children":694},{"style":330},[695],{"type":37,"value":696},"-- models\u002Fmarts\u002Fmrt_session_metrics.sql\n",{"type":32,"tag":71,"props":698,"children":699},{"class":73,"line":90},[700,704,709,714],{"type":32,"tag":71,"props":701,"children":702},{"style":339},[703],{"type":37,"value":342},{"type":32,"tag":71,"props":705,"children":706},{"style":339},[707],{"type":37,"value":708}," sessions",{"type":32,"tag":71,"props":710,"children":711},{"style":339},[712],{"type":37,"value":713}," as",{"type":32,"tag":71,"props":715,"children":716},{"style":84},[717],{"type":37,"value":357},{"type":32,"tag":71,"props":719,"children":720},{"class":73,"line":115},[721,725,729,733,738,743],{"type":32,"tag":71,"props":722,"children":723},{"style":339},[724],{"type":37,"value":365},{"type":32,"tag":71,"props":726,"children":727},{"style":339},[728],{"type":37,"value":370},{"type":32,"tag":71,"props":730,"children":731},{"style":339},[732],{"type":37,"value":375},{"type":32,"tag":71,"props":734,"children":735},{"style":84},[736],{"type":37,"value":737}," {{ ref(",{"type":32,"tag":71,"props":739,"children":740},{"style":109},[741],{"type":37,"value":742},"'int_sessions'",{"type":32,"tag":71,"props":744,"children":745},{"style":84},[746],{"type":37,"value":399},{"type":32,"tag":71,"props":748,"children":749},{"class":73,"line":133},[750],{"type":32,"tag":71,"props":751,"children":752},{"style":84},[753],{"type":37,"value":407},{"type":32,"tag":71,"props":755,"children":756},{"class":73,"line":151},[757],{"type":32,"tag":71,"props":758,"children":759},{"emptyLinePlaceholder":413},[760],{"type":37,"value":416},{"type":32,"tag":71,"props":762,"children":763},{"class":73,"line":164},[764,769,773],{"type":32,"tag":71,"props":765,"children":766},{"style":84},[767],{"type":37,"value":768},"transactions ",{"type":32,"tag":71,"props":770,"children":771},{"style":339},[772],{"type":37,"value":352},{"type":32,"tag":71,"props":774,"children":775},{"style":84},[776],{"type":37,"value":357},{"type":32,"tag":71,"props":778,"children":779},{"class":73,"line":186},[780,784,788,792,796,801],{"type":32,"tag":71,"props":781,"children":782},{"style":339},[783],{"type":37,"value":365},{"type":32,"tag":71,"props":785,"children":786},{"style":339},[787],{"type":37,"value":370},{"type":32,"tag":71,"props":789,"children":790},{"style":339},[791],{"type":37,"value":375},{"type":32,"tag":71,"props":793,"children":794},{"style":84},[795],{"type":37,"value":737},{"type":32,"tag":71,"props":797,"children":798},{"style":109},[799],{"type":37,"value":800},"'int_transactions'",{"type":32,"tag":71,"props":802,"children":803},{"style":84},[804],{"type":37,"value":399},{"type":32,"tag":71,"props":806,"children":807},{"class":73,"line":203},[808],{"type":32,"tag":71,"props":809,"children":810},{"style":84},[811],{"type":37,"value":407},{"type":32,"tag":71,"props":813,"children":814},{"class":73,"line":26},[815],{"type":32,"tag":71,"props":816,"children":817},{"emptyLinePlaceholder":413},[818],{"type":37,"value":416},{"type":32,"tag":71,"props":820,"children":821},{"class":73,"line":233},[822,827,831],{"type":32,"tag":71,"props":823,"children":824},{"style":84},[825],{"type":37,"value":826},"joined ",{"type":32,"tag":71,"props":828,"children":829},{"style":339},[830],{"type":37,"value":352},{"type":32,"tag":71,"props":832,"children":833},{"style":84},[834],{"type":37,"value":357},{"type":32,"tag":71,"props":836,"children":837},{"class":73,"line":467},[838],{"type":32,"tag":71,"props":839,"children":840},{"style":339},[841],{"type":37,"value":440},{"type":32,"tag":71,"props":843,"children":844},{"class":73,"line":539},[845,850,854,859],{"type":32,"tag":71,"props":846,"children":847},{"style":256},[848],{"type":37,"value":849},"    s",{"type":32,"tag":71,"props":851,"children":852},{"style":84},[853],{"type":37,"value":488},{"type":32,"tag":71,"props":855,"children":856},{"style":256},[857],{"type":37,"value":858},"session_id",{"type":32,"tag":71,"props":860,"children":861},{"style":84},[862],{"type":37,"value":863},",\n",{"type":32,"tag":71,"props":865,"children":866},{"class":73,"line":602},[867,871,875,880],{"type":32,"tag":71,"props":868,"children":869},{"style":256},[870],{"type":37,"value":849},{"type":32,"tag":71,"props":872,"children":873},{"style":84},[874],{"type":37,"value":488},{"type":32,"tag":71,"props":876,"children":877},{"style":256},[878],{"type":37,"value":879},"session_date",{"type":32,"tag":71,"props":881,"children":882},{"style":84},[883],{"type":37,"value":863},{"type":32,"tag":71,"props":885,"children":886},{"class":73,"line":616},[887,891,895,900],{"type":32,"tag":71,"props":888,"children":889},{"style":256},[890],{"type":37,"value":849},{"type":32,"tag":71,"props":892,"children":893},{"style":84},[894],{"type":37,"value":488},{"type":32,"tag":71,"props":896,"children":897},{"style":256},[898],{"type":37,"value":899},"traffic_source",{"type":32,"tag":71,"props":901,"children":902},{"style":84},[903],{"type":37,"value":863},{"type":32,"tag":71,"props":905,"children":906},{"class":73,"line":625},[907,911,915,920],{"type":32,"tag":71,"props":908,"children":909},{"style":256},[910],{"type":37,"value":849},{"type":32,"tag":71,"props":912,"children":913},{"style":84},[914],{"type":37,"value":488},{"type":32,"tag":71,"props":916,"children":917},{"style":256},[918],{"type":37,"value":919},"medium",{"type":32,"tag":71,"props":921,"children":922},{"style":84},[923],{"type":37,"value":863},{"type":32,"tag":71,"props":925,"children":926},{"class":73,"line":633},[927,931,935,940],{"type":32,"tag":71,"props":928,"children":929},{"style":256},[930],{"type":37,"value":849},{"type":32,"tag":71,"props":932,"children":933},{"style":84},[934],{"type":37,"value":488},{"type":32,"tag":71,"props":936,"children":937},{"style":256},[938],{"type":37,"value":939},"campaign",{"type":32,"tag":71,"props":941,"children":942},{"style":84},[943],{"type":37,"value":863},{"type":32,"tag":71,"props":945,"children":947},{"class":73,"line":946},17,[948,953,957,962],{"type":32,"tag":71,"props":949,"children":950},{"style":256},[951],{"type":37,"value":952},"    t",{"type":32,"tag":71,"props":954,"children":955},{"style":84},[956],{"type":37,"value":488},{"type":32,"tag":71,"props":958,"children":959},{"style":256},[960],{"type":37,"value":961},"transaction_id",{"type":32,"tag":71,"props":963,"children":964},{"style":84},[965],{"type":37,"value":863},{"type":32,"tag":71,"props":967,"children":969},{"class":73,"line":968},18,[970,974,978,983],{"type":32,"tag":71,"props":971,"children":972},{"style":256},[973],{"type":37,"value":952},{"type":32,"tag":71,"props":975,"children":976},{"style":84},[977],{"type":37,"value":488},{"type":32,"tag":71,"props":979,"children":980},{"style":256},[981],{"type":37,"value":982},"revenue",{"type":32,"tag":71,"props":984,"children":985},{"style":84},[986],{"type":37,"value":863},{"type":32,"tag":71,"props":988,"children":990},{"class":73,"line":989},19,[991,995,999],{"type":32,"tag":71,"props":992,"children":993},{"style":256},[994],{"type":37,"value":952},{"type":32,"tag":71,"props":996,"children":997},{"style":84},[998],{"type":37,"value":488},{"type":32,"tag":71,"props":1000,"children":1001},{"style":256},[1002],{"type":37,"value":1003},"transaction_timestamp\n",{"type":32,"tag":71,"props":1005,"children":1007},{"class":73,"line":1006},20,[1008,1012,1016],{"type":32,"tag":71,"props":1009,"children":1010},{"style":339},[1011],{"type":37,"value":608},{"type":32,"tag":71,"props":1013,"children":1014},{"style":339},[1015],{"type":37,"value":708},{"type":32,"tag":71,"props":1017,"children":1018},{"style":84},[1019],{"type":37,"value":1020}," s\n",{"type":32,"tag":71,"props":1022,"children":1024},{"class":73,"line":1023},21,[1025,1030],{"type":32,"tag":71,"props":1026,"children":1027},{"style":339},[1028],{"type":37,"value":1029},"  left join",{"type":32,"tag":71,"props":1031,"children":1032},{"style":84},[1033],{"type":37,"value":1034}," transactions t\n",{"type":32,"tag":71,"props":1036,"children":1038},{"class":73,"line":1037},22,[1039,1044,1049,1053,1057,1061,1066,1070],{"type":32,"tag":71,"props":1040,"children":1041},{"style":339},[1042],{"type":37,"value":1043},"    on",{"type":32,"tag":71,"props":1045,"children":1046},{"style":256},[1047],{"type":37,"value":1048}," s",{"type":32,"tag":71,"props":1050,"children":1051},{"style":84},[1052],{"type":37,"value":488},{"type":32,"tag":71,"props":1054,"children":1055},{"style":256},[1056],{"type":37,"value":858},{"type":32,"tag":71,"props":1058,"children":1059},{"style":339},[1060],{"type":37,"value":517},{"type":32,"tag":71,"props":1062,"children":1063},{"style":256},[1064],{"type":37,"value":1065}," t",{"type":32,"tag":71,"props":1067,"children":1068},{"style":84},[1069],{"type":37,"value":488},{"type":32,"tag":71,"props":1071,"children":1072},{"style":256},[1073],{"type":37,"value":1074},"session_id\n",{"type":32,"tag":71,"props":1076,"children":1078},{"class":73,"line":1077},23,[1079],{"type":32,"tag":71,"props":1080,"children":1081},{"style":84},[1082],{"type":37,"value":622},{"type":32,"tag":71,"props":1084,"children":1086},{"class":73,"line":1085},24,[1087],{"type":32,"tag":71,"props":1088,"children":1089},{"emptyLinePlaceholder":413},[1090],{"type":37,"value":416},{"type":32,"tag":71,"props":1092,"children":1094},{"class":73,"line":1093},25,[1095],{"type":32,"tag":71,"props":1096,"children":1097},{"style":339},[1098],{"type":37,"value":1099},"select\n",{"type":32,"tag":71,"props":1101,"children":1103},{"class":73,"line":1102},26,[1104],{"type":32,"tag":71,"props":1105,"children":1106},{"style":84},[1107],{"type":37,"value":1108},"  session_date,\n",{"type":32,"tag":71,"props":1110,"children":1112},{"class":73,"line":1111},27,[1113],{"type":32,"tag":71,"props":1114,"children":1115},{"style":84},[1116],{"type":37,"value":1117},"  traffic_source,\n",{"type":32,"tag":71,"props":1119,"children":1121},{"class":73,"line":1120},28,[1122],{"type":32,"tag":71,"props":1123,"children":1124},{"style":84},[1125],{"type":37,"value":1126},"  medium,\n",{"type":32,"tag":71,"props":1128,"children":1130},{"class":73,"line":1129},29,[1131],{"type":32,"tag":71,"props":1132,"children":1133},{"style":84},[1134],{"type":37,"value":1135},"  campaign,\n",{"type":32,"tag":71,"props":1137,"children":1139},{"class":73,"line":1138},30,[1140,1145,1150,1155,1160,1164,1168],{"type":32,"tag":71,"props":1141,"children":1142},{"style":256},[1143],{"type":37,"value":1144},"  count",{"type":32,"tag":71,"props":1146,"children":1147},{"style":84},[1148],{"type":37,"value":1149},"(",{"type":32,"tag":71,"props":1151,"children":1152},{"style":339},[1153],{"type":37,"value":1154},"distinct",{"type":32,"tag":71,"props":1156,"children":1157},{"style":84},[1158],{"type":37,"value":1159}," session_id) ",{"type":32,"tag":71,"props":1161,"children":1162},{"style":339},[1163],{"type":37,"value":352},{"type":32,"tag":71,"props":1165,"children":1166},{"style":339},[1167],{"type":37,"value":708},{"type":32,"tag":71,"props":1169,"children":1170},{"style":84},[1171],{"type":37,"value":863},{"type":32,"tag":71,"props":1173,"children":1175},{"class":73,"line":1174},31,[1176,1180,1184,1188,1193,1197],{"type":32,"tag":71,"props":1177,"children":1178},{"style":256},[1179],{"type":37,"value":1144},{"type":32,"tag":71,"props":1181,"children":1182},{"style":84},[1183],{"type":37,"value":1149},{"type":32,"tag":71,"props":1185,"children":1186},{"style":339},[1187],{"type":37,"value":1154},{"type":32,"tag":71,"props":1189,"children":1190},{"style":84},[1191],{"type":37,"value":1192}," transaction_id) ",{"type":32,"tag":71,"props":1194,"children":1195},{"style":339},[1196],{"type":37,"value":352},{"type":32,"tag":71,"props":1198,"children":1199},{"style":84},[1200],{"type":37,"value":1201}," transactions,\n",{"type":32,"tag":71,"props":1203,"children":1205},{"class":73,"line":1204},32,[1206,1211,1216,1220],{"type":32,"tag":71,"props":1207,"children":1208},{"style":256},[1209],{"type":37,"value":1210},"  sum",{"type":32,"tag":71,"props":1212,"children":1213},{"style":84},[1214],{"type":37,"value":1215},"(revenue) ",{"type":32,"tag":71,"props":1217,"children":1218},{"style":339},[1219],{"type":37,"value":352},{"type":32,"tag":71,"props":1221,"children":1222},{"style":84},[1223],{"type":37,"value":1224}," total_revenue,\n",{"type":32,"tag":71,"props":1226,"children":1228},{"class":73,"line":1227},33,[1229,1234,1238,1242,1246,1251,1255,1259,1263,1268,1272],{"type":32,"tag":71,"props":1230,"children":1231},{"style":84},[1232],{"type":37,"value":1233},"  safe_divide(",{"type":32,"tag":71,"props":1235,"children":1236},{"style":256},[1237],{"type":37,"value":249},{"type":32,"tag":71,"props":1239,"children":1240},{"style":84},[1241],{"type":37,"value":1149},{"type":32,"tag":71,"props":1243,"children":1244},{"style":339},[1245],{"type":37,"value":1154},{"type":32,"tag":71,"props":1247,"children":1248},{"style":84},[1249],{"type":37,"value":1250}," transaction_id), ",{"type":32,"tag":71,"props":1252,"children":1253},{"style":256},[1254],{"type":37,"value":249},{"type":32,"tag":71,"props":1256,"children":1257},{"style":84},[1258],{"type":37,"value":1149},{"type":32,"tag":71,"props":1260,"children":1261},{"style":339},[1262],{"type":37,"value":1154},{"type":32,"tag":71,"props":1264,"children":1265},{"style":84},[1266],{"type":37,"value":1267}," session_id)) ",{"type":32,"tag":71,"props":1269,"children":1270},{"style":339},[1271],{"type":37,"value":352},{"type":32,"tag":71,"props":1273,"children":1274},{"style":84},[1275],{"type":37,"value":1276}," conversion_rate\n",{"type":32,"tag":71,"props":1278,"children":1280},{"class":73,"line":1279},34,[1281,1286],{"type":32,"tag":71,"props":1282,"children":1283},{"style":339},[1284],{"type":37,"value":1285},"from",{"type":32,"tag":71,"props":1287,"children":1288},{"style":84},[1289],{"type":37,"value":1290}," joined\n",{"type":32,"tag":71,"props":1292,"children":1294},{"class":73,"line":1293},35,[1295,1300,1305,1309,1314,1318,1323,1327],{"type":32,"tag":71,"props":1296,"children":1297},{"style":339},[1298],{"type":37,"value":1299},"group by",{"type":32,"tag":71,"props":1301,"children":1302},{"style":256},[1303],{"type":37,"value":1304}," 1",{"type":32,"tag":71,"props":1306,"children":1307},{"style":84},[1308],{"type":37,"value":264},{"type":32,"tag":71,"props":1310,"children":1311},{"style":256},[1312],{"type":37,"value":1313},"2",{"type":32,"tag":71,"props":1315,"children":1316},{"style":84},[1317],{"type":37,"value":264},{"type":32,"tag":71,"props":1319,"children":1320},{"style":256},[1321],{"type":37,"value":1322},"3",{"type":32,"tag":71,"props":1324,"children":1325},{"style":84},[1326],{"type":37,"value":264},{"type":32,"tag":71,"props":1328,"children":1329},{"style":256},[1330],{"type":37,"value":1331},"4\n",{"type":32,"tag":33,"props":1333,"children":1334},{},[1335],{"type":37,"value":1336},"Questo modello gira ogni giorno alle 03:00 (dbt Cloud scheduler), Looker Studio si connette direttamente a questa tabella. Quando è necessario fare modifiche, cambi l'SQL in un'unica posizione e tutti i dashboard si aggiornano automaticamente.",{"type":32,"tag":33,"props":1338,"children":1339},{},[1340,1345,1347,1353],{"type":32,"tag":301,"props":1341,"children":1342},{},[1343],{"type":37,"value":1344},"Dettaglio importante:",{"type":37,"value":1346}," l'uso di ",{"type":32,"tag":52,"props":1348,"children":1350},{"className":1349},[],[1351],{"type":37,"value":1352},"safe_divide",{"type":37,"value":1354}," — se sessions = 0, non genera un errore di divisione per zero, ma ritorna null. La gestione delle eccezioni in una production pipeline avviene a questo livello.",{"type":32,"tag":1356,"props":1357,"children":1359},"h3",{"id":1358},"dbt-tests-verifica-della-qualità-dati-automatica",[1360],{"type":37,"value":1361},"dbt tests: verifica della qualità dati automatica",{"type":32,"tag":33,"props":1363,"children":1364},{},[1365],{"type":37,"value":1366},"Mentre definisci le metriche nel modeling layer, scrivi anche i test:",{"type":32,"tag":61,"props":1368,"children":1370},{"className":63,"code":1369,"language":65,"meta":16,"style":16},"# models\u002Fmarts\u002Fschema.yml\nmodels:\n  - name: mrt_session_metrics\n    columns:\n      - name: session_date\n        tests:\n          - not_null\n      - name: sessions\n        tests:\n          - not_null\n          - dbt_utils.expression_is_true:\n              expression: \">= 0\"\n      - name: conversion_rate\n        tests:\n          - dbt_utils.expression_is_true:\n              expression: \"\u003C= 1\"\n",[1371],{"type":32,"tag":52,"props":1372,"children":1373},{"__ignoreMap":16},[1374,1382,1394,1414,1426,1446,1458,1471,1491,1502,1513,1529,1546,1566,1577,1592],{"type":32,"tag":71,"props":1375,"children":1376},{"class":73,"line":74},[1377],{"type":32,"tag":71,"props":1378,"children":1379},{"style":330},[1380],{"type":37,"value":1381},"# models\u002Fmarts\u002Fschema.yml\n",{"type":32,"tag":71,"props":1383,"children":1384},{"class":73,"line":90},[1385,1390],{"type":32,"tag":71,"props":1386,"children":1387},{"style":78},[1388],{"type":37,"value":1389},"models",{"type":32,"tag":71,"props":1391,"children":1392},{"style":84},[1393],{"type":37,"value":87},{"type":32,"tag":71,"props":1395,"children":1396},{"class":73,"line":115},[1397,1401,1405,1409],{"type":32,"tag":71,"props":1398,"children":1399},{"style":84},[1400],{"type":37,"value":96},{"type":32,"tag":71,"props":1402,"children":1403},{"style":78},[1404],{"type":37,"value":101},{"type":32,"tag":71,"props":1406,"children":1407},{"style":84},[1408],{"type":37,"value":106},{"type":32,"tag":71,"props":1410,"children":1411},{"style":109},[1412],{"type":37,"value":1413},"mrt_session_metrics\n",{"type":32,"tag":71,"props":1415,"children":1416},{"class":73,"line":133},[1417,1422],{"type":32,"tag":71,"props":1418,"children":1419},{"style":78},[1420],{"type":37,"value":1421},"    columns",{"type":32,"tag":71,"props":1423,"children":1424},{"style":84},[1425],{"type":37,"value":87},{"type":32,"tag":71,"props":1427,"children":1428},{"class":73,"line":151},[1429,1433,1437,1441],{"type":32,"tag":71,"props":1430,"children":1431},{"style":84},[1432],{"type":37,"value":170},{"type":32,"tag":71,"props":1434,"children":1435},{"style":78},[1436],{"type":37,"value":101},{"type":32,"tag":71,"props":1438,"children":1439},{"style":84},[1440],{"type":37,"value":106},{"type":32,"tag":71,"props":1442,"children":1443},{"style":109},[1444],{"type":37,"value":1445},"session_date\n",{"type":32,"tag":71,"props":1447,"children":1448},{"class":73,"line":164},[1449,1454],{"type":32,"tag":71,"props":1450,"children":1451},{"style":78},[1452],{"type":37,"value":1453},"        tests",{"type":32,"tag":71,"props":1455,"children":1456},{"style":84},[1457],{"type":37,"value":87},{"type":32,"tag":71,"props":1459,"children":1460},{"class":73,"line":186},[1461,1466],{"type":32,"tag":71,"props":1462,"children":1463},{"style":84},[1464],{"type":37,"value":1465},"          - ",{"type":32,"tag":71,"props":1467,"children":1468},{"style":109},[1469],{"type":37,"value":1470},"not_null\n",{"type":32,"tag":71,"props":1472,"children":1473},{"class":73,"line":203},[1474,1478,1482,1486],{"type":32,"tag":71,"props":1475,"children":1476},{"style":84},[1477],{"type":37,"value":170},{"type":32,"tag":71,"props":1479,"children":1480},{"style":78},[1481],{"type":37,"value":101},{"type":32,"tag":71,"props":1483,"children":1484},{"style":84},[1485],{"type":37,"value":106},{"type":32,"tag":71,"props":1487,"children":1488},{"style":109},[1489],{"type":37,"value":1490},"sessions\n",{"type":32,"tag":71,"props":1492,"children":1493},{"class":73,"line":26},[1494,1498],{"type":32,"tag":71,"props":1495,"children":1496},{"style":78},[1497],{"type":37,"value":1453},{"type":32,"tag":71,"props":1499,"children":1500},{"style":84},[1501],{"type":37,"value":87},{"type":32,"tag":71,"props":1503,"children":1504},{"class":73,"line":233},[1505,1509],{"type":32,"tag":71,"props":1506,"children":1507},{"style":84},[1508],{"type":37,"value":1465},{"type":32,"tag":71,"props":1510,"children":1511},{"style":109},[1512],{"type":37,"value":1470},{"type":32,"tag":71,"props":1514,"children":1515},{"class":73,"line":467},[1516,1520,1525],{"type":32,"tag":71,"props":1517,"children":1518},{"style":84},[1519],{"type":37,"value":1465},{"type":32,"tag":71,"props":1521,"children":1522},{"style":78},[1523],{"type":37,"value":1524},"dbt_utils.expression_is_true",{"type":32,"tag":71,"props":1526,"children":1527},{"style":84},[1528],{"type":37,"value":87},{"type":32,"tag":71,"props":1530,"children":1531},{"class":73,"line":539},[1532,1537,1541],{"type":32,"tag":71,"props":1533,"children":1534},{"style":78},[1535],{"type":37,"value":1536},"              expression",{"type":32,"tag":71,"props":1538,"children":1539},{"style":84},[1540],{"type":37,"value":106},{"type":32,"tag":71,"props":1542,"children":1543},{"style":109},[1544],{"type":37,"value":1545},"\">= 0\"\n",{"type":32,"tag":71,"props":1547,"children":1548},{"class":73,"line":602},[1549,1553,1557,1561],{"type":32,"tag":71,"props":1550,"children":1551},{"style":84},[1552],{"type":37,"value":170},{"type":32,"tag":71,"props":1554,"children":1555},{"style":78},[1556],{"type":37,"value":101},{"type":32,"tag":71,"props":1558,"children":1559},{"style":84},[1560],{"type":37,"value":106},{"type":32,"tag":71,"props":1562,"children":1563},{"style":109},[1564],{"type":37,"value":1565},"conversion_rate\n",{"type":32,"tag":71,"props":1567,"children":1568},{"class":73,"line":616},[1569,1573],{"type":32,"tag":71,"props":1570,"children":1571},{"style":78},[1572],{"type":37,"value":1453},{"type":32,"tag":71,"props":1574,"children":1575},{"style":84},[1576],{"type":37,"value":87},{"type":32,"tag":71,"props":1578,"children":1579},{"class":73,"line":625},[1580,1584,1588],{"type":32,"tag":71,"props":1581,"children":1582},{"style":84},[1583],{"type":37,"value":1465},{"type":32,"tag":71,"props":1585,"children":1586},{"style":78},[1587],{"type":37,"value":1524},{"type":32,"tag":71,"props":1589,"children":1590},{"style":84},[1591],{"type":37,"value":87},{"type":32,"tag":71,"props":1593,"children":1594},{"class":73,"line":633},[1595,1599,1603],{"type":32,"tag":71,"props":1596,"children":1597},{"style":78},[1598],{"type":37,"value":1536},{"type":32,"tag":71,"props":1600,"children":1601},{"style":84},[1602],{"type":37,"value":106},{"type":32,"tag":71,"props":1604,"children":1605},{"style":109},[1606],{"type":37,"value":1607},"\"\u003C= 1\"\n",{"type":32,"tag":33,"props":1609,"children":1610},{},[1611,1613,1619],{"type":37,"value":1612},"Il comando ",{"type":32,"tag":52,"props":1614,"children":1616},{"className":1615},[],[1617],{"type":37,"value":1618},"dbt test",{"type":37,"value":1620}," esegue queste regole. Se il conversion rate > 1 (significa che c'è un errore SQL), il build fallisce e un alert viene inviato a Slack. Invece di QA manuale, ottieni controllo di qualità dei dati automatizzato — il resto dello stack dati è costruito su questa base solida.",{"type":32,"tag":40,"props":1622,"children":1624},{"id":1623},"semantic-layer-definisci-la-metrica-non-la-query",[1625],{"type":37,"value":1626},"Semantic layer: definisci la metrica, non la query",{"type":32,"tag":33,"props":1628,"children":1629},{},[1630,1632,1637],{"type":37,"value":1631},"Con dbt v1.6+, il semantic layer è uscito dalla fase beta. Ora definisci la metrica in un file ",{"type":32,"tag":52,"props":1633,"children":1635},{"className":1634},[],[1636],{"type":37,"value":57},{"type":37,"value":1638},", non in SQL:",{"type":32,"tag":61,"props":1640,"children":1642},{"className":63,"code":1641,"language":65,"meta":16,"style":16},"# models\u002Fsemantic\u002Fmetrics.yml\nmetrics:\n  - name: total_revenue\n    label: Total Revenue\n    model: ref('mrt_session_metrics')\n    type: sum\n    sql: total_revenue\n    timestamp: session_date\n    time_grains: [day, week, month]\n\n  - name: roas\n    label: Return on Ad Spend\n    type: ratio\n    numerator: total_revenue\n    denominator: total_ad_spend\n",[1643],{"type":32,"tag":52,"props":1644,"children":1645},{"__ignoreMap":16},[1646,1654,1666,1686,1703,1720,1737,1753,1769,1810,1817,1837,1853,1869,1885],{"type":32,"tag":71,"props":1647,"children":1648},{"class":73,"line":74},[1649],{"type":32,"tag":71,"props":1650,"children":1651},{"style":330},[1652],{"type":37,"value":1653},"# models\u002Fsemantic\u002Fmetrics.yml\n",{"type":32,"tag":71,"props":1655,"children":1656},{"class":73,"line":90},[1657,1662],{"type":32,"tag":71,"props":1658,"children":1659},{"style":78},[1660],{"type":37,"value":1661},"metrics",{"type":32,"tag":71,"props":1663,"children":1664},{"style":84},[1665],{"type":37,"value":87},{"type":32,"tag":71,"props":1667,"children":1668},{"class":73,"line":115},[1669,1673,1677,1681],{"type":32,"tag":71,"props":1670,"children":1671},{"style":84},[1672],{"type":37,"value":96},{"type":32,"tag":71,"props":1674,"children":1675},{"style":78},[1676],{"type":37,"value":101},{"type":32,"tag":71,"props":1678,"children":1679},{"style":84},[1680],{"type":37,"value":106},{"type":32,"tag":71,"props":1682,"children":1683},{"style":109},[1684],{"type":37,"value":1685},"total_revenue\n",{"type":32,"tag":71,"props":1687,"children":1688},{"class":73,"line":133},[1689,1694,1698],{"type":32,"tag":71,"props":1690,"children":1691},{"style":78},[1692],{"type":37,"value":1693},"    label",{"type":32,"tag":71,"props":1695,"children":1696},{"style":84},[1697],{"type":37,"value":106},{"type":32,"tag":71,"props":1699,"children":1700},{"style":109},[1701],{"type":37,"value":1702},"Total Revenue\n",{"type":32,"tag":71,"props":1704,"children":1705},{"class":73,"line":151},[1706,1711,1715],{"type":32,"tag":71,"props":1707,"children":1708},{"style":78},[1709],{"type":37,"value":1710},"    model",{"type":32,"tag":71,"props":1712,"children":1713},{"style":84},[1714],{"type":37,"value":106},{"type":32,"tag":71,"props":1716,"children":1717},{"style":109},[1718],{"type":37,"value":1719},"ref('mrt_session_metrics')\n",{"type":32,"tag":71,"props":1721,"children":1722},{"class":73,"line":164},[1723,1728,1732],{"type":32,"tag":71,"props":1724,"children":1725},{"style":78},[1726],{"type":37,"value":1727},"    type",{"type":32,"tag":71,"props":1729,"children":1730},{"style":84},[1731],{"type":37,"value":106},{"type":32,"tag":71,"props":1733,"children":1734},{"style":109},[1735],{"type":37,"value":1736},"sum\n",{"type":32,"tag":71,"props":1738,"children":1739},{"class":73,"line":186},[1740,1745,1749],{"type":32,"tag":71,"props":1741,"children":1742},{"style":78},[1743],{"type":37,"value":1744},"    sql",{"type":32,"tag":71,"props":1746,"children":1747},{"style":84},[1748],{"type":37,"value":106},{"type":32,"tag":71,"props":1750,"children":1751},{"style":109},[1752],{"type":37,"value":1685},{"type":32,"tag":71,"props":1754,"children":1755},{"class":73,"line":203},[1756,1761,1765],{"type":32,"tag":71,"props":1757,"children":1758},{"style":78},[1759],{"type":37,"value":1760},"    timestamp",{"type":32,"tag":71,"props":1762,"children":1763},{"style":84},[1764],{"type":37,"value":106},{"type":32,"tag":71,"props":1766,"children":1767},{"style":109},[1768],{"type":37,"value":1445},{"type":32,"tag":71,"props":1770,"children":1771},{"class":73,"line":26},[1772,1777,1782,1787,1791,1796,1800,1805],{"type":32,"tag":71,"props":1773,"children":1774},{"style":78},[1775],{"type":37,"value":1776},"    time_grains",{"type":32,"tag":71,"props":1778,"children":1779},{"style":84},[1780],{"type":37,"value":1781},": [",{"type":32,"tag":71,"props":1783,"children":1784},{"style":109},[1785],{"type":37,"value":1786},"day",{"type":32,"tag":71,"props":1788,"children":1789},{"style":84},[1790],{"type":37,"value":264},{"type":32,"tag":71,"props":1792,"children":1793},{"style":109},[1794],{"type":37,"value":1795},"week",{"type":32,"tag":71,"props":1797,"children":1798},{"style":84},[1799],{"type":37,"value":264},{"type":32,"tag":71,"props":1801,"children":1802},{"style":109},[1803],{"type":37,"value":1804},"month",{"type":32,"tag":71,"props":1806,"children":1807},{"style":84},[1808],{"type":37,"value":1809},"]\n",{"type":32,"tag":71,"props":1811,"children":1812},{"class":73,"line":233},[1813],{"type":32,"tag":71,"props":1814,"children":1815},{"emptyLinePlaceholder":413},[1816],{"type":37,"value":416},{"type":32,"tag":71,"props":1818,"children":1819},{"class":73,"line":467},[1820,1824,1828,1832],{"type":32,"tag":71,"props":1821,"children":1822},{"style":84},[1823],{"type":37,"value":96},{"type":32,"tag":71,"props":1825,"children":1826},{"style":78},[1827],{"type":37,"value":101},{"type":32,"tag":71,"props":1829,"children":1830},{"style":84},[1831],{"type":37,"value":106},{"type":32,"tag":71,"props":1833,"children":1834},{"style":109},[1835],{"type":37,"value":1836},"roas\n",{"type":32,"tag":71,"props":1838,"children":1839},{"class":73,"line":539},[1840,1844,1848],{"type":32,"tag":71,"props":1841,"children":1842},{"style":78},[1843],{"type":37,"value":1693},{"type":32,"tag":71,"props":1845,"children":1846},{"style":84},[1847],{"type":37,"value":106},{"type":32,"tag":71,"props":1849,"children":1850},{"style":109},[1851],{"type":37,"value":1852},"Return on Ad Spend\n",{"type":32,"tag":71,"props":1854,"children":1855},{"class":73,"line":602},[1856,1860,1864],{"type":32,"tag":71,"props":1857,"children":1858},{"style":78},[1859],{"type":37,"value":1727},{"type":32,"tag":71,"props":1861,"children":1862},{"style":84},[1863],{"type":37,"value":106},{"type":32,"tag":71,"props":1865,"children":1866},{"style":109},[1867],{"type":37,"value":1868},"ratio\n",{"type":32,"tag":71,"props":1870,"children":1871},{"class":73,"line":616},[1872,1877,1881],{"type":32,"tag":71,"props":1873,"children":1874},{"style":78},[1875],{"type":37,"value":1876},"    numerator",{"type":32,"tag":71,"props":1878,"children":1879},{"style":84},[1880],{"type":37,"value":106},{"type":32,"tag":71,"props":1882,"children":1883},{"style":109},[1884],{"type":37,"value":1685},{"type":32,"tag":71,"props":1886,"children":1887},{"class":73,"line":625},[1888,1893,1897],{"type":32,"tag":71,"props":1889,"children":1890},{"style":78},[1891],{"type":37,"value":1892},"    denominator",{"type":32,"tag":71,"props":1894,"children":1895},{"style":84},[1896],{"type":37,"value":106},{"type":32,"tag":71,"props":1898,"children":1899},{"style":109},[1900],{"type":37,"value":1901},"total_ad_spend\n",{"type":32,"tag":33,"props":1903,"children":1904},{},[1905],{"type":37,"value":1906},"Questa definizione viene utilizzata in tre contesti: (1) Looker Studio, (2) Slack bot che interroga la dbt Cloud discovery API per metriche, (3) DAG Airflow con input a pipeline ML downstream.",{"type":32,"tag":33,"props":1908,"children":1909},{},[1910,1915],{"type":32,"tag":301,"props":1911,"children":1912},{},[1913],{"type":37,"value":1914},"Il vantaggio:",{"type":37,"value":1916}," le metriche sono consumabili senza scrivere SQL. L'analyst di marketing non conosce il SQL e scrive \"Show me ROAS by campaign, last 7 days\" — il semantic layer di dbt compila automaticamente la query. La logica SQL sta nel modeling layer, la definizione della metrica nel semantic layer — sono separate e i cambiamenti sono isolati.",{"type":32,"tag":33,"props":1918,"children":1919},{},[1920,1925],{"type":32,"tag":301,"props":1921,"children":1922},{},[1923],{"type":37,"value":1924},"Attenzione:",{"type":37,"value":1926}," il semantic layer è ancora nuovo — non tutti gli strumenti BI hanno integrazione nativa. In Roibase usiamo un approccio ibrido: le metriche critiche nel semantic layer, gli analytics personalizzati tramite SQL exposure.",{"type":32,"tag":1356,"props":1928,"children":1930},{"id":1929},"exposures-documenta-le-dipendenze-downstream",[1931],{"type":37,"value":1932},"Exposures: documenta le dipendenze downstream",{"type":32,"tag":33,"props":1934,"children":1935},{},[1936],{"type":37,"value":1937},"Gli exposure mostrano dove un modello dbt viene utilizzato al di fuori:",{"type":32,"tag":61,"props":1939,"children":1941},{"className":63,"code":1940,"language":65,"meta":16,"style":16},"# models\u002Fexposures.yml\nexposures:\n  - name: looker_studio_performance_dashboard\n    type: dashboard\n    url: https:\u002F\u002Flookerstudio.google.com\u002F...\n    depends_on:\n      - ref('mrt_session_metrics')\n      - ref('mrt_campaign_performance')\n    owner:\n      name: Marketing Analytics Team\n      email: analytics@roibase.com.tr\n",[1942],{"type":32,"tag":52,"props":1943,"children":1944},{"__ignoreMap":16},[1945,1953,1965,1985,2001,2018,2030,2041,2053,2065,2082],{"type":32,"tag":71,"props":1946,"children":1947},{"class":73,"line":74},[1948],{"type":32,"tag":71,"props":1949,"children":1950},{"style":330},[1951],{"type":37,"value":1952},"# models\u002Fexposures.yml\n",{"type":32,"tag":71,"props":1954,"children":1955},{"class":73,"line":90},[1956,1961],{"type":32,"tag":71,"props":1957,"children":1958},{"style":78},[1959],{"type":37,"value":1960},"exposures",{"type":32,"tag":71,"props":1962,"children":1963},{"style":84},[1964],{"type":37,"value":87},{"type":32,"tag":71,"props":1966,"children":1967},{"class":73,"line":115},[1968,1972,1976,1980],{"type":32,"tag":71,"props":1969,"children":1970},{"style":84},[1971],{"type":37,"value":96},{"type":32,"tag":71,"props":1973,"children":1974},{"style":78},[1975],{"type":37,"value":101},{"type":32,"tag":71,"props":1977,"children":1978},{"style":84},[1979],{"type":37,"value":106},{"type":32,"tag":71,"props":1981,"children":1982},{"style":109},[1983],{"type":37,"value":1984},"looker_studio_performance_dashboard\n",{"type":32,"tag":71,"props":1986,"children":1987},{"class":73,"line":133},[1988,1992,1996],{"type":32,"tag":71,"props":1989,"children":1990},{"style":78},[1991],{"type":37,"value":1727},{"type":32,"tag":71,"props":1993,"children":1994},{"style":84},[1995],{"type":37,"value":106},{"type":32,"tag":71,"props":1997,"children":1998},{"style":109},[1999],{"type":37,"value":2000},"dashboard\n",{"type":32,"tag":71,"props":2002,"children":2003},{"class":73,"line":151},[2004,2009,2013],{"type":32,"tag":71,"props":2005,"children":2006},{"style":78},[2007],{"type":37,"value":2008},"    url",{"type":32,"tag":71,"props":2010,"children":2011},{"style":84},[2012],{"type":37,"value":106},{"type":32,"tag":71,"props":2014,"children":2015},{"style":109},[2016],{"type":37,"value":2017},"https:\u002F\u002Flookerstudio.google.com\u002F...\n",{"type":32,"tag":71,"props":2019,"children":2020},{"class":73,"line":164},[2021,2026],{"type":32,"tag":71,"props":2022,"children":2023},{"style":78},[2024],{"type":37,"value":2025},"    depends_on",{"type":32,"tag":71,"props":2027,"children":2028},{"style":84},[2029],{"type":37,"value":87},{"type":32,"tag":71,"props":2031,"children":2032},{"class":73,"line":186},[2033,2037],{"type":32,"tag":71,"props":2034,"children":2035},{"style":84},[2036],{"type":37,"value":170},{"type":32,"tag":71,"props":2038,"children":2039},{"style":109},[2040],{"type":37,"value":1719},{"type":32,"tag":71,"props":2042,"children":2043},{"class":73,"line":203},[2044,2048],{"type":32,"tag":71,"props":2045,"children":2046},{"style":84},[2047],{"type":37,"value":170},{"type":32,"tag":71,"props":2049,"children":2050},{"style":109},[2051],{"type":37,"value":2052},"ref('mrt_campaign_performance')\n",{"type":32,"tag":71,"props":2054,"children":2055},{"class":73,"line":26},[2056,2061],{"type":32,"tag":71,"props":2057,"children":2058},{"style":78},[2059],{"type":37,"value":2060},"    owner",{"type":32,"tag":71,"props":2062,"children":2063},{"style":84},[2064],{"type":37,"value":87},{"type":32,"tag":71,"props":2066,"children":2067},{"class":73,"line":233},[2068,2073,2077],{"type":32,"tag":71,"props":2069,"children":2070},{"style":78},[2071],{"type":37,"value":2072},"      name",{"type":32,"tag":71,"props":2074,"children":2075},{"style":84},[2076],{"type":37,"value":106},{"type":32,"tag":71,"props":2078,"children":2079},{"style":109},[2080],{"type":37,"value":2081},"Marketing Analytics Team\n",{"type":32,"tag":71,"props":2083,"children":2084},{"class":73,"line":467},[2085,2090,2094],{"type":32,"tag":71,"props":2086,"children":2087},{"style":78},[2088],{"type":37,"value":2089},"      email",{"type":32,"tag":71,"props":2091,"children":2092},{"style":84},[2093],{"type":37,"value":106},{"type":32,"tag":71,"props":2095,"children":2096},{"style":109},[2097],{"type":37,"value":2098},"analytics@roibase.com.tr\n",{"type":32,"tag":33,"props":2100,"children":2101},{},[2102,2104,2110],{"type":37,"value":2103},"Questa definizione è visualizzata nella documentazione dbt — quale dashboard dipende da quale modello, chi va notificato se il modello cambia. In produzione, quando fai un breaking change nello schema, esegui ",{"type":32,"tag":52,"props":2105,"children":2107},{"className":2106},[],[2108],{"type":37,"value":2109},"dbt run --select +mrt_session_metrics+",{"type":37,"value":2111}," e vedi tutti gli impatti downstream.",{"type":32,"tag":33,"props":2113,"children":2114},{},[2115,2120,2122,2128,2130,2136],{"type":32,"tag":301,"props":2116,"children":2117},{},[2118],{"type":37,"value":2119},"Scenario reale:",{"type":37,"value":2121}," il parametro GA4 ",{"type":32,"tag":52,"props":2123,"children":2125},{"className":2124},[],[2126],{"type":37,"value":2127},"page_location",{"type":37,"value":2129}," è diventato ",{"type":32,"tag":52,"props":2131,"children":2133},{"className":2132},[],[2134],{"type":37,"value":2135},"page_url",{"type":37,"value":2137},". Grazie agli exposure, abbiamo identificato 3 dashboard e 1 DAG Airflow interessati — la migrazione è stata completata in 2 ore. Senza exposure, i dashboard si sarebbero rotti silenziosamente, lo avremmo scoperto dai reclami dei utenti.",{"type":32,"tag":40,"props":2139,"children":2141},{"id":2140},"incremental-models-non-fare-un-rebuild-completo-di-2tb-ogni-giorno",[2142],{"type":37,"value":2143},"Incremental models: non fare un rebuild completo di 2TB ogni giorno",{"type":32,"tag":33,"props":2145,"children":2146},{},[2147,2149,2155],{"type":37,"value":2148},"Nel data di marketing, le partizioni daily raggiungono terabyte. Non puoi fare un refresh completo ad ogni comando ",{"type":32,"tag":52,"props":2150,"children":2152},{"className":2151},[],[2153],{"type":37,"value":2154},"dbt run",{"type":37,"value":2156}," — il costo BigQuery e il tempo sono inaccettabili. Usi i modelli incrementali:",{"type":32,"tag":61,"props":2158,"children":2160},{"className":318,"code":2159,"language":320,"meta":16,"style":16},"-- models\u002Fmarts\u002Fmrt_user_journey.sql\n{{\n  config(\n    materialized='incremental',\n    partition_by={'field': 'event_date', 'data_type': 'date'},\n    cluster_by=['user_pseudo_id', 'traffic_source'],\n    incremental_strategy='insert_overwrite'\n  )\n}}\n\nselect\n  event_date,\n  user_pseudo_id,\n  traffic_source,\n  -- ...\nfrom {{ ref('stg_ga4_events') }}\n\n{% if is_incremental() %}\n  where event_date >= date_sub(current_date(), interval 3 day)\n{% endif %}\n",[2161],{"type":32,"tag":52,"props":2162,"children":2163},{"__ignoreMap":16},[2164,2172,2180,2188,2210,2264,2281,2298,2306,2314,2321,2328,2336,2344,2351,2359,2379,2386,2404,2440],{"type":32,"tag":71,"props":2165,"children":2166},{"class":73,"line":74},[2167],{"type":32,"tag":71,"props":2168,"children":2169},{"style":330},[2170],{"type":37,"value":2171},"-- models\u002Fmarts\u002Fmrt_user_journey.sql\n",{"type":32,"tag":71,"props":2173,"children":2174},{"class":73,"line":90},[2175],{"type":32,"tag":71,"props":2176,"children":2177},{"style":84},[2178],{"type":37,"value":2179},"{{\n",{"type":32,"tag":71,"props":2181,"children":2182},{"class":73,"line":115},[2183],{"type":32,"tag":71,"props":2184,"children":2185},{"style":84},[2186],{"type":37,"value":2187},"  config(\n",{"type":32,"tag":71,"props":2189,"children":2190},{"class":73,"line":133},[2191,2196,2201,2206],{"type":32,"tag":71,"props":2192,"children":2193},{"style":84},[2194],{"type":37,"value":2195},"    materialized",{"type":32,"tag":71,"props":2197,"children":2198},{"style":339},[2199],{"type":37,"value":2200},"=",{"type":32,"tag":71,"props":2202,"children":2203},{"style":109},[2204],{"type":37,"value":2205},"'incremental'",{"type":32,"tag":71,"props":2207,"children":2208},{"style":84},[2209],{"type":37,"value":863},{"type":32,"tag":71,"props":2211,"children":2212},{"class":73,"line":151},[2213,2218,2222,2227,2232,2236,2241,2245,2250,2254,2259],{"type":32,"tag":71,"props":2214,"children":2215},{"style":84},[2216],{"type":37,"value":2217},"    partition_by",{"type":32,"tag":71,"props":2219,"children":2220},{"style":339},[2221],{"type":37,"value":2200},{"type":32,"tag":71,"props":2223,"children":2224},{"style":84},[2225],{"type":37,"value":2226},"{",{"type":32,"tag":71,"props":2228,"children":2229},{"style":109},[2230],{"type":37,"value":2231},"'field'",{"type":32,"tag":71,"props":2233,"children":2234},{"style":84},[2235],{"type":37,"value":106},{"type":32,"tag":71,"props":2237,"children":2238},{"style":109},[2239],{"type":37,"value":2240},"'event_date'",{"type":32,"tag":71,"props":2242,"children":2243},{"style":84},[2244],{"type":37,"value":264},{"type":32,"tag":71,"props":2246,"children":2247},{"style":109},[2248],{"type":37,"value":2249},"'data_type'",{"type":32,"tag":71,"props":2251,"children":2252},{"style":84},[2253],{"type":37,"value":106},{"type":32,"tag":71,"props":2255,"children":2256},{"style":109},[2257],{"type":37,"value":2258},"'date'",{"type":32,"tag":71,"props":2260,"children":2261},{"style":84},[2262],{"type":37,"value":2263},"},\n",{"type":32,"tag":71,"props":2265,"children":2266},{"class":73,"line":164},[2267,2272,2276],{"type":32,"tag":71,"props":2268,"children":2269},{"style":84},[2270],{"type":37,"value":2271},"    cluster_by",{"type":32,"tag":71,"props":2273,"children":2274},{"style":339},[2275],{"type":37,"value":2200},{"type":32,"tag":71,"props":2277,"children":2278},{"style":84},[2279],{"type":37,"value":2280},"['user_pseudo_id', 'traffic_source'],\n",{"type":32,"tag":71,"props":2282,"children":2283},{"class":73,"line":186},[2284,2289,2293],{"type":32,"tag":71,"props":2285,"children":2286},{"style":84},[2287],{"type":37,"value":2288},"    incremental_strategy",{"type":32,"tag":71,"props":2290,"children":2291},{"style":339},[2292],{"type":37,"value":2200},{"type":32,"tag":71,"props":2294,"children":2295},{"style":109},[2296],{"type":37,"value":2297},"'insert_overwrite'\n",{"type":32,"tag":71,"props":2299,"children":2300},{"class":73,"line":203},[2301],{"type":32,"tag":71,"props":2302,"children":2303},{"style":84},[2304],{"type":37,"value":2305},"  )\n",{"type":32,"tag":71,"props":2307,"children":2308},{"class":73,"line":26},[2309],{"type":32,"tag":71,"props":2310,"children":2311},{"style":84},[2312],{"type":37,"value":2313},"}}\n",{"type":32,"tag":71,"props":2315,"children":2316},{"class":73,"line":233},[2317],{"type":32,"tag":71,"props":2318,"children":2319},{"emptyLinePlaceholder":413},[2320],{"type":37,"value":416},{"type":32,"tag":71,"props":2322,"children":2323},{"class":73,"line":467},[2324],{"type":32,"tag":71,"props":2325,"children":2326},{"style":339},[2327],{"type":37,"value":1099},{"type":32,"tag":71,"props":2329,"children":2330},{"class":73,"line":539},[2331],{"type":32,"tag":71,"props":2332,"children":2333},{"style":84},[2334],{"type":37,"value":2335},"  event_date,\n",{"type":32,"tag":71,"props":2337,"children":2338},{"class":73,"line":602},[2339],{"type":32,"tag":71,"props":2340,"children":2341},{"style":84},[2342],{"type":37,"value":2343},"  user_pseudo_id,\n",{"type":32,"tag":71,"props":2345,"children":2346},{"class":73,"line":616},[2347],{"type":32,"tag":71,"props":2348,"children":2349},{"style":84},[2350],{"type":37,"value":1117},{"type":32,"tag":71,"props":2352,"children":2353},{"class":73,"line":625},[2354],{"type":32,"tag":71,"props":2355,"children":2356},{"style":330},[2357],{"type":37,"value":2358},"  -- ...\n",{"type":32,"tag":71,"props":2360,"children":2361},{"class":73,"line":633},[2362,2366,2370,2375],{"type":32,"tag":71,"props":2363,"children":2364},{"style":339},[2365],{"type":37,"value":1285},{"type":32,"tag":71,"props":2367,"children":2368},{"style":84},[2369],{"type":37,"value":737},{"type":32,"tag":71,"props":2371,"children":2372},{"style":109},[2373],{"type":37,"value":2374},"'stg_ga4_events'",{"type":32,"tag":71,"props":2376,"children":2377},{"style":84},[2378],{"type":37,"value":399},{"type":32,"tag":71,"props":2380,"children":2381},{"class":73,"line":946},[2382],{"type":32,"tag":71,"props":2383,"children":2384},{"emptyLinePlaceholder":413},[2385],{"type":37,"value":416},{"type":32,"tag":71,"props":2387,"children":2388},{"class":73,"line":968},[2389,2394,2399],{"type":32,"tag":71,"props":2390,"children":2391},{"style":84},[2392],{"type":37,"value":2393},"{% ",{"type":32,"tag":71,"props":2395,"children":2396},{"style":339},[2397],{"type":37,"value":2398},"if",{"type":32,"tag":71,"props":2400,"children":2401},{"style":84},[2402],{"type":37,"value":2403}," is_incremental() %}\n",{"type":32,"tag":71,"props":2405,"children":2406},{"class":73,"line":989},[2407,2412,2417,2422,2427,2431,2436],{"type":32,"tag":71,"props":2408,"children":2409},{"style":339},[2410],{"type":37,"value":2411},"  where",{"type":32,"tag":71,"props":2413,"children":2414},{"style":84},[2415],{"type":37,"value":2416}," event_date ",{"type":32,"tag":71,"props":2418,"children":2419},{"style":339},[2420],{"type":37,"value":2421},">=",{"type":32,"tag":71,"props":2423,"children":2424},{"style":84},[2425],{"type":37,"value":2426}," date_sub(current_date(), interval ",{"type":32,"tag":71,"props":2428,"children":2429},{"style":256},[2430],{"type":37,"value":1322},{"type":32,"tag":71,"props":2432,"children":2433},{"style":339},[2434],{"type":37,"value":2435}," day",{"type":32,"tag":71,"props":2437,"children":2438},{"style":84},[2439],{"type":37,"value":622},{"type":32,"tag":71,"props":2441,"children":2442},{"class":73,"line":1006},[2443],{"type":32,"tag":71,"props":2444,"children":2445},{"style":84},[2446],{"type":37,"value":2447},"{% endif %}\n",{"type":32,"tag":33,"props":2449,"children":2450},{},[2451,2453,2459,2461,2467],{"type":37,"value":2452},"Questa configurazione fa tre cose: (1) Crea partition in BigQuery — aggiunge il nuovo giorno senza toccare quelli precedenti, (2) La clausola ",{"type":32,"tag":52,"props":2454,"children":2456},{"className":2455},[],[2457],{"type":37,"value":2458},"cluster_by",{"type":37,"value":2460}," migliora le performance delle query, (3) La strategia ",{"type":32,"tag":52,"props":2462,"children":2464},{"className":2463},[],[2465],{"type":37,"value":2466},"insert_overwrite",{"type":37,"value":2468}," — elimina gli ultimi 3 giorni e li riscrive (per gestire late arriving data).",{"type":32,"tag":33,"props":2470,"children":2471},{},[2472,2477],{"type":32,"tag":301,"props":2473,"children":2474},{},[2475],{"type":37,"value":2476},"Differenza di costo:",{"type":37,"value":2478}," 365 giorni di dati, refresh completo = 2,5 TB scan ($12,50), incremental = 3 GB scan ($0,015). Per una pipeline che gira quotidianamente, la differenza annua è ~$4500 vs ~$5. Per questo i modelli incrementali sono la base dello stack dati in produzione.",{"type":32,"tag":40,"props":2480,"children":2482},{"id":2481},"connettere-lo-stack-dati-al-processo-decisionale",[2483],{"type":37,"value":2484},"Connettere lo stack dati al processo decisionale",{"type":32,"tag":33,"props":2486,"children":2487},{},[2488],{"type":37,"value":2489},"dbt + BigQuery costruiscono l'infrastruttura, ma il valore reale è nell'impatto sulle decisioni di marketing. Un flusso tipico dal semantic layer a Slack:",{"type":32,"tag":2491,"props":2492,"children":2493},"ol",{},[2494,2506,2511,2524],{"type":32,"tag":2495,"props":2496,"children":2497},"li",{},[2498,2500],{"type":37,"value":2499},"Il manager marketing scrive in Slack: ",{"type":32,"tag":52,"props":2501,"children":2503},{"className":2502},[],[2504],{"type":37,"value":2505},"\u002Fmetric roas last_30_days campaign=brand",{"type":32,"tag":2495,"props":2507,"children":2508},{},[2509],{"type":37,"value":2510},"L'app Slack chiama l'API del semantic layer di dbt Cloud",{"type":32,"tag":2495,"props":2512,"children":2513},{},[2514,2516,2522],{"type":37,"value":2515},"L'API interroga la tabella ",{"type":32,"tag":52,"props":2517,"children":2519},{"className":2518},[],[2520],{"type":37,"value":2521},"mrt_session_metrics",{"type":37,"value":2523}," e calcola il ROAS",{"type":32,"tag":2495,"props":2525,"children":2526},{},[2527],{"type":37,"value":2528},"Il risultato torna a Slack: \"Campagna brand ROAS: 4.2x\"",{"type":32,"tag":33,"props":2530,"children":2531},{},[2532],{"type":37,"value":2533},"Questo flusso richiede il semantic layer dbt + un middleware Python personalizzato. Nello stack di produzione Roibase, un DAG Airflow cattura uno snapshot giornaliero dal semantic layer — Looker Studio e le app interne usano questo snapshot, evitando problemi di API rate limit.",{"type":32,"tag":33,"props":2535,"children":2536},{},[2537,2542,2544,2553],{"type":32,"tag":301,"props":2538,"children":2539},{},[2540],{"type":37,"value":2541},"Approccio alternativo:",{"type":37,"value":2543}," nello stack ibrido che utilizziamo nel nostro servizio ",{"type":32,"tag":2545,"props":2546,"children":2550},"a",{"href":2547,"rel":2548},"https:\u002F\u002Fwww.roibase.com.tr\u002Fit\u002Ffirstparty",[2549],"nofollow",[2551],{"type":37,"value":2552},"Dati First-Party & Architettura di Misurazione",{"type":37,"value":2554},", usiamo dbt semantic layer + Cube.js. Cube.js aggiunge un layer di caching, migliorando la performance della BI. La scelta dipende dal volume dei dati e dal pattern di query.",{"type":32,"tag":40,"props":2556,"children":2558},{"id":2557},"production-checklist-prima-di-deployare-lo-stack-dbt",[2559],{"type":37,"value":2560},"Production checklist: prima di deployare lo stack dbt",{"type":32,"tag":33,"props":2562,"children":2563},{},[2564],{"type":37,"value":2565},"dbt funziona in locale — prima di passare in produzione, esegui questi controlli:",{"type":32,"tag":2567,"props":2568,"children":2569},"ul",{},[2570,2588,2612,2622,2640,2650],{"type":32,"tag":2495,"props":2571,"children":2572},{},[2573,2578,2580,2586],{"type":32,"tag":301,"props":2574,"children":2575},{},[2576],{"type":37,"value":2577},"CI\u002FCD:",{"type":37,"value":2579}," con dbt Cloud o GitHub Actions, esegui ",{"type":32,"tag":52,"props":2581,"children":2583},{"className":2582},[],[2584],{"type":37,"value":2585},"dbt build --select state:modified+",{"type":37,"value":2587}," ad ogni commit",{"type":32,"tag":2495,"props":2589,"children":2590},{},[2591,2596,2598,2604,2606],{"type":32,"tag":301,"props":2592,"children":2593},{},[2594],{"type":37,"value":2595},"Freshness monitoring:",{"type":37,"value":2597}," per le sorgenti critiche, definisci ",{"type":32,"tag":52,"props":2599,"children":2601},{"className":2600},[],[2602],{"type":37,"value":2603},"warn_after",{"type":37,"value":2605}," e ",{"type":32,"tag":52,"props":2607,"children":2609},{"className":2608},[],[2610],{"type":37,"value":2611},"error_after",{"type":32,"tag":2495,"props":2613,"children":2614},{},[2615,2620],{"type":32,"tag":301,"props":2616,"children":2617},{},[2618],{"type":37,"value":2619},"Alerting:",{"type":37,"value":2621}," integra dbt Cloud webhook con Slack — se il build fallisce, il team è notificato in 5 minuti",{"type":32,"tag":2495,"props":2623,"children":2624},{},[2625,2630,2632,2638],{"type":32,"tag":301,"props":2626,"children":2627},{},[2628],{"type":37,"value":2629},"Documentazione:",{"type":37,"value":2631}," ",{"type":32,"tag":52,"props":2633,"children":2635},{"className":2634},[],[2636],{"type":37,"value":2637},"dbt docs generate",{"type":37,"value":2639}," deve girare automaticamente, gli artifact vanno pushed su S3\u002FGCS",{"type":32,"tag":2495,"props":2641,"children":2642},{},[2643,2648],{"type":32,"tag":301,"props":2644,"children":2645},{},[2646],{"type":37,"value":2647},"Cost monitoring:",{"type":37,"value":2649}," usa BigQuery slot reservation o attiva alert sui costi on-demand — imposta una soglia di $500\u002Fday per spike inaspettati",{"type":32,"tag":2495,"props":2651,"children":2652},{},[2653,2658],{"type":32,"tag":301,"props":2654,"children":2655},{},[2656],{"type":37,"value":2657},"Backup strategy:",{"type":37,"value":2659}," mantieni una snapshot table nel data warehouse di produzione — se un modello viene aggiornato male, puoi fare rollback",{"type":32,"tag":33,"props":2661,"children":2662},{},[2663,2668,2670,2675],{"type":32,"tag":301,"props":2664,"children":2665},{},[2666],{"type":37,"value":2667},"Regola critica:",{"type":37,"value":2669}," in produzione, nessun ",{"type":32,"tag":52,"props":2671,"children":2673},{"className":2672},[],[2674],{"type":37,"value":2154},{"type":37,"value":2676}," manuale. Tutta l'esecuzione deve passare attraverso uno scheduler (dbt Cloud, Airflow, Prefect). L'esecuzione manuale rompe la data lineage — se c'è un errore, il root cause analysis diventa impossibile.",{"type":32,"tag":33,"props":2678,"children":2679},{},[2680],{"type":37,"value":2681},"dbt + BigQuery è la spina dorsale dello stack di marketing moderno — con source mapping hai collegato i dati raw a contract significativi, il modeling layer ti permette di definire la metrica una sola volta, il semantic layer consente anche a chi non conosce SQL di consumare metriche. In produzione, i modelli incrementali e il coverage dei test rendono la pipeline sostenibile. Il prossimo passo è collegare questi dati all'attivazione real-time — CDP, audience sync, misurazione dell'incrementalità. Ma questo è un'altra discussione su data stack.",{"type":32,"tag":2683,"props":2684,"children":2685},"style",{},[2686],{"type":37,"value":2687},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":16,"searchDepth":115,"depth":115,"links":2689},[2690,2691,2694,2697,2698,2699],{"id":42,"depth":90,"text":45},{"id":667,"depth":90,"text":670,"children":2692},[2693],{"id":1358,"depth":115,"text":1361},{"id":1623,"depth":90,"text":1626,"children":2695},[2696],{"id":1929,"depth":115,"text":1932},{"id":2140,"depth":90,"text":2143},{"id":2481,"depth":90,"text":2484},{"id":2557,"depth":90,"text":2560},"markdown","content:it:data:dbt-bigquery-modern-data-stack-marketing.md","content","it\u002Fdata\u002Fdbt-bigquery-modern-data-stack-marketing.md","it\u002Fdata\u002Fdbt-bigquery-modern-data-stack-marketing","md",1785967479096]