[{"data":1,"prerenderedAt":6476},["ShallowReactive",2],{"tutorial-bruin-python":3,"content-query-GoHPetHZS5":712,"content-query-or0orPEmTc":1246,"content-query-hyxkMXmS1E":1247},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"category":11,"module":12,"isModuleIndex":13,"relatedTag":14,"relatedTagDescription":15,"prerequisites":16,"resources":19,"author":29,"body":33,"_type":706,"_id":707,"_source":708,"_file":709,"_stem":710,"_extension":711},"/tutorials/bruin-python","tutorials",false,"","Bruin + Python","Bruin is a first-class home for Python in your data stack - write Python assets, return DataFrames with materialization, and skip the boilerplate with the Python SDK.","2026-04-23","Module","bruin-python",true,"Python","Hands-on guides for writing Python in Bruin.",[17,18],"\u003Ca href=\"https://getbruin.com/docs/bruin/getting-started/introduction/installation.html\">Bruin CLI\u003C/a> installed","Python 3.10 or higher",[20,23,26],{"label":21,"url":22},"Python assets documentation","https://getbruin.com/docs/bruin/assets/python.html",{"label":24,"url":25},"Python SDK documentation","https://getbruin.com/docs/bruin/assets/python-sdk.html",{"label":27,"url":28},"bruin-sdk on PyPI","https://pypi.org/project/bruin-sdk/",{"name":30,"role":31,"image":32},"Bruin Team","Bruin Data","/bruin-logo-2025.svg",{"type":34,"children":35,"toc":699},"root",[36,45,60,65,72,85,169,190,196,217,466,526,532,553,591,679,684,688,693],{"type":37,"tag":38,"props":39,"children":41},"element","h2",{"id":40},"how-bruin-supports-python",[42],{"type":43,"value":44},"text","How Bruin supports Python",{"type":37,"tag":46,"props":47,"children":48},"p",{},[49,51,58],{"type":43,"value":50},"Python is a first-class asset type in Bruin - not a sidecar, not an escape hatch. You can drop a ",{"type":37,"tag":52,"props":53,"children":55},"code",{"className":54},[],[56],{"type":43,"value":57},".py",{"type":43,"value":59}," file into your pipeline alongside SQL assets and Bruin treats it the same way: it runs in the right order, respects dependencies, surfaces checks, and integrates with lineage.",{"type":37,"tag":46,"props":61,"children":62},{},[63],{"type":43,"value":64},"There are three layers that make this work.",{"type":37,"tag":66,"props":67,"children":69},"h3",{"id":68},"_1-python-assets",[70],{"type":43,"value":71},"1. Python assets",{"type":37,"tag":46,"props":73,"children":74},{},[75,77,83],{"type":43,"value":76},"Any Python script becomes a Bruin asset by adding a ",{"type":37,"tag":52,"props":78,"children":80},{"className":79},[],[81],{"type":43,"value":82},"@bruin",{"type":43,"value":84}," comment block at the top:",{"type":37,"tag":86,"props":87,"children":91},"pre",{"className":88,"code":89,"language":90,"meta":7,"style":7},"language-python shiki shiki-themes github-dark","\"\"\"@bruin\nname: my_script\nimage: python:3.13\n@bruin\"\"\"\n\nprint(\"Hello from Bruin!\")\n","python",[92],{"type":37,"tag":52,"props":93,"children":94},{"__ignoreMap":7},[95,107,116,125,134,143],{"type":37,"tag":96,"props":97,"children":100},"span",{"class":98,"line":99},"line",1,[101],{"type":37,"tag":96,"props":102,"children":104},{"style":103},"--shiki-default:#9ECBFF",[105],{"type":43,"value":106},"\"\"\"@bruin\n",{"type":37,"tag":96,"props":108,"children":110},{"class":98,"line":109},2,[111],{"type":37,"tag":96,"props":112,"children":113},{"style":103},[114],{"type":43,"value":115},"name: my_script\n",{"type":37,"tag":96,"props":117,"children":119},{"class":98,"line":118},3,[120],{"type":37,"tag":96,"props":121,"children":122},{"style":103},[123],{"type":43,"value":124},"image: python:3.13\n",{"type":37,"tag":96,"props":126,"children":128},{"class":98,"line":127},4,[129],{"type":37,"tag":96,"props":130,"children":131},{"style":103},[132],{"type":43,"value":133},"@bruin\"\"\"\n",{"type":37,"tag":96,"props":135,"children":137},{"class":98,"line":136},5,[138],{"type":37,"tag":96,"props":139,"children":140},{"emptyLinePlaceholder":13},[141],{"type":43,"value":142},"\n",{"type":37,"tag":96,"props":144,"children":146},{"class":98,"line":145},6,[147,153,159,164],{"type":37,"tag":96,"props":148,"children":150},{"style":149},"--shiki-default:#79B8FF",[151],{"type":43,"value":152},"print",{"type":37,"tag":96,"props":154,"children":156},{"style":155},"--shiki-default:#E1E4E8",[157],{"type":43,"value":158},"(",{"type":37,"tag":96,"props":160,"children":161},{"style":103},[162],{"type":43,"value":163},"\"Hello from Bruin!\"",{"type":37,"tag":96,"props":165,"children":166},{"style":155},[167],{"type":43,"value":168},")\n",{"type":37,"tag":46,"props":170,"children":171},{},[172,174,180,182,188],{"type":43,"value":173},"Each asset runs in an isolated environment with its own ",{"type":37,"tag":52,"props":175,"children":177},{"className":176},[],[178],{"type":43,"value":179},"requirements.txt",{"type":43,"value":181},", so there are no cross-asset dependency conflicts. Bruin uses ",{"type":37,"tag":52,"props":183,"children":185},{"className":184},[],[186],{"type":43,"value":187},"uv",{"type":43,"value":189}," under the hood for fast, deterministic installs.",{"type":37,"tag":66,"props":191,"children":193},{"id":192},"_2-materialization",[194],{"type":43,"value":195},"2. Materialization",{"type":37,"tag":46,"props":197,"children":198},{},[199,201,207,209,215],{"type":43,"value":200},"By default, a Python script just runs. If you want the data it produces to land in a warehouse table, add a ",{"type":37,"tag":52,"props":202,"children":204},{"className":203},[],[205],{"type":43,"value":206},"materialization",{"type":43,"value":208}," block and define a ",{"type":37,"tag":52,"props":210,"children":212},{"className":211},[],[213],{"type":43,"value":214},"materialize()",{"type":43,"value":216}," function that returns a DataFrame:",{"type":37,"tag":86,"props":218,"children":220},{"className":88,"code":219,"language":90,"meta":7,"style":7},"\"\"\"@bruin\nname: analytics.users\nconnection: my_bigquery\nmaterialization:\n  type: table\n  strategy: merge\ncolumns:\n  - name: id\n    type: integer\n    primary_key: true\n@bruin\"\"\"\n\nimport pandas as pd\n\ndef materialize():\n    return pd.DataFrame({\"id\": [1, 2, 3], \"name\": [\"Alice\", \"Bob\", \"Charlie\"]})\n",[221],{"type":37,"tag":52,"props":222,"children":223},{"__ignoreMap":7},[224,231,239,247,255,263,271,280,289,298,307,315,323,348,356,376],{"type":37,"tag":96,"props":225,"children":226},{"class":98,"line":99},[227],{"type":37,"tag":96,"props":228,"children":229},{"style":103},[230],{"type":43,"value":106},{"type":37,"tag":96,"props":232,"children":233},{"class":98,"line":109},[234],{"type":37,"tag":96,"props":235,"children":236},{"style":103},[237],{"type":43,"value":238},"name: analytics.users\n",{"type":37,"tag":96,"props":240,"children":241},{"class":98,"line":118},[242],{"type":37,"tag":96,"props":243,"children":244},{"style":103},[245],{"type":43,"value":246},"connection: my_bigquery\n",{"type":37,"tag":96,"props":248,"children":249},{"class":98,"line":127},[250],{"type":37,"tag":96,"props":251,"children":252},{"style":103},[253],{"type":43,"value":254},"materialization:\n",{"type":37,"tag":96,"props":256,"children":257},{"class":98,"line":136},[258],{"type":37,"tag":96,"props":259,"children":260},{"style":103},[261],{"type":43,"value":262},"  type: table\n",{"type":37,"tag":96,"props":264,"children":265},{"class":98,"line":145},[266],{"type":37,"tag":96,"props":267,"children":268},{"style":103},[269],{"type":43,"value":270},"  strategy: merge\n",{"type":37,"tag":96,"props":272,"children":274},{"class":98,"line":273},7,[275],{"type":37,"tag":96,"props":276,"children":277},{"style":103},[278],{"type":43,"value":279},"columns:\n",{"type":37,"tag":96,"props":281,"children":283},{"class":98,"line":282},8,[284],{"type":37,"tag":96,"props":285,"children":286},{"style":103},[287],{"type":43,"value":288},"  - name: id\n",{"type":37,"tag":96,"props":290,"children":292},{"class":98,"line":291},9,[293],{"type":37,"tag":96,"props":294,"children":295},{"style":103},[296],{"type":43,"value":297},"    type: integer\n",{"type":37,"tag":96,"props":299,"children":301},{"class":98,"line":300},10,[302],{"type":37,"tag":96,"props":303,"children":304},{"style":103},[305],{"type":43,"value":306},"    primary_key: true\n",{"type":37,"tag":96,"props":308,"children":310},{"class":98,"line":309},11,[311],{"type":37,"tag":96,"props":312,"children":313},{"style":103},[314],{"type":43,"value":133},{"type":37,"tag":96,"props":316,"children":318},{"class":98,"line":317},12,[319],{"type":37,"tag":96,"props":320,"children":321},{"emptyLinePlaceholder":13},[322],{"type":43,"value":142},{"type":37,"tag":96,"props":324,"children":326},{"class":98,"line":325},13,[327,333,338,343],{"type":37,"tag":96,"props":328,"children":330},{"style":329},"--shiki-default:#F97583",[331],{"type":43,"value":332},"import",{"type":37,"tag":96,"props":334,"children":335},{"style":155},[336],{"type":43,"value":337}," pandas ",{"type":37,"tag":96,"props":339,"children":340},{"style":329},[341],{"type":43,"value":342},"as",{"type":37,"tag":96,"props":344,"children":345},{"style":155},[346],{"type":43,"value":347}," pd\n",{"type":37,"tag":96,"props":349,"children":351},{"class":98,"line":350},14,[352],{"type":37,"tag":96,"props":353,"children":354},{"emptyLinePlaceholder":13},[355],{"type":43,"value":142},{"type":37,"tag":96,"props":357,"children":359},{"class":98,"line":358},15,[360,365,371],{"type":37,"tag":96,"props":361,"children":362},{"style":329},[363],{"type":43,"value":364},"def",{"type":37,"tag":96,"props":366,"children":368},{"style":367},"--shiki-default:#B392F0",[369],{"type":43,"value":370}," materialize",{"type":37,"tag":96,"props":372,"children":373},{"style":155},[374],{"type":43,"value":375},"():\n",{"type":37,"tag":96,"props":377,"children":379},{"class":98,"line":378},16,[380,385,390,395,400,405,410,415,419,424,429,434,438,443,447,452,456,461],{"type":37,"tag":96,"props":381,"children":382},{"style":329},[383],{"type":43,"value":384},"    return",{"type":37,"tag":96,"props":386,"children":387},{"style":155},[388],{"type":43,"value":389}," pd.DataFrame({",{"type":37,"tag":96,"props":391,"children":392},{"style":103},[393],{"type":43,"value":394},"\"id\"",{"type":37,"tag":96,"props":396,"children":397},{"style":155},[398],{"type":43,"value":399},": [",{"type":37,"tag":96,"props":401,"children":402},{"style":149},[403],{"type":43,"value":404},"1",{"type":37,"tag":96,"props":406,"children":407},{"style":155},[408],{"type":43,"value":409},", ",{"type":37,"tag":96,"props":411,"children":412},{"style":149},[413],{"type":43,"value":414},"2",{"type":37,"tag":96,"props":416,"children":417},{"style":155},[418],{"type":43,"value":409},{"type":37,"tag":96,"props":420,"children":421},{"style":149},[422],{"type":43,"value":423},"3",{"type":37,"tag":96,"props":425,"children":426},{"style":155},[427],{"type":43,"value":428},"], ",{"type":37,"tag":96,"props":430,"children":431},{"style":103},[432],{"type":43,"value":433},"\"name\"",{"type":37,"tag":96,"props":435,"children":436},{"style":155},[437],{"type":43,"value":399},{"type":37,"tag":96,"props":439,"children":440},{"style":103},[441],{"type":43,"value":442},"\"Alice\"",{"type":37,"tag":96,"props":444,"children":445},{"style":155},[446],{"type":43,"value":409},{"type":37,"tag":96,"props":448,"children":449},{"style":103},[450],{"type":43,"value":451},"\"Bob\"",{"type":37,"tag":96,"props":453,"children":454},{"style":155},[455],{"type":43,"value":409},{"type":37,"tag":96,"props":457,"children":458},{"style":103},[459],{"type":43,"value":460},"\"Charlie\"",{"type":37,"tag":96,"props":462,"children":463},{"style":155},[464],{"type":43,"value":465},"]})\n",{"type":37,"tag":46,"props":467,"children":468},{},[469,471,477,479,485,486,492,493,499,501,507,509,515,517,524],{"type":43,"value":470},"Bruin serializes the return value to Apache Arrow and uses ",{"type":37,"tag":52,"props":472,"children":474},{"className":473},[],[475],{"type":43,"value":476},"ingestr",{"type":43,"value":478}," to load it with your chosen strategy (",{"type":37,"tag":52,"props":480,"children":482},{"className":481},[],[483],{"type":43,"value":484},"create+replace",{"type":43,"value":409},{"type":37,"tag":52,"props":487,"children":489},{"className":488},[],[490],{"type":43,"value":491},"append",{"type":43,"value":409},{"type":37,"tag":52,"props":494,"children":496},{"className":495},[],[497],{"type":43,"value":498},"delete+insert",{"type":43,"value":500},", or ",{"type":37,"tag":52,"props":502,"children":504},{"className":503},[],[505],{"type":43,"value":506},"merge",{"type":43,"value":508},"). No manual ",{"type":37,"tag":52,"props":510,"children":512},{"className":511},[],[513],{"type":43,"value":514},"to_sql",{"type":43,"value":516},", no credential wiring. See ",{"type":37,"tag":518,"props":519,"children":521},"a",{"href":520},"/learn/python-materialization",[522],{"type":43,"value":523},"Python materialization",{"type":43,"value":525}," for the full walkthrough.",{"type":37,"tag":66,"props":527,"children":529},{"id":528},"_3-the-python-sdk",[530],{"type":43,"value":531},"3. The Python SDK",{"type":37,"tag":46,"props":533,"children":534},{},[535,537,543,545,551],{"type":43,"value":536},"The ",{"type":37,"tag":518,"props":538,"children":540},{"href":539},"/learn/bruin-python-sdk",[541],{"type":43,"value":542},"Bruin Python SDK",{"type":43,"value":544}," (",{"type":37,"tag":52,"props":546,"children":548},{"className":547},[],[549],{"type":43,"value":550},"bruin-sdk",{"type":43,"value":552}," on PyPI) eliminates the boilerplate most Python assets would otherwise need. Three imports cover the common cases:",{"type":37,"tag":554,"props":555,"children":556},"ul",{},[557,569,580],{"type":37,"tag":558,"props":559,"children":560},"li",{},[561,567],{"type":37,"tag":52,"props":562,"children":564},{"className":563},[],[565],{"type":43,"value":566},"query(sql)",{"type":43,"value":568}," - run SQL against the asset's connection, get a pandas DataFrame back",{"type":37,"tag":558,"props":570,"children":571},{},[572,578],{"type":37,"tag":52,"props":573,"children":575},{"className":574},[],[576],{"type":43,"value":577},"context",{"type":43,"value":579}," - typed access to pipeline metadata (start/end dates, full-refresh flag, variables)",{"type":37,"tag":558,"props":581,"children":582},{},[583,589],{"type":37,"tag":52,"props":584,"children":586},{"className":585},[],[587],{"type":43,"value":588},"get_connection(name)",{"type":43,"value":590}," - the underlying database client when you need more control",{"type":37,"tag":86,"props":592,"children":594},{"className":88,"code":593,"language":90,"meta":7,"style":7},"from bruin import query, context\n\ndf = query(f\"SELECT * FROM events WHERE dt >= '{context.start_date}'\")\n",[595],{"type":37,"tag":52,"props":596,"children":597},{"__ignoreMap":7},[598,620,627],{"type":37,"tag":96,"props":599,"children":600},{"class":98,"line":99},[601,606,611,615],{"type":37,"tag":96,"props":602,"children":603},{"style":329},[604],{"type":43,"value":605},"from",{"type":37,"tag":96,"props":607,"children":608},{"style":155},[609],{"type":43,"value":610}," bruin ",{"type":37,"tag":96,"props":612,"children":613},{"style":329},[614],{"type":43,"value":332},{"type":37,"tag":96,"props":616,"children":617},{"style":155},[618],{"type":43,"value":619}," query, context\n",{"type":37,"tag":96,"props":621,"children":622},{"class":98,"line":109},[623],{"type":37,"tag":96,"props":624,"children":625},{"emptyLinePlaceholder":13},[626],{"type":43,"value":142},{"type":37,"tag":96,"props":628,"children":629},{"class":98,"line":118},[630,635,640,645,650,655,660,665,670,675],{"type":37,"tag":96,"props":631,"children":632},{"style":155},[633],{"type":43,"value":634},"df ",{"type":37,"tag":96,"props":636,"children":637},{"style":329},[638],{"type":43,"value":639},"=",{"type":37,"tag":96,"props":641,"children":642},{"style":155},[643],{"type":43,"value":644}," query(",{"type":37,"tag":96,"props":646,"children":647},{"style":329},[648],{"type":43,"value":649},"f",{"type":37,"tag":96,"props":651,"children":652},{"style":103},[653],{"type":43,"value":654},"\"SELECT * FROM events WHERE dt >= '",{"type":37,"tag":96,"props":656,"children":657},{"style":149},[658],{"type":43,"value":659},"{",{"type":37,"tag":96,"props":661,"children":662},{"style":155},[663],{"type":43,"value":664},"context.start_date",{"type":37,"tag":96,"props":666,"children":667},{"style":149},[668],{"type":43,"value":669},"}",{"type":37,"tag":96,"props":671,"children":672},{"style":103},[673],{"type":43,"value":674},"'\"",{"type":37,"tag":96,"props":676,"children":677},{"style":155},[678],{"type":43,"value":168},{"type":37,"tag":46,"props":680,"children":681},{},[682],{"type":43,"value":683},"The SDK and materialization compose naturally: the SDK handles reading and transforming, materialization handles writing.",{"type":37,"tag":685,"props":686,"children":687},"hr",{},[],{"type":37,"tag":46,"props":689,"children":690},{},[691],{"type":43,"value":692},"More modules and walkthroughs coming soon. In the meantime, start with the tutorials below.",{"type":37,"tag":694,"props":695,"children":696},"style",{},[697],{"type":43,"value":698},"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":7,"searchDepth":109,"depth":109,"links":700},[701],{"id":40,"depth":109,"text":44,"children":702},[703,704,705],{"id":68,"depth":118,"text":71},{"id":192,"depth":118,"text":195},{"id":528,"depth":118,"text":531},"markdown","content:tutorials:bruin-python:index.md","content","tutorials/bruin-python/index.md","tutorials/bruin-python/index","md",{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"category":11,"module":12,"isModuleIndex":13,"relatedTag":14,"relatedTagDescription":15,"prerequisites":713,"resources":714,"author":718,"body":719,"_type":706,"_id":707,"_source":708,"_file":709,"_stem":710,"_extension":711},[17,18],[715,716,717],{"label":21,"url":22},{"label":24,"url":25},{"label":27,"url":28},{"name":30,"role":31,"image":32},{"type":34,"children":720,"toc":1239},[721,725,735,739,743,753,813,829,833,849,1055,1100,1104,1119,1149,1224,1228,1231,1235],{"type":37,"tag":38,"props":722,"children":723},{"id":40},[724],{"type":43,"value":44},{"type":37,"tag":46,"props":726,"children":727},{},[728,729,734],{"type":43,"value":50},{"type":37,"tag":52,"props":730,"children":732},{"className":731},[],[733],{"type":43,"value":57},{"type":43,"value":59},{"type":37,"tag":46,"props":736,"children":737},{},[738],{"type":43,"value":64},{"type":37,"tag":66,"props":740,"children":741},{"id":68},[742],{"type":43,"value":71},{"type":37,"tag":46,"props":744,"children":745},{},[746,747,752],{"type":43,"value":76},{"type":37,"tag":52,"props":748,"children":750},{"className":749},[],[751],{"type":43,"value":82},{"type":43,"value":84},{"type":37,"tag":86,"props":754,"children":755},{"className":88,"code":89,"language":90,"meta":7,"style":7},[756],{"type":37,"tag":52,"props":757,"children":758},{"__ignoreMap":7},[759,766,773,780,787,794],{"type":37,"tag":96,"props":760,"children":761},{"class":98,"line":99},[762],{"type":37,"tag":96,"props":763,"children":764},{"style":103},[765],{"type":43,"value":106},{"type":37,"tag":96,"props":767,"children":768},{"class":98,"line":109},[769],{"type":37,"tag":96,"props":770,"children":771},{"style":103},[772],{"type":43,"value":115},{"type":37,"tag":96,"props":774,"children":775},{"class":98,"line":118},[776],{"type":37,"tag":96,"props":777,"children":778},{"style":103},[779],{"type":43,"value":124},{"type":37,"tag":96,"props":781,"children":782},{"class":98,"line":127},[783],{"type":37,"tag":96,"props":784,"children":785},{"style":103},[786],{"type":43,"value":133},{"type":37,"tag":96,"props":788,"children":789},{"class":98,"line":136},[790],{"type":37,"tag":96,"props":791,"children":792},{"emptyLinePlaceholder":13},[793],{"type":43,"value":142},{"type":37,"tag":96,"props":795,"children":796},{"class":98,"line":145},[797,801,805,809],{"type":37,"tag":96,"props":798,"children":799},{"style":149},[800],{"type":43,"value":152},{"type":37,"tag":96,"props":802,"children":803},{"style":155},[804],{"type":43,"value":158},{"type":37,"tag":96,"props":806,"children":807},{"style":103},[808],{"type":43,"value":163},{"type":37,"tag":96,"props":810,"children":811},{"style":155},[812],{"type":43,"value":168},{"type":37,"tag":46,"props":814,"children":815},{},[816,817,822,823,828],{"type":43,"value":173},{"type":37,"tag":52,"props":818,"children":820},{"className":819},[],[821],{"type":43,"value":179},{"type":43,"value":181},{"type":37,"tag":52,"props":824,"children":826},{"className":825},[],[827],{"type":43,"value":187},{"type":43,"value":189},{"type":37,"tag":66,"props":830,"children":831},{"id":192},[832],{"type":43,"value":195},{"type":37,"tag":46,"props":834,"children":835},{},[836,837,842,843,848],{"type":43,"value":200},{"type":37,"tag":52,"props":838,"children":840},{"className":839},[],[841],{"type":43,"value":206},{"type":43,"value":208},{"type":37,"tag":52,"props":844,"children":846},{"className":845},[],[847],{"type":43,"value":214},{"type":43,"value":216},{"type":37,"tag":86,"props":850,"children":851},{"className":88,"code":219,"language":90,"meta":7,"style":7},[852],{"type":37,"tag":52,"props":853,"children":854},{"__ignoreMap":7},[855,862,869,876,883,890,897,904,911,918,925,932,939,958,965,980],{"type":37,"tag":96,"props":856,"children":857},{"class":98,"line":99},[858],{"type":37,"tag":96,"props":859,"children":860},{"style":103},[861],{"type":43,"value":106},{"type":37,"tag":96,"props":863,"children":864},{"class":98,"line":109},[865],{"type":37,"tag":96,"props":866,"children":867},{"style":103},[868],{"type":43,"value":238},{"type":37,"tag":96,"props":870,"children":871},{"class":98,"line":118},[872],{"type":37,"tag":96,"props":873,"children":874},{"style":103},[875],{"type":43,"value":246},{"type":37,"tag":96,"props":877,"children":878},{"class":98,"line":127},[879],{"type":37,"tag":96,"props":880,"children":881},{"style":103},[882],{"type":43,"value":254},{"type":37,"tag":96,"props":884,"children":885},{"class":98,"line":136},[886],{"type":37,"tag":96,"props":887,"children":888},{"style":103},[889],{"type":43,"value":262},{"type":37,"tag":96,"props":891,"children":892},{"class":98,"line":145},[893],{"type":37,"tag":96,"props":894,"children":895},{"style":103},[896],{"type":43,"value":270},{"type":37,"tag":96,"props":898,"children":899},{"class":98,"line":273},[900],{"type":37,"tag":96,"props":901,"children":902},{"style":103},[903],{"type":43,"value":279},{"type":37,"tag":96,"props":905,"children":906},{"class":98,"line":282},[907],{"type":37,"tag":96,"props":908,"children":909},{"style":103},[910],{"type":43,"value":288},{"type":37,"tag":96,"props":912,"children":913},{"class":98,"line":291},[914],{"type":37,"tag":96,"props":915,"children":916},{"style":103},[917],{"type":43,"value":297},{"type":37,"tag":96,"props":919,"children":920},{"class":98,"line":300},[921],{"type":37,"tag":96,"props":922,"children":923},{"style":103},[924],{"type":43,"value":306},{"type":37,"tag":96,"props":926,"children":927},{"class":98,"line":309},[928],{"type":37,"tag":96,"props":929,"children":930},{"style":103},[931],{"type":43,"value":133},{"type":37,"tag":96,"props":933,"children":934},{"class":98,"line":317},[935],{"type":37,"tag":96,"props":936,"children":937},{"emptyLinePlaceholder":13},[938],{"type":43,"value":142},{"type":37,"tag":96,"props":940,"children":941},{"class":98,"line":325},[942,946,950,954],{"type":37,"tag":96,"props":943,"children":944},{"style":329},[945],{"type":43,"value":332},{"type":37,"tag":96,"props":947,"children":948},{"style":155},[949],{"type":43,"value":337},{"type":37,"tag":96,"props":951,"children":952},{"style":329},[953],{"type":43,"value":342},{"type":37,"tag":96,"props":955,"children":956},{"style":155},[957],{"type":43,"value":347},{"type":37,"tag":96,"props":959,"children":960},{"class":98,"line":350},[961],{"type":37,"tag":96,"props":962,"children":963},{"emptyLinePlaceholder":13},[964],{"type":43,"value":142},{"type":37,"tag":96,"props":966,"children":967},{"class":98,"line":358},[968,972,976],{"type":37,"tag":96,"props":969,"children":970},{"style":329},[971],{"type":43,"value":364},{"type":37,"tag":96,"props":973,"children":974},{"style":367},[975],{"type":43,"value":370},{"type":37,"tag":96,"props":977,"children":978},{"style":155},[979],{"type":43,"value":375},{"type":37,"tag":96,"props":981,"children":982},{"class":98,"line":378},[983,987,991,995,999,1003,1007,1011,1015,1019,1023,1027,1031,1035,1039,1043,1047,1051],{"type":37,"tag":96,"props":984,"children":985},{"style":329},[986],{"type":43,"value":384},{"type":37,"tag":96,"props":988,"children":989},{"style":155},[990],{"type":43,"value":389},{"type":37,"tag":96,"props":992,"children":993},{"style":103},[994],{"type":43,"value":394},{"type":37,"tag":96,"props":996,"children":997},{"style":155},[998],{"type":43,"value":399},{"type":37,"tag":96,"props":1000,"children":1001},{"style":149},[1002],{"type":43,"value":404},{"type":37,"tag":96,"props":1004,"children":1005},{"style":155},[1006],{"type":43,"value":409},{"type":37,"tag":96,"props":1008,"children":1009},{"style":149},[1010],{"type":43,"value":414},{"type":37,"tag":96,"props":1012,"children":1013},{"style":155},[1014],{"type":43,"value":409},{"type":37,"tag":96,"props":1016,"children":1017},{"style":149},[1018],{"type":43,"value":423},{"type":37,"tag":96,"props":1020,"children":1021},{"style":155},[1022],{"type":43,"value":428},{"type":37,"tag":96,"props":1024,"children":1025},{"style":103},[1026],{"type":43,"value":433},{"type":37,"tag":96,"props":1028,"children":1029},{"style":155},[1030],{"type":43,"value":399},{"type":37,"tag":96,"props":1032,"children":1033},{"style":103},[1034],{"type":43,"value":442},{"type":37,"tag":96,"props":1036,"children":1037},{"style":155},[1038],{"type":43,"value":409},{"type":37,"tag":96,"props":1040,"children":1041},{"style":103},[1042],{"type":43,"value":451},{"type":37,"tag":96,"props":1044,"children":1045},{"style":155},[1046],{"type":43,"value":409},{"type":37,"tag":96,"props":1048,"children":1049},{"style":103},[1050],{"type":43,"value":460},{"type":37,"tag":96,"props":1052,"children":1053},{"style":155},[1054],{"type":43,"value":465},{"type":37,"tag":46,"props":1056,"children":1057},{},[1058,1059,1064,1065,1070,1071,1076,1077,1082,1083,1088,1089,1094,1095,1099],{"type":43,"value":470},{"type":37,"tag":52,"props":1060,"children":1062},{"className":1061},[],[1063],{"type":43,"value":476},{"type":43,"value":478},{"type":37,"tag":52,"props":1066,"children":1068},{"className":1067},[],[1069],{"type":43,"value":484},{"type":43,"value":409},{"type":37,"tag":52,"props":1072,"children":1074},{"className":1073},[],[1075],{"type":43,"value":491},{"type":43,"value":409},{"type":37,"tag":52,"props":1078,"children":1080},{"className":1079},[],[1081],{"type":43,"value":498},{"type":43,"value":500},{"type":37,"tag":52,"props":1084,"children":1086},{"className":1085},[],[1087],{"type":43,"value":506},{"type":43,"value":508},{"type":37,"tag":52,"props":1090,"children":1092},{"className":1091},[],[1093],{"type":43,"value":514},{"type":43,"value":516},{"type":37,"tag":518,"props":1096,"children":1097},{"href":520},[1098],{"type":43,"value":523},{"type":43,"value":525},{"type":37,"tag":66,"props":1101,"children":1102},{"id":528},[1103],{"type":43,"value":531},{"type":37,"tag":46,"props":1105,"children":1106},{},[1107,1108,1112,1113,1118],{"type":43,"value":536},{"type":37,"tag":518,"props":1109,"children":1110},{"href":539},[1111],{"type":43,"value":542},{"type":43,"value":544},{"type":37,"tag":52,"props":1114,"children":1116},{"className":1115},[],[1117],{"type":43,"value":550},{"type":43,"value":552},{"type":37,"tag":554,"props":1120,"children":1121},{},[1122,1131,1140],{"type":37,"tag":558,"props":1123,"children":1124},{},[1125,1130],{"type":37,"tag":52,"props":1126,"children":1128},{"className":1127},[],[1129],{"type":43,"value":566},{"type":43,"value":568},{"type":37,"tag":558,"props":1132,"children":1133},{},[1134,1139],{"type":37,"tag":52,"props":1135,"children":1137},{"className":1136},[],[1138],{"type":43,"value":577},{"type":43,"value":579},{"type":37,"tag":558,"props":1141,"children":1142},{},[1143,1148],{"type":37,"tag":52,"props":1144,"children":1146},{"className":1145},[],[1147],{"type":43,"value":588},{"type":43,"value":590},{"type":37,"tag":86,"props":1150,"children":1151},{"className":88,"code":593,"language":90,"meta":7,"style":7},[1152],{"type":37,"tag":52,"props":1153,"children":1154},{"__ignoreMap":7},[1155,1174,1181],{"type":37,"tag":96,"props":1156,"children":1157},{"class":98,"line":99},[1158,1162,1166,1170],{"type":37,"tag":96,"props":1159,"children":1160},{"style":329},[1161],{"type":43,"value":605},{"type":37,"tag":96,"props":1163,"children":1164},{"style":155},[1165],{"type":43,"value":610},{"type":37,"tag":96,"props":1167,"children":1168},{"style":329},[1169],{"type":43,"value":332},{"type":37,"tag":96,"props":1171,"children":1172},{"style":155},[1173],{"type":43,"value":619},{"type":37,"tag":96,"props":1175,"children":1176},{"class":98,"line":109},[1177],{"type":37,"tag":96,"props":1178,"children":1179},{"emptyLinePlaceholder":13},[1180],{"type":43,"value":142},{"type":37,"tag":96,"props":1182,"children":1183},{"class":98,"line":118},[1184,1188,1192,1196,1200,1204,1208,1212,1216,1220],{"type":37,"tag":96,"props":1185,"children":1186},{"style":155},[1187],{"type":43,"value":634},{"type":37,"tag":96,"props":1189,"children":1190},{"style":329},[1191],{"type":43,"value":639},{"type":37,"tag":96,"props":1193,"children":1194},{"style":155},[1195],{"type":43,"value":644},{"type":37,"tag":96,"props":1197,"children":1198},{"style":329},[1199],{"type":43,"value":649},{"type":37,"tag":96,"props":1201,"children":1202},{"style":103},[1203],{"type":43,"value":654},{"type":37,"tag":96,"props":1205,"children":1206},{"style":149},[1207],{"type":43,"value":659},{"type":37,"tag":96,"props":1209,"children":1210},{"style":155},[1211],{"type":43,"value":664},{"type":37,"tag":96,"props":1213,"children":1214},{"style":149},[1215],{"type":43,"value":669},{"type":37,"tag":96,"props":1217,"children":1218},{"style":103},[1219],{"type":43,"value":674},{"type":37,"tag":96,"props":1221,"children":1222},{"style":155},[1223],{"type":43,"value":168},{"type":37,"tag":46,"props":1225,"children":1226},{},[1227],{"type":43,"value":683},{"type":37,"tag":685,"props":1229,"children":1230},{},[],{"type":37,"tag":46,"props":1232,"children":1233},{},[1234],{"type":43,"value":692},{"type":37,"tag":694,"props":1236,"children":1237},{},[1238],{"type":43,"value":698},{"title":7,"searchDepth":109,"depth":109,"links":1240},[1241],{"id":40,"depth":109,"text":44,"children":1242},[1243,1244,1245],{"id":68,"depth":118,"text":71},{"id":192,"depth":118,"text":195},{"id":528,"depth":118,"text":531},[],[1248,3934],{"_path":1249,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":1250,"description":1251,"date":10,"readingTime":317,"category":1252,"tags":1253,"difficulty":1258,"journeys":1259,"hidden":6,"author":1262,"body":1263,"_type":706,"_id":3931,"_source":708,"_file":3932,"_stem":3933,"_extension":711},"/tutorials/bruin-python-sdk","Using the Bruin Python SDK","Skip the boilerplate. Use the Bruin Python SDK to query databases, manage connections, and access pipeline context from your Python assets with a few imports.","Tutorial",[1254,14,1255,1256,1257],"Bruin CLI","BigQuery","Postgres","DuckDB","Beginner",[1260,1261],"Data Engineer","Data Analyst",{"name":30,"role":31,"image":32},{"type":34,"children":1264,"toc":3914},[1265,1271,1290,1300,1308,1336,1339,1345,1350,1355,1432,1437,1466,1469,1475,1481,1500,1516,1521,1623,1628,1634,1646,1754,1767,1773,1852,1877,2033,2039,2058,2229,2234,2342,2348,2368,2554,2560,2573,2844,2887,2893,2904,3217,3237,3243,3253,3394,3407,3514,3541,3547,3552,3759,3771,3774,3780,3852,3855,3861,3910],{"type":37,"tag":38,"props":1266,"children":1268},{"id":1267},"overview",[1269],{"type":43,"value":1270},"Overview",{"type":37,"tag":46,"props":1272,"children":1273},{},[1274,1280,1282,1288],{"type":37,"tag":1275,"props":1276,"children":1277},"strong",{},[1278],{"type":43,"value":1279},"Goal",{"type":43,"value":1281}," - Learn how to use the ",{"type":37,"tag":518,"props":1283,"children":1286},{"href":28,"rel":1284},[1285],"nofollow",[1287],{"type":43,"value":542},{"type":43,"value":1289}," to eliminate boilerplate in your Python assets. Query databases, access typed connections, and read pipeline context with just a few imports.",{"type":37,"tag":46,"props":1291,"children":1292},{},[1293,1298],{"type":37,"tag":1275,"props":1294,"children":1295},{},[1296],{"type":43,"value":1297},"Audience",{"type":43,"value":1299}," - Data engineers and analysts writing Python assets in Bruin who want cleaner, more maintainable pipeline code.",{"type":37,"tag":46,"props":1301,"children":1302},{},[1303],{"type":37,"tag":1275,"props":1304,"children":1305},{},[1306],{"type":43,"value":1307},"Prerequisites",{"type":37,"tag":554,"props":1309,"children":1310},{},[1311,1322,1327,1331],{"type":37,"tag":558,"props":1312,"children":1313},{},[1314,1320],{"type":37,"tag":518,"props":1315,"children":1318},{"href":1316,"rel":1317},"https://getbruin.com/docs/bruin/getting-started/introduction/installation.html",[1285],[1319],{"type":43,"value":1254},{"type":43,"value":1321}," installed",{"type":37,"tag":558,"props":1323,"children":1324},{},[1325],{"type":43,"value":1326},"A Bruin project with at least one Python asset",{"type":37,"tag":558,"props":1328,"children":1329},{},[1330],{"type":43,"value":18},{"type":37,"tag":558,"props":1332,"children":1333},{},[1334],{"type":43,"value":1335},"A configured database connection (BigQuery, Postgres, Snowflake, DuckDB, etc.)",{"type":37,"tag":685,"props":1337,"children":1338},{},[],{"type":37,"tag":38,"props":1340,"children":1342},{"id":1341},"why-the-sdk",[1343],{"type":43,"value":1344},"Why the SDK?",{"type":37,"tag":46,"props":1346,"children":1347},{},[1348],{"type":43,"value":1349},"Before the SDK, a Python asset that ran a query required manually parsing credentials from environment variables, building a database client, handling auth, and executing the query. That's 10+ lines of setup before you write a single line of business logic.",{"type":37,"tag":46,"props":1351,"children":1352},{},[1353],{"type":43,"value":1354},"With the SDK, it collapses to this:",{"type":37,"tag":86,"props":1356,"children":1358},{"className":88,"code":1357,"language":90,"meta":7,"style":7},"from bruin import query, context\n\ndf = query(f\"SELECT * FROM users WHERE dt >= '{context.start_date}'\")\n",[1359],{"type":37,"tag":52,"props":1360,"children":1361},{"__ignoreMap":7},[1362,1381,1388],{"type":37,"tag":96,"props":1363,"children":1364},{"class":98,"line":99},[1365,1369,1373,1377],{"type":37,"tag":96,"props":1366,"children":1367},{"style":329},[1368],{"type":43,"value":605},{"type":37,"tag":96,"props":1370,"children":1371},{"style":155},[1372],{"type":43,"value":610},{"type":37,"tag":96,"props":1374,"children":1375},{"style":329},[1376],{"type":43,"value":332},{"type":37,"tag":96,"props":1378,"children":1379},{"style":155},[1380],{"type":43,"value":619},{"type":37,"tag":96,"props":1382,"children":1383},{"class":98,"line":109},[1384],{"type":37,"tag":96,"props":1385,"children":1386},{"emptyLinePlaceholder":13},[1387],{"type":43,"value":142},{"type":37,"tag":96,"props":1389,"children":1390},{"class":98,"line":118},[1391,1395,1399,1403,1407,1412,1416,1420,1424,1428],{"type":37,"tag":96,"props":1392,"children":1393},{"style":155},[1394],{"type":43,"value":634},{"type":37,"tag":96,"props":1396,"children":1397},{"style":329},[1398],{"type":43,"value":639},{"type":37,"tag":96,"props":1400,"children":1401},{"style":155},[1402],{"type":43,"value":644},{"type":37,"tag":96,"props":1404,"children":1405},{"style":329},[1406],{"type":43,"value":649},{"type":37,"tag":96,"props":1408,"children":1409},{"style":103},[1410],{"type":43,"value":1411},"\"SELECT * FROM users WHERE dt >= '",{"type":37,"tag":96,"props":1413,"children":1414},{"style":149},[1415],{"type":43,"value":659},{"type":37,"tag":96,"props":1417,"children":1418},{"style":155},[1419],{"type":43,"value":664},{"type":37,"tag":96,"props":1421,"children":1422},{"style":149},[1423],{"type":43,"value":669},{"type":37,"tag":96,"props":1425,"children":1426},{"style":103},[1427],{"type":43,"value":674},{"type":37,"tag":96,"props":1429,"children":1430},{"style":155},[1431],{"type":43,"value":168},{"type":37,"tag":46,"props":1433,"children":1434},{},[1435],{"type":43,"value":1436},"The SDK handles credential parsing, client initialization, and context injection for you.",{"type":37,"tag":1438,"props":1439,"children":1440},"blockquote",{},[1441],{"type":37,"tag":46,"props":1442,"children":1443},{},[1444,1446,1450,1452,1457,1459,1464],{"type":43,"value":1445},"The SDK pairs naturally with ",{"type":37,"tag":518,"props":1447,"children":1448},{"href":520},[1449],{"type":43,"value":523},{"type":43,"value":1451},". The SDK handles reading and transforming data; materialization handles writing a DataFrame back to your warehouse with strategies like ",{"type":37,"tag":52,"props":1453,"children":1455},{"className":1454},[],[1456],{"type":43,"value":506},{"type":43,"value":1458}," or ",{"type":37,"tag":52,"props":1460,"children":1462},{"className":1461},[],[1463],{"type":43,"value":491},{"type":43,"value":1465},". See Step 7 below.",{"type":37,"tag":685,"props":1467,"children":1468},{},[],{"type":37,"tag":38,"props":1470,"children":1472},{"id":1471},"steps",[1473],{"type":43,"value":1474},"Steps",{"type":37,"tag":66,"props":1476,"children":1478},{"id":1477},"_1-install-the-sdk",[1479],{"type":43,"value":1480},"1) Install the SDK",{"type":37,"tag":46,"props":1482,"children":1483},{},[1484,1486,1491,1493,1498],{"type":43,"value":1485},"Add ",{"type":37,"tag":52,"props":1487,"children":1489},{"className":1488},[],[1490],{"type":43,"value":550},{"type":43,"value":1492}," to your asset's ",{"type":37,"tag":52,"props":1494,"children":1496},{"className":1495},[],[1497],{"type":43,"value":179},{"type":43,"value":1499},". Use extras to pull in the database drivers you need:",{"type":37,"tag":86,"props":1501,"children":1505},{"className":1502,"code":1503,"language":1504,"meta":7,"style":7},"language-txt shiki shiki-themes github-dark","bruin-sdk[bigquery]\n","txt",[1506],{"type":37,"tag":52,"props":1507,"children":1508},{"__ignoreMap":7},[1509],{"type":37,"tag":96,"props":1510,"children":1511},{"class":98,"line":99},[1512],{"type":37,"tag":96,"props":1513,"children":1514},{},[1515],{"type":43,"value":1503},{"type":37,"tag":46,"props":1517,"children":1518},{},[1519],{"type":43,"value":1520},"Available extras:",{"type":37,"tag":554,"props":1522,"children":1523},{},[1524,1535,1546,1557,1568,1579,1590,1601,1612],{"type":37,"tag":558,"props":1525,"children":1526},{},[1527,1533],{"type":37,"tag":52,"props":1528,"children":1530},{"className":1529},[],[1531],{"type":43,"value":1532},"bruin-sdk[bigquery]",{"type":43,"value":1534}," - Google BigQuery",{"type":37,"tag":558,"props":1536,"children":1537},{},[1538,1544],{"type":37,"tag":52,"props":1539,"children":1541},{"className":1540},[],[1542],{"type":43,"value":1543},"bruin-sdk[snowflake]",{"type":43,"value":1545}," - Snowflake",{"type":37,"tag":558,"props":1547,"children":1548},{},[1549,1555],{"type":37,"tag":52,"props":1550,"children":1552},{"className":1551},[],[1553],{"type":43,"value":1554},"bruin-sdk[postgres]",{"type":43,"value":1556}," - PostgreSQL",{"type":37,"tag":558,"props":1558,"children":1559},{},[1560,1566],{"type":37,"tag":52,"props":1561,"children":1563},{"className":1562},[],[1564],{"type":43,"value":1565},"bruin-sdk[redshift]",{"type":43,"value":1567}," - Redshift",{"type":37,"tag":558,"props":1569,"children":1570},{},[1571,1577],{"type":37,"tag":52,"props":1572,"children":1574},{"className":1573},[],[1575],{"type":43,"value":1576},"bruin-sdk[mssql]",{"type":43,"value":1578}," - Microsoft SQL Server",{"type":37,"tag":558,"props":1580,"children":1581},{},[1582,1588],{"type":37,"tag":52,"props":1583,"children":1585},{"className":1584},[],[1586],{"type":43,"value":1587},"bruin-sdk[mysql]",{"type":43,"value":1589}," - MySQL",{"type":37,"tag":558,"props":1591,"children":1592},{},[1593,1599],{"type":37,"tag":52,"props":1594,"children":1596},{"className":1595},[],[1597],{"type":43,"value":1598},"bruin-sdk[duckdb]",{"type":43,"value":1600}," - DuckDB",{"type":37,"tag":558,"props":1602,"children":1603},{},[1604,1610],{"type":37,"tag":52,"props":1605,"children":1607},{"className":1606},[],[1608],{"type":43,"value":1609},"bruin-sdk[sheets]",{"type":43,"value":1611}," - Google Sheets",{"type":37,"tag":558,"props":1613,"children":1614},{},[1615,1621],{"type":37,"tag":52,"props":1616,"children":1618},{"className":1617},[],[1619],{"type":43,"value":1620},"bruin-sdk[all]",{"type":43,"value":1622}," - Everything",{"type":37,"tag":46,"props":1624,"children":1625},{},[1626],{"type":43,"value":1627},"Bruin will install the dependencies automatically when your asset runs.",{"type":37,"tag":66,"props":1629,"children":1631},{"id":1630},"_2-declare-your-connection-in-asset-metadata",[1632],{"type":43,"value":1633},"2) Declare your connection in asset metadata",{"type":37,"tag":46,"props":1635,"children":1636},{},[1637,1639,1644],{"type":43,"value":1638},"In your Python asset, declare the connection in the ",{"type":37,"tag":52,"props":1640,"children":1642},{"className":1641},[],[1643],{"type":43,"value":82},{"type":43,"value":1645}," block. The SDK reads this to know which credentials to load:",{"type":37,"tag":86,"props":1647,"children":1649},{"className":88,"code":1648,"language":90,"meta":7,"style":7},"\"\"\" @bruin\nname: raw.active_users\nconnection: my_bigquery\n@bruin \"\"\"\n\nfrom bruin import query\n\ndf = query(\"SELECT * FROM users WHERE active = true\")\nprint(df.head())\n",[1650],{"type":37,"tag":52,"props":1651,"children":1652},{"__ignoreMap":7},[1653,1661,1669,1676,1684,1691,1711,1718,1742],{"type":37,"tag":96,"props":1654,"children":1655},{"class":98,"line":99},[1656],{"type":37,"tag":96,"props":1657,"children":1658},{"style":103},[1659],{"type":43,"value":1660},"\"\"\" @bruin\n",{"type":37,"tag":96,"props":1662,"children":1663},{"class":98,"line":109},[1664],{"type":37,"tag":96,"props":1665,"children":1666},{"style":103},[1667],{"type":43,"value":1668},"name: raw.active_users\n",{"type":37,"tag":96,"props":1670,"children":1671},{"class":98,"line":118},[1672],{"type":37,"tag":96,"props":1673,"children":1674},{"style":103},[1675],{"type":43,"value":246},{"type":37,"tag":96,"props":1677,"children":1678},{"class":98,"line":127},[1679],{"type":37,"tag":96,"props":1680,"children":1681},{"style":103},[1682],{"type":43,"value":1683},"@bruin \"\"\"\n",{"type":37,"tag":96,"props":1685,"children":1686},{"class":98,"line":136},[1687],{"type":37,"tag":96,"props":1688,"children":1689},{"emptyLinePlaceholder":13},[1690],{"type":43,"value":142},{"type":37,"tag":96,"props":1692,"children":1693},{"class":98,"line":145},[1694,1698,1702,1706],{"type":37,"tag":96,"props":1695,"children":1696},{"style":329},[1697],{"type":43,"value":605},{"type":37,"tag":96,"props":1699,"children":1700},{"style":155},[1701],{"type":43,"value":610},{"type":37,"tag":96,"props":1703,"children":1704},{"style":329},[1705],{"type":43,"value":332},{"type":37,"tag":96,"props":1707,"children":1708},{"style":155},[1709],{"type":43,"value":1710}," query\n",{"type":37,"tag":96,"props":1712,"children":1713},{"class":98,"line":273},[1714],{"type":37,"tag":96,"props":1715,"children":1716},{"emptyLinePlaceholder":13},[1717],{"type":43,"value":142},{"type":37,"tag":96,"props":1719,"children":1720},{"class":98,"line":282},[1721,1725,1729,1733,1738],{"type":37,"tag":96,"props":1722,"children":1723},{"style":155},[1724],{"type":43,"value":634},{"type":37,"tag":96,"props":1726,"children":1727},{"style":329},[1728],{"type":43,"value":639},{"type":37,"tag":96,"props":1730,"children":1731},{"style":155},[1732],{"type":43,"value":644},{"type":37,"tag":96,"props":1734,"children":1735},{"style":103},[1736],{"type":43,"value":1737},"\"SELECT * FROM users WHERE active = true\"",{"type":37,"tag":96,"props":1739,"children":1740},{"style":155},[1741],{"type":43,"value":168},{"type":37,"tag":96,"props":1743,"children":1744},{"class":98,"line":291},[1745,1749],{"type":37,"tag":96,"props":1746,"children":1747},{"style":149},[1748],{"type":43,"value":152},{"type":37,"tag":96,"props":1750,"children":1751},{"style":155},[1752],{"type":43,"value":1753},"(df.head())\n",{"type":37,"tag":46,"props":1755,"children":1756},{},[1757,1759,1765],{"type":43,"value":1758},"No credential parsing, no client setup. ",{"type":37,"tag":52,"props":1760,"children":1762},{"className":1761},[],[1763],{"type":43,"value":1764},"query()",{"type":43,"value":1766}," uses the asset's default connection.",{"type":37,"tag":66,"props":1768,"children":1770},{"id":1769},"_3-run-a-query",[1771],{"type":43,"value":1772},"3) Run a query",{"type":37,"tag":46,"props":1774,"children":1775},{},[1776,1777,1783,1785,1790,1792,1798,1799,1805,1806,1812,1813,1819,1821,1827,1829,1835,1837,1843,1844,1850],{"type":43,"value":536},{"type":37,"tag":52,"props":1778,"children":1780},{"className":1779},[],[1781],{"type":43,"value":1782},"query(sql, connection=None)",{"type":43,"value":1784}," function returns a ",{"type":37,"tag":1275,"props":1786,"children":1787},{},[1788],{"type":43,"value":1789},"pandas DataFrame",{"type":43,"value":1791}," for ",{"type":37,"tag":52,"props":1793,"children":1795},{"className":1794},[],[1796],{"type":43,"value":1797},"SELECT",{"type":43,"value":409},{"type":37,"tag":52,"props":1800,"children":1802},{"className":1801},[],[1803],{"type":43,"value":1804},"WITH",{"type":43,"value":409},{"type":37,"tag":52,"props":1807,"children":1809},{"className":1808},[],[1810],{"type":43,"value":1811},"SHOW",{"type":43,"value":409},{"type":37,"tag":52,"props":1814,"children":1816},{"className":1815},[],[1817],{"type":43,"value":1818},"DESCRIBE",{"type":43,"value":1820},", and ",{"type":37,"tag":52,"props":1822,"children":1824},{"className":1823},[],[1825],{"type":43,"value":1826},"EXPLAIN",{"type":43,"value":1828}," statements, and ",{"type":37,"tag":52,"props":1830,"children":1832},{"className":1831},[],[1833],{"type":43,"value":1834},"None",{"type":43,"value":1836}," for DDL/DML operations like ",{"type":37,"tag":52,"props":1838,"children":1840},{"className":1839},[],[1841],{"type":43,"value":1842},"CREATE",{"type":43,"value":1458},{"type":37,"tag":52,"props":1845,"children":1847},{"className":1846},[],[1848],{"type":43,"value":1849},"INSERT",{"type":43,"value":1851},".",{"type":37,"tag":46,"props":1853,"children":1854},{},[1855,1857,1863,1865,1869,1871,1876],{"type":43,"value":1856},"Note: if you want to write the result back to a table, don't hand-roll ",{"type":37,"tag":52,"props":1858,"children":1860},{"className":1859},[],[1861],{"type":43,"value":1862},"CREATE TABLE",{"type":43,"value":1864}," statements - use ",{"type":37,"tag":518,"props":1866,"children":1867},{"href":520},[1868],{"type":43,"value":523},{"type":43,"value":1870}," instead and return the DataFrame from ",{"type":37,"tag":52,"props":1872,"children":1874},{"className":1873},[],[1875],{"type":43,"value":214},{"type":43,"value":1851},{"type":37,"tag":86,"props":1878,"children":1880},{"className":88,"code":1879,"language":90,"meta":7,"style":7},"from bruin import query\n\n# Uses the asset's default connection\ndf = query(\"SELECT * FROM users\")\n\n# Or specify a different one\ndf = query(\"SELECT * FROM events\", connection=\"my_postgres\")\n\n# DDL/DML returns None\nquery(\"CREATE TABLE temp AS SELECT * FROM users\")\n",[1881],{"type":37,"tag":52,"props":1882,"children":1883},{"__ignoreMap":7},[1884,1903,1910,1919,1943,1950,1958,2001,2008,2016],{"type":37,"tag":96,"props":1885,"children":1886},{"class":98,"line":99},[1887,1891,1895,1899],{"type":37,"tag":96,"props":1888,"children":1889},{"style":329},[1890],{"type":43,"value":605},{"type":37,"tag":96,"props":1892,"children":1893},{"style":155},[1894],{"type":43,"value":610},{"type":37,"tag":96,"props":1896,"children":1897},{"style":329},[1898],{"type":43,"value":332},{"type":37,"tag":96,"props":1900,"children":1901},{"style":155},[1902],{"type":43,"value":1710},{"type":37,"tag":96,"props":1904,"children":1905},{"class":98,"line":109},[1906],{"type":37,"tag":96,"props":1907,"children":1908},{"emptyLinePlaceholder":13},[1909],{"type":43,"value":142},{"type":37,"tag":96,"props":1911,"children":1912},{"class":98,"line":118},[1913],{"type":37,"tag":96,"props":1914,"children":1916},{"style":1915},"--shiki-default:#6A737D",[1917],{"type":43,"value":1918},"# Uses the asset's default connection\n",{"type":37,"tag":96,"props":1920,"children":1921},{"class":98,"line":127},[1922,1926,1930,1934,1939],{"type":37,"tag":96,"props":1923,"children":1924},{"style":155},[1925],{"type":43,"value":634},{"type":37,"tag":96,"props":1927,"children":1928},{"style":329},[1929],{"type":43,"value":639},{"type":37,"tag":96,"props":1931,"children":1932},{"style":155},[1933],{"type":43,"value":644},{"type":37,"tag":96,"props":1935,"children":1936},{"style":103},[1937],{"type":43,"value":1938},"\"SELECT * FROM users\"",{"type":37,"tag":96,"props":1940,"children":1941},{"style":155},[1942],{"type":43,"value":168},{"type":37,"tag":96,"props":1944,"children":1945},{"class":98,"line":136},[1946],{"type":37,"tag":96,"props":1947,"children":1948},{"emptyLinePlaceholder":13},[1949],{"type":43,"value":142},{"type":37,"tag":96,"props":1951,"children":1952},{"class":98,"line":145},[1953],{"type":37,"tag":96,"props":1954,"children":1955},{"style":1915},[1956],{"type":43,"value":1957},"# Or specify a different one\n",{"type":37,"tag":96,"props":1959,"children":1960},{"class":98,"line":273},[1961,1965,1969,1973,1978,1982,1988,1992,1997],{"type":37,"tag":96,"props":1962,"children":1963},{"style":155},[1964],{"type":43,"value":634},{"type":37,"tag":96,"props":1966,"children":1967},{"style":329},[1968],{"type":43,"value":639},{"type":37,"tag":96,"props":1970,"children":1971},{"style":155},[1972],{"type":43,"value":644},{"type":37,"tag":96,"props":1974,"children":1975},{"style":103},[1976],{"type":43,"value":1977},"\"SELECT * FROM events\"",{"type":37,"tag":96,"props":1979,"children":1980},{"style":155},[1981],{"type":43,"value":409},{"type":37,"tag":96,"props":1983,"children":1985},{"style":1984},"--shiki-default:#FFAB70",[1986],{"type":43,"value":1987},"connection",{"type":37,"tag":96,"props":1989,"children":1990},{"style":329},[1991],{"type":43,"value":639},{"type":37,"tag":96,"props":1993,"children":1994},{"style":103},[1995],{"type":43,"value":1996},"\"my_postgres\"",{"type":37,"tag":96,"props":1998,"children":1999},{"style":155},[2000],{"type":43,"value":168},{"type":37,"tag":96,"props":2002,"children":2003},{"class":98,"line":282},[2004],{"type":37,"tag":96,"props":2005,"children":2006},{"emptyLinePlaceholder":13},[2007],{"type":43,"value":142},{"type":37,"tag":96,"props":2009,"children":2010},{"class":98,"line":291},[2011],{"type":37,"tag":96,"props":2012,"children":2013},{"style":1915},[2014],{"type":43,"value":2015},"# DDL/DML returns None\n",{"type":37,"tag":96,"props":2017,"children":2018},{"class":98,"line":300},[2019,2024,2029],{"type":37,"tag":96,"props":2020,"children":2021},{"style":155},[2022],{"type":43,"value":2023},"query(",{"type":37,"tag":96,"props":2025,"children":2026},{"style":103},[2027],{"type":43,"value":2028},"\"CREATE TABLE temp AS SELECT * FROM users\"",{"type":37,"tag":96,"props":2030,"children":2031},{"style":155},[2032],{"type":43,"value":168},{"type":37,"tag":66,"props":2034,"children":2036},{"id":2035},"_4-access-pipeline-context",[2037],{"type":43,"value":2038},"4) Access pipeline context",{"type":37,"tag":46,"props":2040,"children":2041},{},[2042,2043,2048,2050,2056],{"type":43,"value":536},{"type":37,"tag":52,"props":2044,"children":2046},{"className":2045},[],[2047],{"type":43,"value":577},{"type":43,"value":2049}," module gives typed access to Bruin's runtime environment variables without manual ",{"type":37,"tag":52,"props":2051,"children":2053},{"className":2052},[],[2054],{"type":43,"value":2055},"os.environ",{"type":43,"value":2057}," parsing:",{"type":37,"tag":86,"props":2059,"children":2061},{"className":88,"code":2060,"language":90,"meta":7,"style":7},"from bruin import query, context\n\nif context.is_full_refresh:\n    df = query(\"SELECT * FROM raw.events\")\nelse:\n    df = query(f\"\"\"\n        SELECT * FROM raw.events\n        WHERE event_date BETWEEN '{context.start_date}' AND '{context.end_date}'\n    \"\"\")\n",[2062],{"type":37,"tag":52,"props":2063,"children":2064},{"__ignoreMap":7},[2065,2084,2091,2104,2129,2142,2166,2174,2217],{"type":37,"tag":96,"props":2066,"children":2067},{"class":98,"line":99},[2068,2072,2076,2080],{"type":37,"tag":96,"props":2069,"children":2070},{"style":329},[2071],{"type":43,"value":605},{"type":37,"tag":96,"props":2073,"children":2074},{"style":155},[2075],{"type":43,"value":610},{"type":37,"tag":96,"props":2077,"children":2078},{"style":329},[2079],{"type":43,"value":332},{"type":37,"tag":96,"props":2081,"children":2082},{"style":155},[2083],{"type":43,"value":619},{"type":37,"tag":96,"props":2085,"children":2086},{"class":98,"line":109},[2087],{"type":37,"tag":96,"props":2088,"children":2089},{"emptyLinePlaceholder":13},[2090],{"type":43,"value":142},{"type":37,"tag":96,"props":2092,"children":2093},{"class":98,"line":118},[2094,2099],{"type":37,"tag":96,"props":2095,"children":2096},{"style":329},[2097],{"type":43,"value":2098},"if",{"type":37,"tag":96,"props":2100,"children":2101},{"style":155},[2102],{"type":43,"value":2103}," context.is_full_refresh:\n",{"type":37,"tag":96,"props":2105,"children":2106},{"class":98,"line":127},[2107,2112,2116,2120,2125],{"type":37,"tag":96,"props":2108,"children":2109},{"style":155},[2110],{"type":43,"value":2111},"    df ",{"type":37,"tag":96,"props":2113,"children":2114},{"style":329},[2115],{"type":43,"value":639},{"type":37,"tag":96,"props":2117,"children":2118},{"style":155},[2119],{"type":43,"value":644},{"type":37,"tag":96,"props":2121,"children":2122},{"style":103},[2123],{"type":43,"value":2124},"\"SELECT * FROM raw.events\"",{"type":37,"tag":96,"props":2126,"children":2127},{"style":155},[2128],{"type":43,"value":168},{"type":37,"tag":96,"props":2130,"children":2131},{"class":98,"line":136},[2132,2137],{"type":37,"tag":96,"props":2133,"children":2134},{"style":329},[2135],{"type":43,"value":2136},"else",{"type":37,"tag":96,"props":2138,"children":2139},{"style":155},[2140],{"type":43,"value":2141},":\n",{"type":37,"tag":96,"props":2143,"children":2144},{"class":98,"line":145},[2145,2149,2153,2157,2161],{"type":37,"tag":96,"props":2146,"children":2147},{"style":155},[2148],{"type":43,"value":2111},{"type":37,"tag":96,"props":2150,"children":2151},{"style":329},[2152],{"type":43,"value":639},{"type":37,"tag":96,"props":2154,"children":2155},{"style":155},[2156],{"type":43,"value":644},{"type":37,"tag":96,"props":2158,"children":2159},{"style":329},[2160],{"type":43,"value":649},{"type":37,"tag":96,"props":2162,"children":2163},{"style":103},[2164],{"type":43,"value":2165},"\"\"\"\n",{"type":37,"tag":96,"props":2167,"children":2168},{"class":98,"line":273},[2169],{"type":37,"tag":96,"props":2170,"children":2171},{"style":103},[2172],{"type":43,"value":2173},"        SELECT * FROM raw.events\n",{"type":37,"tag":96,"props":2175,"children":2176},{"class":98,"line":282},[2177,2182,2186,2190,2194,2199,2203,2208,2212],{"type":37,"tag":96,"props":2178,"children":2179},{"style":103},[2180],{"type":43,"value":2181},"        WHERE event_date BETWEEN '",{"type":37,"tag":96,"props":2183,"children":2184},{"style":149},[2185],{"type":43,"value":659},{"type":37,"tag":96,"props":2187,"children":2188},{"style":155},[2189],{"type":43,"value":664},{"type":37,"tag":96,"props":2191,"children":2192},{"style":149},[2193],{"type":43,"value":669},{"type":37,"tag":96,"props":2195,"children":2196},{"style":103},[2197],{"type":43,"value":2198},"' AND '",{"type":37,"tag":96,"props":2200,"children":2201},{"style":149},[2202],{"type":43,"value":659},{"type":37,"tag":96,"props":2204,"children":2205},{"style":155},[2206],{"type":43,"value":2207},"context.end_date",{"type":37,"tag":96,"props":2209,"children":2210},{"style":149},[2211],{"type":43,"value":669},{"type":37,"tag":96,"props":2213,"children":2214},{"style":103},[2215],{"type":43,"value":2216},"'\n",{"type":37,"tag":96,"props":2218,"children":2219},{"class":98,"line":291},[2220,2225],{"type":37,"tag":96,"props":2221,"children":2222},{"style":103},[2223],{"type":43,"value":2224},"    \"\"\"",{"type":37,"tag":96,"props":2226,"children":2227},{"style":155},[2228],{"type":43,"value":168},{"type":37,"tag":46,"props":2230,"children":2231},{},[2232],{"type":43,"value":2233},"Available properties include:",{"type":37,"tag":554,"props":2235,"children":2236},{},[2237,2262,2280,2291,2302,2320,2331],{"type":37,"tag":558,"props":2238,"children":2239},{},[2240,2245,2247,2252,2254,2260],{"type":37,"tag":52,"props":2241,"children":2243},{"className":2242},[],[2244],{"type":43,"value":664},{"type":43,"value":2246}," / ",{"type":37,"tag":52,"props":2248,"children":2250},{"className":2249},[],[2251],{"type":43,"value":2207},{"type":43,"value":2253}," - run window as ",{"type":37,"tag":52,"props":2255,"children":2257},{"className":2256},[],[2258],{"type":43,"value":2259},"date",{"type":43,"value":2261}," objects",{"type":37,"tag":558,"props":2263,"children":2264},{},[2265,2271,2272,2278],{"type":37,"tag":52,"props":2266,"children":2268},{"className":2267},[],[2269],{"type":43,"value":2270},"context.start_datetime",{"type":43,"value":2246},{"type":37,"tag":52,"props":2273,"children":2275},{"className":2274},[],[2276],{"type":43,"value":2277},"context.end_datetime",{"type":43,"value":2279}," - same window with time",{"type":37,"tag":558,"props":2281,"children":2282},{},[2283,2289],{"type":37,"tag":52,"props":2284,"children":2286},{"className":2285},[],[2287],{"type":43,"value":2288},"context.execution_date",{"type":43,"value":2290}," - the run's execution date",{"type":37,"tag":558,"props":2292,"children":2293},{},[2294,2300],{"type":37,"tag":52,"props":2295,"children":2297},{"className":2296},[],[2298],{"type":43,"value":2299},"context.is_full_refresh",{"type":43,"value":2301}," - boolean flag for full refreshes",{"type":37,"tag":558,"props":2303,"children":2304},{},[2305,2311,2312,2318],{"type":37,"tag":52,"props":2306,"children":2308},{"className":2307},[],[2309],{"type":43,"value":2310},"context.pipeline",{"type":43,"value":2246},{"type":37,"tag":52,"props":2313,"children":2315},{"className":2314},[],[2316],{"type":43,"value":2317},"context.asset_name",{"type":43,"value":2319}," - names of the current pipeline and asset",{"type":37,"tag":558,"props":2321,"children":2322},{},[2323,2329],{"type":37,"tag":52,"props":2324,"children":2326},{"className":2325},[],[2327],{"type":43,"value":2328},"context.run_id",{"type":43,"value":2330}," - unique identifier for the run",{"type":37,"tag":558,"props":2332,"children":2333},{},[2334,2340],{"type":37,"tag":52,"props":2335,"children":2337},{"className":2336},[],[2338],{"type":43,"value":2339},"context.vars",{"type":43,"value":2341}," - pipeline variables dict (JSON Schema types preserved)",{"type":37,"tag":66,"props":2343,"children":2345},{"id":2344},"_5-use-pipeline-variables",[2346],{"type":43,"value":2347},"5) Use pipeline variables",{"type":37,"tag":46,"props":2349,"children":2350},{},[2351,2353,2359,2361,2366],{"type":43,"value":2352},"Pipeline variables defined in ",{"type":37,"tag":52,"props":2354,"children":2356},{"className":2355},[],[2357],{"type":43,"value":2358},"pipeline.yml",{"type":43,"value":2360}," are exposed through ",{"type":37,"tag":52,"props":2362,"children":2364},{"className":2363},[],[2365],{"type":43,"value":2339},{"type":43,"value":2367}," with their types preserved:",{"type":37,"tag":86,"props":2369,"children":2371},{"className":88,"code":2370,"language":90,"meta":7,"style":7},"from bruin import query, context\n\nsegment = context.vars[\"segment\"]\nlookback = context.vars[\"lookback_days\"]\n\ndf = query(f\"\"\"\n    SELECT * FROM customers\n    WHERE segment = '{segment}'\n    AND created_at >= DATEADD(day, -{lookback}, CURRENT_DATE())\n\"\"\")\n",[2372],{"type":37,"tag":52,"props":2373,"children":2374},{"__ignoreMap":7},[2375,2394,2401,2428,2453,2460,2483,2491,2516,2542],{"type":37,"tag":96,"props":2376,"children":2377},{"class":98,"line":99},[2378,2382,2386,2390],{"type":37,"tag":96,"props":2379,"children":2380},{"style":329},[2381],{"type":43,"value":605},{"type":37,"tag":96,"props":2383,"children":2384},{"style":155},[2385],{"type":43,"value":610},{"type":37,"tag":96,"props":2387,"children":2388},{"style":329},[2389],{"type":43,"value":332},{"type":37,"tag":96,"props":2391,"children":2392},{"style":155},[2393],{"type":43,"value":619},{"type":37,"tag":96,"props":2395,"children":2396},{"class":98,"line":109},[2397],{"type":37,"tag":96,"props":2398,"children":2399},{"emptyLinePlaceholder":13},[2400],{"type":43,"value":142},{"type":37,"tag":96,"props":2402,"children":2403},{"class":98,"line":118},[2404,2409,2413,2418,2423],{"type":37,"tag":96,"props":2405,"children":2406},{"style":155},[2407],{"type":43,"value":2408},"segment ",{"type":37,"tag":96,"props":2410,"children":2411},{"style":329},[2412],{"type":43,"value":639},{"type":37,"tag":96,"props":2414,"children":2415},{"style":155},[2416],{"type":43,"value":2417}," context.vars[",{"type":37,"tag":96,"props":2419,"children":2420},{"style":103},[2421],{"type":43,"value":2422},"\"segment\"",{"type":37,"tag":96,"props":2424,"children":2425},{"style":155},[2426],{"type":43,"value":2427},"]\n",{"type":37,"tag":96,"props":2429,"children":2430},{"class":98,"line":127},[2431,2436,2440,2444,2449],{"type":37,"tag":96,"props":2432,"children":2433},{"style":155},[2434],{"type":43,"value":2435},"lookback ",{"type":37,"tag":96,"props":2437,"children":2438},{"style":329},[2439],{"type":43,"value":639},{"type":37,"tag":96,"props":2441,"children":2442},{"style":155},[2443],{"type":43,"value":2417},{"type":37,"tag":96,"props":2445,"children":2446},{"style":103},[2447],{"type":43,"value":2448},"\"lookback_days\"",{"type":37,"tag":96,"props":2450,"children":2451},{"style":155},[2452],{"type":43,"value":2427},{"type":37,"tag":96,"props":2454,"children":2455},{"class":98,"line":136},[2456],{"type":37,"tag":96,"props":2457,"children":2458},{"emptyLinePlaceholder":13},[2459],{"type":43,"value":142},{"type":37,"tag":96,"props":2461,"children":2462},{"class":98,"line":145},[2463,2467,2471,2475,2479],{"type":37,"tag":96,"props":2464,"children":2465},{"style":155},[2466],{"type":43,"value":634},{"type":37,"tag":96,"props":2468,"children":2469},{"style":329},[2470],{"type":43,"value":639},{"type":37,"tag":96,"props":2472,"children":2473},{"style":155},[2474],{"type":43,"value":644},{"type":37,"tag":96,"props":2476,"children":2477},{"style":329},[2478],{"type":43,"value":649},{"type":37,"tag":96,"props":2480,"children":2481},{"style":103},[2482],{"type":43,"value":2165},{"type":37,"tag":96,"props":2484,"children":2485},{"class":98,"line":273},[2486],{"type":37,"tag":96,"props":2487,"children":2488},{"style":103},[2489],{"type":43,"value":2490},"    SELECT * FROM customers\n",{"type":37,"tag":96,"props":2492,"children":2493},{"class":98,"line":282},[2494,2499,2503,2508,2512],{"type":37,"tag":96,"props":2495,"children":2496},{"style":103},[2497],{"type":43,"value":2498},"    WHERE segment = '",{"type":37,"tag":96,"props":2500,"children":2501},{"style":149},[2502],{"type":43,"value":659},{"type":37,"tag":96,"props":2504,"children":2505},{"style":155},[2506],{"type":43,"value":2507},"segment",{"type":37,"tag":96,"props":2509,"children":2510},{"style":149},[2511],{"type":43,"value":669},{"type":37,"tag":96,"props":2513,"children":2514},{"style":103},[2515],{"type":43,"value":2216},{"type":37,"tag":96,"props":2517,"children":2518},{"class":98,"line":291},[2519,2524,2528,2533,2537],{"type":37,"tag":96,"props":2520,"children":2521},{"style":103},[2522],{"type":43,"value":2523},"    AND created_at >= DATEADD(day, -",{"type":37,"tag":96,"props":2525,"children":2526},{"style":149},[2527],{"type":43,"value":659},{"type":37,"tag":96,"props":2529,"children":2530},{"style":155},[2531],{"type":43,"value":2532},"lookback",{"type":37,"tag":96,"props":2534,"children":2535},{"style":149},[2536],{"type":43,"value":669},{"type":37,"tag":96,"props":2538,"children":2539},{"style":103},[2540],{"type":43,"value":2541},", CURRENT_DATE())\n",{"type":37,"tag":96,"props":2543,"children":2544},{"class":98,"line":300},[2545,2550],{"type":37,"tag":96,"props":2546,"children":2547},{"style":103},[2548],{"type":43,"value":2549},"\"\"\"",{"type":37,"tag":96,"props":2551,"children":2552},{"style":155},[2553],{"type":43,"value":168},{"type":37,"tag":66,"props":2555,"children":2557},{"id":2556},"_6-work-with-multiple-connections",[2558],{"type":43,"value":2559},"6) Work with multiple connections",{"type":37,"tag":46,"props":2561,"children":2562},{},[2563,2565,2571],{"type":43,"value":2564},"When you need a second connection, list it under ",{"type":37,"tag":52,"props":2566,"children":2568},{"className":2567},[],[2569],{"type":43,"value":2570},"secrets",{"type":43,"value":2572}," in the asset metadata:",{"type":37,"tag":86,"props":2574,"children":2576},{"className":88,"code":2575,"language":90,"meta":7,"style":7},"\"\"\" @bruin\nname: staging.active_users\nconnection: my_bigquery\nsecrets:\n    - key: my_postgres\n@bruin \"\"\"\n\nfrom bruin import query, get_connection\n\n# Reads from Postgres\ndf = query(\"SELECT * FROM users WHERE active = true\", connection=\"my_postgres\")\n\n# Writes to BigQuery using the typed client\nbq = get_connection(\"my_bigquery\")\ndf.to_gbq(\n    \"staging.active_users\",\n    project_id=bq.raw[\"project_id\"],\n    credentials=bq.credentials,\n    if_exists=\"replace\",\n)\n",[2577],{"type":37,"tag":52,"props":2578,"children":2579},{"__ignoreMap":7},[2580,2587,2595,2602,2610,2618,2625,2632,2652,2659,2667,2706,2713,2721,2747,2755,2768,2796,2814,2836],{"type":37,"tag":96,"props":2581,"children":2582},{"class":98,"line":99},[2583],{"type":37,"tag":96,"props":2584,"children":2585},{"style":103},[2586],{"type":43,"value":1660},{"type":37,"tag":96,"props":2588,"children":2589},{"class":98,"line":109},[2590],{"type":37,"tag":96,"props":2591,"children":2592},{"style":103},[2593],{"type":43,"value":2594},"name: staging.active_users\n",{"type":37,"tag":96,"props":2596,"children":2597},{"class":98,"line":118},[2598],{"type":37,"tag":96,"props":2599,"children":2600},{"style":103},[2601],{"type":43,"value":246},{"type":37,"tag":96,"props":2603,"children":2604},{"class":98,"line":127},[2605],{"type":37,"tag":96,"props":2606,"children":2607},{"style":103},[2608],{"type":43,"value":2609},"secrets:\n",{"type":37,"tag":96,"props":2611,"children":2612},{"class":98,"line":136},[2613],{"type":37,"tag":96,"props":2614,"children":2615},{"style":103},[2616],{"type":43,"value":2617},"    - key: my_postgres\n",{"type":37,"tag":96,"props":2619,"children":2620},{"class":98,"line":145},[2621],{"type":37,"tag":96,"props":2622,"children":2623},{"style":103},[2624],{"type":43,"value":1683},{"type":37,"tag":96,"props":2626,"children":2627},{"class":98,"line":273},[2628],{"type":37,"tag":96,"props":2629,"children":2630},{"emptyLinePlaceholder":13},[2631],{"type":43,"value":142},{"type":37,"tag":96,"props":2633,"children":2634},{"class":98,"line":282},[2635,2639,2643,2647],{"type":37,"tag":96,"props":2636,"children":2637},{"style":329},[2638],{"type":43,"value":605},{"type":37,"tag":96,"props":2640,"children":2641},{"style":155},[2642],{"type":43,"value":610},{"type":37,"tag":96,"props":2644,"children":2645},{"style":329},[2646],{"type":43,"value":332},{"type":37,"tag":96,"props":2648,"children":2649},{"style":155},[2650],{"type":43,"value":2651}," query, get_connection\n",{"type":37,"tag":96,"props":2653,"children":2654},{"class":98,"line":291},[2655],{"type":37,"tag":96,"props":2656,"children":2657},{"emptyLinePlaceholder":13},[2658],{"type":43,"value":142},{"type":37,"tag":96,"props":2660,"children":2661},{"class":98,"line":300},[2662],{"type":37,"tag":96,"props":2663,"children":2664},{"style":1915},[2665],{"type":43,"value":2666},"# Reads from Postgres\n",{"type":37,"tag":96,"props":2668,"children":2669},{"class":98,"line":309},[2670,2674,2678,2682,2686,2690,2694,2698,2702],{"type":37,"tag":96,"props":2671,"children":2672},{"style":155},[2673],{"type":43,"value":634},{"type":37,"tag":96,"props":2675,"children":2676},{"style":329},[2677],{"type":43,"value":639},{"type":37,"tag":96,"props":2679,"children":2680},{"style":155},[2681],{"type":43,"value":644},{"type":37,"tag":96,"props":2683,"children":2684},{"style":103},[2685],{"type":43,"value":1737},{"type":37,"tag":96,"props":2687,"children":2688},{"style":155},[2689],{"type":43,"value":409},{"type":37,"tag":96,"props":2691,"children":2692},{"style":1984},[2693],{"type":43,"value":1987},{"type":37,"tag":96,"props":2695,"children":2696},{"style":329},[2697],{"type":43,"value":639},{"type":37,"tag":96,"props":2699,"children":2700},{"style":103},[2701],{"type":43,"value":1996},{"type":37,"tag":96,"props":2703,"children":2704},{"style":155},[2705],{"type":43,"value":168},{"type":37,"tag":96,"props":2707,"children":2708},{"class":98,"line":317},[2709],{"type":37,"tag":96,"props":2710,"children":2711},{"emptyLinePlaceholder":13},[2712],{"type":43,"value":142},{"type":37,"tag":96,"props":2714,"children":2715},{"class":98,"line":325},[2716],{"type":37,"tag":96,"props":2717,"children":2718},{"style":1915},[2719],{"type":43,"value":2720},"# Writes to BigQuery using the typed client\n",{"type":37,"tag":96,"props":2722,"children":2723},{"class":98,"line":350},[2724,2729,2733,2738,2743],{"type":37,"tag":96,"props":2725,"children":2726},{"style":155},[2727],{"type":43,"value":2728},"bq ",{"type":37,"tag":96,"props":2730,"children":2731},{"style":329},[2732],{"type":43,"value":639},{"type":37,"tag":96,"props":2734,"children":2735},{"style":155},[2736],{"type":43,"value":2737}," get_connection(",{"type":37,"tag":96,"props":2739,"children":2740},{"style":103},[2741],{"type":43,"value":2742},"\"my_bigquery\"",{"type":37,"tag":96,"props":2744,"children":2745},{"style":155},[2746],{"type":43,"value":168},{"type":37,"tag":96,"props":2748,"children":2749},{"class":98,"line":358},[2750],{"type":37,"tag":96,"props":2751,"children":2752},{"style":155},[2753],{"type":43,"value":2754},"df.to_gbq(\n",{"type":37,"tag":96,"props":2756,"children":2757},{"class":98,"line":378},[2758,2763],{"type":37,"tag":96,"props":2759,"children":2760},{"style":103},[2761],{"type":43,"value":2762},"    \"staging.active_users\"",{"type":37,"tag":96,"props":2764,"children":2765},{"style":155},[2766],{"type":43,"value":2767},",\n",{"type":37,"tag":96,"props":2769,"children":2771},{"class":98,"line":2770},17,[2772,2777,2781,2786,2791],{"type":37,"tag":96,"props":2773,"children":2774},{"style":1984},[2775],{"type":43,"value":2776},"    project_id",{"type":37,"tag":96,"props":2778,"children":2779},{"style":329},[2780],{"type":43,"value":639},{"type":37,"tag":96,"props":2782,"children":2783},{"style":155},[2784],{"type":43,"value":2785},"bq.raw[",{"type":37,"tag":96,"props":2787,"children":2788},{"style":103},[2789],{"type":43,"value":2790},"\"project_id\"",{"type":37,"tag":96,"props":2792,"children":2793},{"style":155},[2794],{"type":43,"value":2795},"],\n",{"type":37,"tag":96,"props":2797,"children":2799},{"class":98,"line":2798},18,[2800,2805,2809],{"type":37,"tag":96,"props":2801,"children":2802},{"style":1984},[2803],{"type":43,"value":2804},"    credentials",{"type":37,"tag":96,"props":2806,"children":2807},{"style":329},[2808],{"type":43,"value":639},{"type":37,"tag":96,"props":2810,"children":2811},{"style":155},[2812],{"type":43,"value":2813},"bq.credentials,\n",{"type":37,"tag":96,"props":2815,"children":2817},{"class":98,"line":2816},19,[2818,2823,2827,2832],{"type":37,"tag":96,"props":2819,"children":2820},{"style":1984},[2821],{"type":43,"value":2822},"    if_exists",{"type":37,"tag":96,"props":2824,"children":2825},{"style":329},[2826],{"type":43,"value":639},{"type":37,"tag":96,"props":2828,"children":2829},{"style":103},[2830],{"type":43,"value":2831},"\"replace\"",{"type":37,"tag":96,"props":2833,"children":2834},{"style":155},[2835],{"type":43,"value":2767},{"type":37,"tag":96,"props":2837,"children":2839},{"class":98,"line":2838},20,[2840],{"type":37,"tag":96,"props":2841,"children":2842},{"style":155},[2843],{"type":43,"value":168},{"type":37,"tag":46,"props":2845,"children":2846},{},[2847,2849,2853,2855,2860,2862,2867,2868,2873,2874,2879,2880,2885],{"type":43,"value":2848},"Writing data manually like this works, but for most cases you're better off using ",{"type":37,"tag":518,"props":2850,"children":2851},{"href":520},[2852],{"type":43,"value":523},{"type":43,"value":2854}," - return the DataFrame from ",{"type":37,"tag":52,"props":2856,"children":2858},{"className":2857},[],[2859],{"type":43,"value":214},{"type":43,"value":2861}," and let Bruin handle the load with a proper strategy (",{"type":37,"tag":52,"props":2863,"children":2865},{"className":2864},[],[2866],{"type":43,"value":506},{"type":43,"value":409},{"type":37,"tag":52,"props":2869,"children":2871},{"className":2870},[],[2872],{"type":43,"value":491},{"type":43,"value":409},{"type":37,"tag":52,"props":2875,"children":2877},{"className":2876},[],[2878],{"type":43,"value":498},{"type":43,"value":500},{"type":37,"tag":52,"props":2881,"children":2883},{"className":2882},[],[2884],{"type":43,"value":484},{"type":43,"value":2886},").",{"type":37,"tag":66,"props":2888,"children":2890},{"id":2889},"_7-combine-the-sdk-with-materialization",[2891],{"type":43,"value":2892},"7) Combine the SDK with materialization",{"type":37,"tag":46,"props":2894,"children":2895},{},[2896,2898,2902],{"type":43,"value":2897},"The SDK and ",{"type":37,"tag":518,"props":2899,"children":2900},{"href":520},[2901],{"type":43,"value":523},{"type":43,"value":2903}," compose cleanly: the SDK reads and transforms; materialization writes.",{"type":37,"tag":86,"props":2905,"children":2907},{"className":88,"code":2906,"language":90,"meta":7,"style":7},"\"\"\"@bruin\nname: analytics.active_users\nimage: python:3.13\nconnection: my_bigquery\n\nmaterialization:\n  type: table\n  strategy: merge\n\ncolumns:\n  - name: id\n    type: integer\n    primary_key: true\n  - name: name\n    type: string\n    update_on_merge: true\n@bruin\"\"\"\n\nfrom bruin import query, context\n\ndef materialize():\n    if context.is_full_refresh:\n        return query(\"SELECT id, name FROM raw.users WHERE active = true\")\n\n    return query(f\"\"\"\n        SELECT id, name FROM raw.users\n        WHERE active = true\n          AND last_seen_at BETWEEN '{context.start_date}' AND '{context.end_date}'\n    \"\"\")\n",[2908],{"type":37,"tag":52,"props":2909,"children":2910},{"__ignoreMap":7},[2911,2918,2926,2933,2940,2947,2954,2961,2968,2975,2982,2989,2996,3003,3011,3019,3027,3034,3041,3060,3067,3083,3096,3118,3126,3146,3155,3164,3205],{"type":37,"tag":96,"props":2912,"children":2913},{"class":98,"line":99},[2914],{"type":37,"tag":96,"props":2915,"children":2916},{"style":103},[2917],{"type":43,"value":106},{"type":37,"tag":96,"props":2919,"children":2920},{"class":98,"line":109},[2921],{"type":37,"tag":96,"props":2922,"children":2923},{"style":103},[2924],{"type":43,"value":2925},"name: analytics.active_users\n",{"type":37,"tag":96,"props":2927,"children":2928},{"class":98,"line":118},[2929],{"type":37,"tag":96,"props":2930,"children":2931},{"style":103},[2932],{"type":43,"value":124},{"type":37,"tag":96,"props":2934,"children":2935},{"class":98,"line":127},[2936],{"type":37,"tag":96,"props":2937,"children":2938},{"style":103},[2939],{"type":43,"value":246},{"type":37,"tag":96,"props":2941,"children":2942},{"class":98,"line":136},[2943],{"type":37,"tag":96,"props":2944,"children":2945},{"emptyLinePlaceholder":13},[2946],{"type":43,"value":142},{"type":37,"tag":96,"props":2948,"children":2949},{"class":98,"line":145},[2950],{"type":37,"tag":96,"props":2951,"children":2952},{"style":103},[2953],{"type":43,"value":254},{"type":37,"tag":96,"props":2955,"children":2956},{"class":98,"line":273},[2957],{"type":37,"tag":96,"props":2958,"children":2959},{"style":103},[2960],{"type":43,"value":262},{"type":37,"tag":96,"props":2962,"children":2963},{"class":98,"line":282},[2964],{"type":37,"tag":96,"props":2965,"children":2966},{"style":103},[2967],{"type":43,"value":270},{"type":37,"tag":96,"props":2969,"children":2970},{"class":98,"line":291},[2971],{"type":37,"tag":96,"props":2972,"children":2973},{"emptyLinePlaceholder":13},[2974],{"type":43,"value":142},{"type":37,"tag":96,"props":2976,"children":2977},{"class":98,"line":300},[2978],{"type":37,"tag":96,"props":2979,"children":2980},{"style":103},[2981],{"type":43,"value":279},{"type":37,"tag":96,"props":2983,"children":2984},{"class":98,"line":309},[2985],{"type":37,"tag":96,"props":2986,"children":2987},{"style":103},[2988],{"type":43,"value":288},{"type":37,"tag":96,"props":2990,"children":2991},{"class":98,"line":317},[2992],{"type":37,"tag":96,"props":2993,"children":2994},{"style":103},[2995],{"type":43,"value":297},{"type":37,"tag":96,"props":2997,"children":2998},{"class":98,"line":325},[2999],{"type":37,"tag":96,"props":3000,"children":3001},{"style":103},[3002],{"type":43,"value":306},{"type":37,"tag":96,"props":3004,"children":3005},{"class":98,"line":350},[3006],{"type":37,"tag":96,"props":3007,"children":3008},{"style":103},[3009],{"type":43,"value":3010},"  - name: name\n",{"type":37,"tag":96,"props":3012,"children":3013},{"class":98,"line":358},[3014],{"type":37,"tag":96,"props":3015,"children":3016},{"style":103},[3017],{"type":43,"value":3018},"    type: string\n",{"type":37,"tag":96,"props":3020,"children":3021},{"class":98,"line":378},[3022],{"type":37,"tag":96,"props":3023,"children":3024},{"style":103},[3025],{"type":43,"value":3026},"    update_on_merge: true\n",{"type":37,"tag":96,"props":3028,"children":3029},{"class":98,"line":2770},[3030],{"type":37,"tag":96,"props":3031,"children":3032},{"style":103},[3033],{"type":43,"value":133},{"type":37,"tag":96,"props":3035,"children":3036},{"class":98,"line":2798},[3037],{"type":37,"tag":96,"props":3038,"children":3039},{"emptyLinePlaceholder":13},[3040],{"type":43,"value":142},{"type":37,"tag":96,"props":3042,"children":3043},{"class":98,"line":2816},[3044,3048,3052,3056],{"type":37,"tag":96,"props":3045,"children":3046},{"style":329},[3047],{"type":43,"value":605},{"type":37,"tag":96,"props":3049,"children":3050},{"style":155},[3051],{"type":43,"value":610},{"type":37,"tag":96,"props":3053,"children":3054},{"style":329},[3055],{"type":43,"value":332},{"type":37,"tag":96,"props":3057,"children":3058},{"style":155},[3059],{"type":43,"value":619},{"type":37,"tag":96,"props":3061,"children":3062},{"class":98,"line":2838},[3063],{"type":37,"tag":96,"props":3064,"children":3065},{"emptyLinePlaceholder":13},[3066],{"type":43,"value":142},{"type":37,"tag":96,"props":3068,"children":3070},{"class":98,"line":3069},21,[3071,3075,3079],{"type":37,"tag":96,"props":3072,"children":3073},{"style":329},[3074],{"type":43,"value":364},{"type":37,"tag":96,"props":3076,"children":3077},{"style":367},[3078],{"type":43,"value":370},{"type":37,"tag":96,"props":3080,"children":3081},{"style":155},[3082],{"type":43,"value":375},{"type":37,"tag":96,"props":3084,"children":3086},{"class":98,"line":3085},22,[3087,3092],{"type":37,"tag":96,"props":3088,"children":3089},{"style":329},[3090],{"type":43,"value":3091},"    if",{"type":37,"tag":96,"props":3093,"children":3094},{"style":155},[3095],{"type":43,"value":2103},{"type":37,"tag":96,"props":3097,"children":3099},{"class":98,"line":3098},23,[3100,3105,3109,3114],{"type":37,"tag":96,"props":3101,"children":3102},{"style":329},[3103],{"type":43,"value":3104},"        return",{"type":37,"tag":96,"props":3106,"children":3107},{"style":155},[3108],{"type":43,"value":644},{"type":37,"tag":96,"props":3110,"children":3111},{"style":103},[3112],{"type":43,"value":3113},"\"SELECT id, name FROM raw.users WHERE active = true\"",{"type":37,"tag":96,"props":3115,"children":3116},{"style":155},[3117],{"type":43,"value":168},{"type":37,"tag":96,"props":3119,"children":3121},{"class":98,"line":3120},24,[3122],{"type":37,"tag":96,"props":3123,"children":3124},{"emptyLinePlaceholder":13},[3125],{"type":43,"value":142},{"type":37,"tag":96,"props":3127,"children":3129},{"class":98,"line":3128},25,[3130,3134,3138,3142],{"type":37,"tag":96,"props":3131,"children":3132},{"style":329},[3133],{"type":43,"value":384},{"type":37,"tag":96,"props":3135,"children":3136},{"style":155},[3137],{"type":43,"value":644},{"type":37,"tag":96,"props":3139,"children":3140},{"style":329},[3141],{"type":43,"value":649},{"type":37,"tag":96,"props":3143,"children":3144},{"style":103},[3145],{"type":43,"value":2165},{"type":37,"tag":96,"props":3147,"children":3149},{"class":98,"line":3148},26,[3150],{"type":37,"tag":96,"props":3151,"children":3152},{"style":103},[3153],{"type":43,"value":3154},"        SELECT id, name FROM raw.users\n",{"type":37,"tag":96,"props":3156,"children":3158},{"class":98,"line":3157},27,[3159],{"type":37,"tag":96,"props":3160,"children":3161},{"style":103},[3162],{"type":43,"value":3163},"        WHERE active = true\n",{"type":37,"tag":96,"props":3165,"children":3167},{"class":98,"line":3166},28,[3168,3173,3177,3181,3185,3189,3193,3197,3201],{"type":37,"tag":96,"props":3169,"children":3170},{"style":103},[3171],{"type":43,"value":3172},"          AND last_seen_at BETWEEN '",{"type":37,"tag":96,"props":3174,"children":3175},{"style":149},[3176],{"type":43,"value":659},{"type":37,"tag":96,"props":3178,"children":3179},{"style":155},[3180],{"type":43,"value":664},{"type":37,"tag":96,"props":3182,"children":3183},{"style":149},[3184],{"type":43,"value":669},{"type":37,"tag":96,"props":3186,"children":3187},{"style":103},[3188],{"type":43,"value":2198},{"type":37,"tag":96,"props":3190,"children":3191},{"style":149},[3192],{"type":43,"value":659},{"type":37,"tag":96,"props":3194,"children":3195},{"style":155},[3196],{"type":43,"value":2207},{"type":37,"tag":96,"props":3198,"children":3199},{"style":149},[3200],{"type":43,"value":669},{"type":37,"tag":96,"props":3202,"children":3203},{"style":103},[3204],{"type":43,"value":2216},{"type":37,"tag":96,"props":3206,"children":3208},{"class":98,"line":3207},29,[3209,3213],{"type":37,"tag":96,"props":3210,"children":3211},{"style":103},[3212],{"type":43,"value":2224},{"type":37,"tag":96,"props":3214,"children":3215},{"style":155},[3216],{"type":43,"value":168},{"type":37,"tag":46,"props":3218,"children":3219},{},[3220,3222,3227,3229,3235],{"type":43,"value":3221},"Bruin calls ",{"type":37,"tag":52,"props":3223,"children":3225},{"className":3224},[],[3226],{"type":43,"value":214},{"type":43,"value":3228},", captures the returned DataFrame, and merges it into ",{"type":37,"tag":52,"props":3230,"children":3232},{"className":3231},[],[3233],{"type":43,"value":3234},"analytics.active_users",{"type":43,"value":3236}," using the primary key you declared.",{"type":37,"tag":66,"props":3238,"children":3240},{"id":3239},"_8-use-typed-connection-objects",[3241],{"type":43,"value":3242},"8) Use typed connection objects",{"type":37,"tag":46,"props":3244,"children":3245},{},[3246,3251],{"type":37,"tag":52,"props":3247,"children":3249},{"className":3248},[],[3250],{"type":43,"value":588},{"type":43,"value":3252}," returns an object with lazy-initialized database clients:",{"type":37,"tag":86,"props":3254,"children":3256},{"className":88,"code":3255,"language":90,"meta":7,"style":7},"from bruin import get_connection\n\nconn = get_connection(\"my_bigquery\")\n\nconn.name     # Connection name\nconn.type     # Connection type string\nconn.raw      # Parsed connection JSON\nconn.client   # Native client, initialized on first access\ndf = conn.query(\"SELECT * FROM users\")\n",[3257],{"type":37,"tag":52,"props":3258,"children":3259},{"__ignoreMap":7},[3260,3280,3287,3311,3318,3331,3344,3357,3370],{"type":37,"tag":96,"props":3261,"children":3262},{"class":98,"line":99},[3263,3267,3271,3275],{"type":37,"tag":96,"props":3264,"children":3265},{"style":329},[3266],{"type":43,"value":605},{"type":37,"tag":96,"props":3268,"children":3269},{"style":155},[3270],{"type":43,"value":610},{"type":37,"tag":96,"props":3272,"children":3273},{"style":329},[3274],{"type":43,"value":332},{"type":37,"tag":96,"props":3276,"children":3277},{"style":155},[3278],{"type":43,"value":3279}," get_connection\n",{"type":37,"tag":96,"props":3281,"children":3282},{"class":98,"line":109},[3283],{"type":37,"tag":96,"props":3284,"children":3285},{"emptyLinePlaceholder":13},[3286],{"type":43,"value":142},{"type":37,"tag":96,"props":3288,"children":3289},{"class":98,"line":118},[3290,3295,3299,3303,3307],{"type":37,"tag":96,"props":3291,"children":3292},{"style":155},[3293],{"type":43,"value":3294},"conn ",{"type":37,"tag":96,"props":3296,"children":3297},{"style":329},[3298],{"type":43,"value":639},{"type":37,"tag":96,"props":3300,"children":3301},{"style":155},[3302],{"type":43,"value":2737},{"type":37,"tag":96,"props":3304,"children":3305},{"style":103},[3306],{"type":43,"value":2742},{"type":37,"tag":96,"props":3308,"children":3309},{"style":155},[3310],{"type":43,"value":168},{"type":37,"tag":96,"props":3312,"children":3313},{"class":98,"line":127},[3314],{"type":37,"tag":96,"props":3315,"children":3316},{"emptyLinePlaceholder":13},[3317],{"type":43,"value":142},{"type":37,"tag":96,"props":3319,"children":3320},{"class":98,"line":136},[3321,3326],{"type":37,"tag":96,"props":3322,"children":3323},{"style":155},[3324],{"type":43,"value":3325},"conn.name     ",{"type":37,"tag":96,"props":3327,"children":3328},{"style":1915},[3329],{"type":43,"value":3330},"# Connection name\n",{"type":37,"tag":96,"props":3332,"children":3333},{"class":98,"line":145},[3334,3339],{"type":37,"tag":96,"props":3335,"children":3336},{"style":155},[3337],{"type":43,"value":3338},"conn.type     ",{"type":37,"tag":96,"props":3340,"children":3341},{"style":1915},[3342],{"type":43,"value":3343},"# Connection type string\n",{"type":37,"tag":96,"props":3345,"children":3346},{"class":98,"line":273},[3347,3352],{"type":37,"tag":96,"props":3348,"children":3349},{"style":155},[3350],{"type":43,"value":3351},"conn.raw      ",{"type":37,"tag":96,"props":3353,"children":3354},{"style":1915},[3355],{"type":43,"value":3356},"# Parsed connection JSON\n",{"type":37,"tag":96,"props":3358,"children":3359},{"class":98,"line":282},[3360,3365],{"type":37,"tag":96,"props":3361,"children":3362},{"style":155},[3363],{"type":43,"value":3364},"conn.client   ",{"type":37,"tag":96,"props":3366,"children":3367},{"style":1915},[3368],{"type":43,"value":3369},"# Native client, initialized on first access\n",{"type":37,"tag":96,"props":3371,"children":3372},{"class":98,"line":291},[3373,3377,3381,3386,3390],{"type":37,"tag":96,"props":3374,"children":3375},{"style":155},[3376],{"type":43,"value":634},{"type":37,"tag":96,"props":3378,"children":3379},{"style":329},[3380],{"type":43,"value":639},{"type":37,"tag":96,"props":3382,"children":3383},{"style":155},[3384],{"type":43,"value":3385}," conn.query(",{"type":37,"tag":96,"props":3387,"children":3388},{"style":103},[3389],{"type":43,"value":1938},{"type":37,"tag":96,"props":3391,"children":3392},{"style":155},[3393],{"type":43,"value":168},{"type":37,"tag":46,"props":3395,"children":3396},{},[3397,3399,3405],{"type":43,"value":3398},"Client types returned by ",{"type":37,"tag":52,"props":3400,"children":3402},{"className":3401},[],[3403],{"type":43,"value":3404},"conn.client",{"type":43,"value":3406},":",{"type":37,"tag":554,"props":3408,"children":3409},{},[3410,3427,3443,3466,3482,3498],{"type":37,"tag":558,"props":3411,"children":3412},{},[3413,3419,3421],{"type":37,"tag":52,"props":3414,"children":3416},{"className":3415},[],[3417],{"type":43,"value":3418},"google_cloud_platform",{"type":43,"value":3420}," → ",{"type":37,"tag":52,"props":3422,"children":3424},{"className":3423},[],[3425],{"type":43,"value":3426},"bigquery.Client",{"type":37,"tag":558,"props":3428,"children":3429},{},[3430,3436,3437],{"type":37,"tag":52,"props":3431,"children":3433},{"className":3432},[],[3434],{"type":43,"value":3435},"snowflake",{"type":43,"value":3420},{"type":37,"tag":52,"props":3438,"children":3440},{"className":3439},[],[3441],{"type":43,"value":3442},"snowflake.connector.Connection",{"type":37,"tag":558,"props":3444,"children":3445},{},[3446,3452,3453,3459,3460],{"type":37,"tag":52,"props":3447,"children":3449},{"className":3448},[],[3450],{"type":43,"value":3451},"postgres",{"type":43,"value":2246},{"type":37,"tag":52,"props":3454,"children":3456},{"className":3455},[],[3457],{"type":43,"value":3458},"redshift",{"type":43,"value":3420},{"type":37,"tag":52,"props":3461,"children":3463},{"className":3462},[],[3464],{"type":43,"value":3465},"psycopg2.connection",{"type":37,"tag":558,"props":3467,"children":3468},{},[3469,3475,3476],{"type":37,"tag":52,"props":3470,"children":3472},{"className":3471},[],[3473],{"type":43,"value":3474},"mssql",{"type":43,"value":3420},{"type":37,"tag":52,"props":3477,"children":3479},{"className":3478},[],[3480],{"type":43,"value":3481},"pymssql.Connection",{"type":37,"tag":558,"props":3483,"children":3484},{},[3485,3491,3492],{"type":37,"tag":52,"props":3486,"children":3488},{"className":3487},[],[3489],{"type":43,"value":3490},"mysql",{"type":43,"value":3420},{"type":37,"tag":52,"props":3493,"children":3495},{"className":3494},[],[3496],{"type":43,"value":3497},"mysql.connector.Connection",{"type":37,"tag":558,"props":3499,"children":3500},{},[3501,3507,3508],{"type":37,"tag":52,"props":3502,"children":3504},{"className":3503},[],[3505],{"type":43,"value":3506},"duckdb",{"type":43,"value":3420},{"type":37,"tag":52,"props":3509,"children":3511},{"className":3510},[],[3512],{"type":43,"value":3513},"duckdb.DuckDBPyConnection",{"type":37,"tag":46,"props":3515,"children":3516},{},[3517,3519,3525,3526,3532,3533,3539],{"type":43,"value":3518},"GCP connections also expose ",{"type":37,"tag":52,"props":3520,"children":3522},{"className":3521},[],[3523],{"type":43,"value":3524},"conn.bigquery()",{"type":43,"value":409},{"type":37,"tag":52,"props":3527,"children":3529},{"className":3528},[],[3530],{"type":43,"value":3531},"conn.sheets()",{"type":43,"value":1820},{"type":37,"tag":52,"props":3534,"children":3536},{"className":3535},[],[3537],{"type":43,"value":3538},"conn.credentials",{"type":43,"value":3540}," for finer-grained service access.",{"type":37,"tag":66,"props":3542,"children":3544},{"id":3543},"_9-handle-errors",[3545],{"type":43,"value":3546},"9) Handle errors",{"type":37,"tag":46,"props":3548,"children":3549},{},[3550],{"type":43,"value":3551},"The SDK ships a small exception hierarchy so you can catch specific failure modes:",{"type":37,"tag":86,"props":3553,"children":3555},{"className":88,"code":3554,"language":90,"meta":7,"style":7},"from bruin.exceptions import (\n    BruinError,                # base class\n    ConnectionNotFoundError,   # connection name unknown\n    ConnectionParseError,      # invalid connection JSON\n    ConnectionTypeError,       # unsupported connection type\n    QueryError,                # SQL execution failure\n)\n\ntry:\n    df = query(\"SELECT * FROM users\")\nexcept QueryError as e:\n    print(f\"Query failed: {e}\")\n",[3556],{"type":37,"tag":52,"props":3557,"children":3558},{"__ignoreMap":7},[3559,3580,3593,3606,3619,3632,3645,3652,3659,3671,3694,3716],{"type":37,"tag":96,"props":3560,"children":3561},{"class":98,"line":99},[3562,3566,3571,3575],{"type":37,"tag":96,"props":3563,"children":3564},{"style":329},[3565],{"type":43,"value":605},{"type":37,"tag":96,"props":3567,"children":3568},{"style":155},[3569],{"type":43,"value":3570}," bruin.exceptions ",{"type":37,"tag":96,"props":3572,"children":3573},{"style":329},[3574],{"type":43,"value":332},{"type":37,"tag":96,"props":3576,"children":3577},{"style":155},[3578],{"type":43,"value":3579}," (\n",{"type":37,"tag":96,"props":3581,"children":3582},{"class":98,"line":109},[3583,3588],{"type":37,"tag":96,"props":3584,"children":3585},{"style":155},[3586],{"type":43,"value":3587},"    BruinError,                ",{"type":37,"tag":96,"props":3589,"children":3590},{"style":1915},[3591],{"type":43,"value":3592},"# base class\n",{"type":37,"tag":96,"props":3594,"children":3595},{"class":98,"line":118},[3596,3601],{"type":37,"tag":96,"props":3597,"children":3598},{"style":155},[3599],{"type":43,"value":3600},"    ConnectionNotFoundError,   ",{"type":37,"tag":96,"props":3602,"children":3603},{"style":1915},[3604],{"type":43,"value":3605},"# connection name unknown\n",{"type":37,"tag":96,"props":3607,"children":3608},{"class":98,"line":127},[3609,3614],{"type":37,"tag":96,"props":3610,"children":3611},{"style":155},[3612],{"type":43,"value":3613},"    ConnectionParseError,      ",{"type":37,"tag":96,"props":3615,"children":3616},{"style":1915},[3617],{"type":43,"value":3618},"# invalid connection JSON\n",{"type":37,"tag":96,"props":3620,"children":3621},{"class":98,"line":136},[3622,3627],{"type":37,"tag":96,"props":3623,"children":3624},{"style":155},[3625],{"type":43,"value":3626},"    ConnectionTypeError,       ",{"type":37,"tag":96,"props":3628,"children":3629},{"style":1915},[3630],{"type":43,"value":3631},"# unsupported connection type\n",{"type":37,"tag":96,"props":3633,"children":3634},{"class":98,"line":145},[3635,3640],{"type":37,"tag":96,"props":3636,"children":3637},{"style":155},[3638],{"type":43,"value":3639},"    QueryError,                ",{"type":37,"tag":96,"props":3641,"children":3642},{"style":1915},[3643],{"type":43,"value":3644},"# SQL execution failure\n",{"type":37,"tag":96,"props":3646,"children":3647},{"class":98,"line":273},[3648],{"type":37,"tag":96,"props":3649,"children":3650},{"style":155},[3651],{"type":43,"value":168},{"type":37,"tag":96,"props":3653,"children":3654},{"class":98,"line":282},[3655],{"type":37,"tag":96,"props":3656,"children":3657},{"emptyLinePlaceholder":13},[3658],{"type":43,"value":142},{"type":37,"tag":96,"props":3660,"children":3661},{"class":98,"line":291},[3662,3667],{"type":37,"tag":96,"props":3663,"children":3664},{"style":329},[3665],{"type":43,"value":3666},"try",{"type":37,"tag":96,"props":3668,"children":3669},{"style":155},[3670],{"type":43,"value":2141},{"type":37,"tag":96,"props":3672,"children":3673},{"class":98,"line":300},[3674,3678,3682,3686,3690],{"type":37,"tag":96,"props":3675,"children":3676},{"style":155},[3677],{"type":43,"value":2111},{"type":37,"tag":96,"props":3679,"children":3680},{"style":329},[3681],{"type":43,"value":639},{"type":37,"tag":96,"props":3683,"children":3684},{"style":155},[3685],{"type":43,"value":644},{"type":37,"tag":96,"props":3687,"children":3688},{"style":103},[3689],{"type":43,"value":1938},{"type":37,"tag":96,"props":3691,"children":3692},{"style":155},[3693],{"type":43,"value":168},{"type":37,"tag":96,"props":3695,"children":3696},{"class":98,"line":309},[3697,3702,3707,3711],{"type":37,"tag":96,"props":3698,"children":3699},{"style":329},[3700],{"type":43,"value":3701},"except",{"type":37,"tag":96,"props":3703,"children":3704},{"style":155},[3705],{"type":43,"value":3706}," QueryError ",{"type":37,"tag":96,"props":3708,"children":3709},{"style":329},[3710],{"type":43,"value":342},{"type":37,"tag":96,"props":3712,"children":3713},{"style":155},[3714],{"type":43,"value":3715}," e:\n",{"type":37,"tag":96,"props":3717,"children":3718},{"class":98,"line":317},[3719,3724,3728,3732,3737,3741,3746,3750,3755],{"type":37,"tag":96,"props":3720,"children":3721},{"style":149},[3722],{"type":43,"value":3723},"    print",{"type":37,"tag":96,"props":3725,"children":3726},{"style":155},[3727],{"type":43,"value":158},{"type":37,"tag":96,"props":3729,"children":3730},{"style":329},[3731],{"type":43,"value":649},{"type":37,"tag":96,"props":3733,"children":3734},{"style":103},[3735],{"type":43,"value":3736},"\"Query failed: ",{"type":37,"tag":96,"props":3738,"children":3739},{"style":149},[3740],{"type":43,"value":659},{"type":37,"tag":96,"props":3742,"children":3743},{"style":155},[3744],{"type":43,"value":3745},"e",{"type":37,"tag":96,"props":3747,"children":3748},{"style":149},[3749],{"type":43,"value":669},{"type":37,"tag":96,"props":3751,"children":3752},{"style":103},[3753],{"type":43,"value":3754},"\"",{"type":37,"tag":96,"props":3756,"children":3757},{"style":155},[3758],{"type":43,"value":168},{"type":37,"tag":46,"props":3760,"children":3761},{},[3762,3764,3769],{"type":43,"value":3763},"If a database extra is missing (e.g. ",{"type":37,"tag":52,"props":3765,"children":3767},{"className":3766},[],[3768],{"type":43,"value":1532},{"type":43,"value":3770}," not installed), the SDK raises a clear error telling you which extra to add.",{"type":37,"tag":685,"props":3772,"children":3773},{},[],{"type":37,"tag":38,"props":3775,"children":3777},{"id":3776},"key-takeaways",[3778],{"type":43,"value":3779},"Key takeaways",{"type":37,"tag":554,"props":3781,"children":3782},{},[3783,3788,3805,3815,3826],{"type":37,"tag":558,"props":3784,"children":3785},{},[3786],{"type":43,"value":3787},"The SDK removes boilerplate: credentials, clients, and context are handled for you",{"type":37,"tag":558,"props":3789,"children":3790},{},[3791,3796,3798,3803],{"type":37,"tag":52,"props":3792,"children":3794},{"className":3793},[],[3795],{"type":43,"value":1764},{"type":43,"value":3797}," returns a pandas DataFrame for reads, ",{"type":37,"tag":52,"props":3799,"children":3801},{"className":3800},[],[3802],{"type":43,"value":1834},{"type":43,"value":3804}," for writes",{"type":37,"tag":558,"props":3806,"children":3807},{},[3808,3813],{"type":37,"tag":52,"props":3809,"children":3811},{"className":3810},[],[3812],{"type":43,"value":577},{"type":43,"value":3814}," gives you typed access to run dates, pipeline variables, and the full-refresh flag",{"type":37,"tag":558,"props":3816,"children":3817},{},[3818,3824],{"type":37,"tag":52,"props":3819,"children":3821},{"className":3820},[],[3822],{"type":43,"value":3823},"get_connection()",{"type":43,"value":3825}," exposes the native database client when you need more control",{"type":37,"tag":558,"props":3827,"children":3828},{},[3829,3831,3836,3838,3844,3846],{"type":43,"value":3830},"Declare connections in the ",{"type":37,"tag":52,"props":3832,"children":3834},{"className":3833},[],[3835],{"type":43,"value":82},{"type":43,"value":3837}," metadata block - the default goes under ",{"type":37,"tag":52,"props":3839,"children":3841},{"className":3840},[],[3842],{"type":43,"value":3843},"connection:",{"type":43,"value":3845},", extras go under ",{"type":37,"tag":52,"props":3847,"children":3849},{"className":3848},[],[3850],{"type":43,"value":3851},"secrets:",{"type":37,"tag":685,"props":3853,"children":3854},{},[],{"type":37,"tag":38,"props":3856,"children":3858},{"id":3857},"helpful-links",[3859],{"type":43,"value":3860},"Helpful links",{"type":37,"tag":554,"props":3862,"children":3863},{},[3864,3873,3881,3891,3900],{"type":37,"tag":558,"props":3865,"children":3866},{},[3867],{"type":37,"tag":518,"props":3868,"children":3870},{"href":25,"rel":3869},[1285],[3871],{"type":43,"value":3872},"Bruin Python SDK documentation",{"type":37,"tag":558,"props":3874,"children":3875},{},[3876],{"type":37,"tag":518,"props":3877,"children":3879},{"href":28,"rel":3878},[1285],[3880],{"type":43,"value":27},{"type":37,"tag":558,"props":3882,"children":3883},{},[3884],{"type":37,"tag":518,"props":3885,"children":3888},{"href":3886,"rel":3887},"https://github.com/bruin-data/python-sdk",[1285],[3889],{"type":43,"value":3890},"Source on GitHub",{"type":37,"tag":558,"props":3892,"children":3893},{},[3894],{"type":37,"tag":518,"props":3895,"children":3897},{"href":22,"rel":3896},[1285],[3898],{"type":43,"value":3899},"Python assets in Bruin",{"type":37,"tag":558,"props":3901,"children":3902},{},[3903,3908],{"type":37,"tag":518,"props":3904,"children":3905},{"href":520},[3906],{"type":43,"value":3907},"Python materialization tutorial",{"type":43,"value":3909}," - pair with the SDK to load DataFrames back into your warehouse",{"type":37,"tag":694,"props":3911,"children":3912},{},[3913],{"type":43,"value":698},{"title":7,"searchDepth":109,"depth":109,"links":3915},[3916,3917,3918,3929,3930],{"id":1267,"depth":109,"text":1270},{"id":1341,"depth":109,"text":1344},{"id":1471,"depth":109,"text":1474,"children":3919},[3920,3921,3922,3923,3924,3925,3926,3927,3928],{"id":1477,"depth":118,"text":1480},{"id":1630,"depth":118,"text":1633},{"id":1769,"depth":118,"text":1772},{"id":2035,"depth":118,"text":2038},{"id":2344,"depth":118,"text":2347},{"id":2556,"depth":118,"text":2559},{"id":2889,"depth":118,"text":2892},{"id":3239,"depth":118,"text":3242},{"id":3543,"depth":118,"text":3546},{"id":3776,"depth":109,"text":3779},{"id":3857,"depth":109,"text":3860},"content:tutorials:bruin-python-sdk.md","tutorials/bruin-python-sdk.md","tutorials/bruin-python-sdk",{"_path":3935,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":3936,"description":3937,"date":10,"readingTime":300,"category":1252,"tags":3938,"difficulty":1258,"journeys":3939,"hidden":6,"author":3940,"body":3941,"_type":706,"_id":6473,"_source":708,"_file":6474,"_stem":6475,"_extension":711},"/tutorials/python-materialization","Materializing Python Assets into Your Warehouse","Return a DataFrame, let Bruin handle the rest. Learn how to use Python materialization to load data into BigQuery, Snowflake, Postgres, and more - with support for merge, append, and incremental strategies.",[1254,14,1255,1256,1257],[1260,1261],{"name":30,"role":31,"image":32},{"type":34,"children":3942,"toc":6456},[3943,3947,3971,3980,3987,4015,4018,4024,4036,4067,4072,4088,4091,4095,4101,4106,4367,4372,4447,4453,4463,4497,4502,4508,4543,4555,4560,4616,4627,4632,4681,4692,4697,4763,4774,4787,4963,4973,4979,4991,5385,5391,5396,5581,5586,5592,5597,5698,5704,5729,6079,6104,6110,6137,6142,6169,6181,6223,6226,6232,6237,6289,6308,6311,6315,6406,6409,6413,6452],{"type":37,"tag":38,"props":3944,"children":3945},{"id":1267},[3946],{"type":43,"value":1270},{"type":37,"tag":46,"props":3948,"children":3949},{},[3950,3954,3956,3962,3964,3969],{"type":37,"tag":1275,"props":3951,"children":3952},{},[3953],{"type":43,"value":1279},{"type":43,"value":3955}," - Use ",{"type":37,"tag":518,"props":3957,"children":3960},{"href":3958,"rel":3959},"https://getbruin.com/docs/bruin/assets/python.html#materialization",[1285],[3961],{"type":43,"value":523},{"type":43,"value":3963}," to turn any Python script that returns a DataFrame into a loaded, managed table in your data warehouse. No manual ",{"type":37,"tag":52,"props":3965,"children":3967},{"className":3966},[],[3968],{"type":43,"value":514},{"type":43,"value":3970},", no credential wiring, no duplicate-handling code.",{"type":37,"tag":46,"props":3972,"children":3973},{},[3974,3978],{"type":37,"tag":1275,"props":3975,"children":3976},{},[3977],{"type":43,"value":1297},{"type":43,"value":3979}," - Data engineers who want Python assets that behave like SQL assets: typed columns, merge/append/incremental strategies, and quality checks - all driven by the asset's YAML config.",{"type":37,"tag":46,"props":3981,"children":3982},{},[3983],{"type":37,"tag":1275,"props":3984,"children":3985},{},[3986],{"type":43,"value":1307},{"type":37,"tag":554,"props":3988,"children":3989},{},[3990,3999,4004],{"type":37,"tag":558,"props":3991,"children":3992},{},[3993,3998],{"type":37,"tag":518,"props":3994,"children":3996},{"href":1316,"rel":3995},[1285],[3997],{"type":43,"value":1254},{"type":43,"value":1321},{"type":37,"tag":558,"props":4000,"children":4001},{},[4002],{"type":43,"value":4003},"A Bruin project with a configured warehouse connection (BigQuery, Snowflake, Postgres, Redshift, MSSQL, MySQL, DuckDB, etc.)",{"type":37,"tag":558,"props":4005,"children":4006},{},[4007,4009,4013],{"type":43,"value":4008},"Familiarity with Python assets - see ",{"type":37,"tag":518,"props":4010,"children":4011},{"href":539},[4012],{"type":43,"value":1250},{"type":43,"value":4014}," if you're new to them",{"type":37,"tag":685,"props":4016,"children":4017},{},[],{"type":37,"tag":38,"props":4019,"children":4021},{"id":4020},"what-is-python-materialization",[4022],{"type":43,"value":4023},"What is Python materialization?",{"type":37,"tag":46,"props":4025,"children":4026},{},[4027,4029,4034],{"type":43,"value":4028},"In a regular Python asset, you write code and handle storage yourself. With materialization, you return a DataFrame from a ",{"type":37,"tag":52,"props":4030,"children":4032},{"className":4031},[],[4033],{"type":43,"value":214},{"type":43,"value":4035}," function and Bruin:",{"type":37,"tag":4037,"props":4038,"children":4039},"ol",{},[4040,4045,4050,4062],{"type":37,"tag":558,"props":4041,"children":4042},{},[4043],{"type":43,"value":4044},"Runs your script",{"type":37,"tag":558,"props":4046,"children":4047},{},[4048],{"type":43,"value":4049},"Saves the output to a temporary Apache Arrow file",{"type":37,"tag":558,"props":4051,"children":4052},{},[4053,4055,4060],{"type":43,"value":4054},"Uses ",{"type":37,"tag":52,"props":4056,"children":4058},{"className":4057},[],[4059],{"type":43,"value":476},{"type":43,"value":4061}," to load it into the destination with your chosen strategy",{"type":37,"tag":558,"props":4063,"children":4064},{},[4065],{"type":43,"value":4066},"Cleans up the temporary file",{"type":37,"tag":46,"props":4068,"children":4069},{},[4070],{"type":43,"value":4071},"This is how SQL assets already work. Materialization brings the same model to Python: define the target, describe the columns, return the data.",{"type":37,"tag":1438,"props":4073,"children":4074},{},[4075],{"type":37,"tag":46,"props":4076,"children":4077},{},[4078,4080,4087],{"type":43,"value":4079},"Materialization is a newer feature. It's stable for production use but if you hit an edge case, ",{"type":37,"tag":518,"props":4081,"children":4084},{"href":4082,"rel":4083},"https://github.com/bruin-data/bruin",[1285],[4085],{"type":43,"value":4086},"open an issue",{"type":43,"value":1851},{"type":37,"tag":685,"props":4089,"children":4090},{},[],{"type":37,"tag":38,"props":4092,"children":4093},{"id":1471},[4094],{"type":43,"value":1474},{"type":37,"tag":66,"props":4096,"children":4098},{"id":4097},"_1-anatomy-of-a-materialized-python-asset",[4099],{"type":43,"value":4100},"1) Anatomy of a materialized Python asset",{"type":37,"tag":46,"props":4102,"children":4103},{},[4104],{"type":43,"value":4105},"Here's the minimal shape:",{"type":37,"tag":86,"props":4107,"children":4109},{"className":88,"code":4108,"language":90,"meta":7,"style":7},"\"\"\"@bruin\nname: tier1.users\nimage: python:3.13\nconnection: my_bigquery\n\nmaterialization:\n  type: table\n  strategy: create+replace\n\ncolumns:\n  - name: id\n    type: integer\n    primary_key: true\n  - name: name\n    type: string\n@bruin\"\"\"\n\nimport pandas as pd\n\ndef materialize():\n    return pd.DataFrame({\n        \"id\": [1, 2, 3],\n        \"name\": [\"Alice\", \"Bob\", \"Charlie\"],\n    })\n",[4110],{"type":37,"tag":52,"props":4111,"children":4112},{"__ignoreMap":7},[4113,4120,4128,4135,4142,4149,4156,4163,4171,4178,4185,4192,4199,4206,4213,4220,4227,4234,4253,4260,4275,4287,4323,4359],{"type":37,"tag":96,"props":4114,"children":4115},{"class":98,"line":99},[4116],{"type":37,"tag":96,"props":4117,"children":4118},{"style":103},[4119],{"type":43,"value":106},{"type":37,"tag":96,"props":4121,"children":4122},{"class":98,"line":109},[4123],{"type":37,"tag":96,"props":4124,"children":4125},{"style":103},[4126],{"type":43,"value":4127},"name: tier1.users\n",{"type":37,"tag":96,"props":4129,"children":4130},{"class":98,"line":118},[4131],{"type":37,"tag":96,"props":4132,"children":4133},{"style":103},[4134],{"type":43,"value":124},{"type":37,"tag":96,"props":4136,"children":4137},{"class":98,"line":127},[4138],{"type":37,"tag":96,"props":4139,"children":4140},{"style":103},[4141],{"type":43,"value":246},{"type":37,"tag":96,"props":4143,"children":4144},{"class":98,"line":136},[4145],{"type":37,"tag":96,"props":4146,"children":4147},{"emptyLinePlaceholder":13},[4148],{"type":43,"value":142},{"type":37,"tag":96,"props":4150,"children":4151},{"class":98,"line":145},[4152],{"type":37,"tag":96,"props":4153,"children":4154},{"style":103},[4155],{"type":43,"value":254},{"type":37,"tag":96,"props":4157,"children":4158},{"class":98,"line":273},[4159],{"type":37,"tag":96,"props":4160,"children":4161},{"style":103},[4162],{"type":43,"value":262},{"type":37,"tag":96,"props":4164,"children":4165},{"class":98,"line":282},[4166],{"type":37,"tag":96,"props":4167,"children":4168},{"style":103},[4169],{"type":43,"value":4170},"  strategy: create+replace\n",{"type":37,"tag":96,"props":4172,"children":4173},{"class":98,"line":291},[4174],{"type":37,"tag":96,"props":4175,"children":4176},{"emptyLinePlaceholder":13},[4177],{"type":43,"value":142},{"type":37,"tag":96,"props":4179,"children":4180},{"class":98,"line":300},[4181],{"type":37,"tag":96,"props":4182,"children":4183},{"style":103},[4184],{"type":43,"value":279},{"type":37,"tag":96,"props":4186,"children":4187},{"class":98,"line":309},[4188],{"type":37,"tag":96,"props":4189,"children":4190},{"style":103},[4191],{"type":43,"value":288},{"type":37,"tag":96,"props":4193,"children":4194},{"class":98,"line":317},[4195],{"type":37,"tag":96,"props":4196,"children":4197},{"style":103},[4198],{"type":43,"value":297},{"type":37,"tag":96,"props":4200,"children":4201},{"class":98,"line":325},[4202],{"type":37,"tag":96,"props":4203,"children":4204},{"style":103},[4205],{"type":43,"value":306},{"type":37,"tag":96,"props":4207,"children":4208},{"class":98,"line":350},[4209],{"type":37,"tag":96,"props":4210,"children":4211},{"style":103},[4212],{"type":43,"value":3010},{"type":37,"tag":96,"props":4214,"children":4215},{"class":98,"line":358},[4216],{"type":37,"tag":96,"props":4217,"children":4218},{"style":103},[4219],{"type":43,"value":3018},{"type":37,"tag":96,"props":4221,"children":4222},{"class":98,"line":378},[4223],{"type":37,"tag":96,"props":4224,"children":4225},{"style":103},[4226],{"type":43,"value":133},{"type":37,"tag":96,"props":4228,"children":4229},{"class":98,"line":2770},[4230],{"type":37,"tag":96,"props":4231,"children":4232},{"emptyLinePlaceholder":13},[4233],{"type":43,"value":142},{"type":37,"tag":96,"props":4235,"children":4236},{"class":98,"line":2798},[4237,4241,4245,4249],{"type":37,"tag":96,"props":4238,"children":4239},{"style":329},[4240],{"type":43,"value":332},{"type":37,"tag":96,"props":4242,"children":4243},{"style":155},[4244],{"type":43,"value":337},{"type":37,"tag":96,"props":4246,"children":4247},{"style":329},[4248],{"type":43,"value":342},{"type":37,"tag":96,"props":4250,"children":4251},{"style":155},[4252],{"type":43,"value":347},{"type":37,"tag":96,"props":4254,"children":4255},{"class":98,"line":2816},[4256],{"type":37,"tag":96,"props":4257,"children":4258},{"emptyLinePlaceholder":13},[4259],{"type":43,"value":142},{"type":37,"tag":96,"props":4261,"children":4262},{"class":98,"line":2838},[4263,4267,4271],{"type":37,"tag":96,"props":4264,"children":4265},{"style":329},[4266],{"type":43,"value":364},{"type":37,"tag":96,"props":4268,"children":4269},{"style":367},[4270],{"type":43,"value":370},{"type":37,"tag":96,"props":4272,"children":4273},{"style":155},[4274],{"type":43,"value":375},{"type":37,"tag":96,"props":4276,"children":4277},{"class":98,"line":3069},[4278,4282],{"type":37,"tag":96,"props":4279,"children":4280},{"style":329},[4281],{"type":43,"value":384},{"type":37,"tag":96,"props":4283,"children":4284},{"style":155},[4285],{"type":43,"value":4286}," pd.DataFrame({\n",{"type":37,"tag":96,"props":4288,"children":4289},{"class":98,"line":3085},[4290,4295,4299,4303,4307,4311,4315,4319],{"type":37,"tag":96,"props":4291,"children":4292},{"style":103},[4293],{"type":43,"value":4294},"        \"id\"",{"type":37,"tag":96,"props":4296,"children":4297},{"style":155},[4298],{"type":43,"value":399},{"type":37,"tag":96,"props":4300,"children":4301},{"style":149},[4302],{"type":43,"value":404},{"type":37,"tag":96,"props":4304,"children":4305},{"style":155},[4306],{"type":43,"value":409},{"type":37,"tag":96,"props":4308,"children":4309},{"style":149},[4310],{"type":43,"value":414},{"type":37,"tag":96,"props":4312,"children":4313},{"style":155},[4314],{"type":43,"value":409},{"type":37,"tag":96,"props":4316,"children":4317},{"style":149},[4318],{"type":43,"value":423},{"type":37,"tag":96,"props":4320,"children":4321},{"style":155},[4322],{"type":43,"value":2795},{"type":37,"tag":96,"props":4324,"children":4325},{"class":98,"line":3098},[4326,4331,4335,4339,4343,4347,4351,4355],{"type":37,"tag":96,"props":4327,"children":4328},{"style":103},[4329],{"type":43,"value":4330},"        \"name\"",{"type":37,"tag":96,"props":4332,"children":4333},{"style":155},[4334],{"type":43,"value":399},{"type":37,"tag":96,"props":4336,"children":4337},{"style":103},[4338],{"type":43,"value":442},{"type":37,"tag":96,"props":4340,"children":4341},{"style":155},[4342],{"type":43,"value":409},{"type":37,"tag":96,"props":4344,"children":4345},{"style":103},[4346],{"type":43,"value":451},{"type":37,"tag":96,"props":4348,"children":4349},{"style":155},[4350],{"type":43,"value":409},{"type":37,"tag":96,"props":4352,"children":4353},{"style":103},[4354],{"type":43,"value":460},{"type":37,"tag":96,"props":4356,"children":4357},{"style":155},[4358],{"type":43,"value":2795},{"type":37,"tag":96,"props":4360,"children":4361},{"class":98,"line":3120},[4362],{"type":37,"tag":96,"props":4363,"children":4364},{"style":155},[4365],{"type":43,"value":4366},"    })\n",{"type":37,"tag":46,"props":4368,"children":4369},{},[4370],{"type":43,"value":4371},"Three things to notice:",{"type":37,"tag":554,"props":4373,"children":4374},{},[4375,4430,4442],{"type":37,"tag":558,"props":4376,"children":4377},{},[4378,4379,4384,4386,4391,4393,4399,4401,4407,4409,4414,4416,4422,4424],{"type":43,"value":536},{"type":37,"tag":52,"props":4380,"children":4382},{"className":4381},[],[4383],{"type":43,"value":82},{"type":43,"value":4385}," block declares a ",{"type":37,"tag":52,"props":4387,"children":4389},{"className":4388},[],[4390],{"type":43,"value":1987},{"type":43,"value":4392}," (required when ",{"type":37,"tag":52,"props":4394,"children":4396},{"className":4395},[],[4397],{"type":43,"value":4398},"materialization.type",{"type":43,"value":4400}," is ",{"type":37,"tag":52,"props":4402,"children":4404},{"className":4403},[],[4405],{"type":43,"value":4406},"table",{"type":43,"value":4408},") and a ",{"type":37,"tag":52,"props":4410,"children":4412},{"className":4411},[],[4413],{"type":43,"value":206},{"type":43,"value":4415}," block with a ",{"type":37,"tag":52,"props":4417,"children":4419},{"className":4418},[],[4420],{"type":43,"value":4421},"type",{"type":43,"value":4423}," and ",{"type":37,"tag":52,"props":4425,"children":4427},{"className":4426},[],[4428],{"type":43,"value":4429},"strategy",{"type":37,"tag":558,"props":4431,"children":4432},{},[4433,4435,4440],{"type":43,"value":4434},"The function is named ",{"type":37,"tag":52,"props":4436,"children":4438},{"className":4437},[],[4439],{"type":43,"value":214},{"type":43,"value":4441}," - Bruin looks for it specifically",{"type":37,"tag":558,"props":4443,"children":4444},{},[4445],{"type":43,"value":4446},"The return value is a DataFrame. Bruin handles the rest",{"type":37,"tag":66,"props":4448,"children":4450},{"id":4449},"_2-return-types-supported",[4451],{"type":43,"value":4452},"2) Return types supported",{"type":37,"tag":46,"props":4454,"children":4455},{},[4456,4461],{"type":37,"tag":52,"props":4457,"children":4459},{"className":4458},[],[4460],{"type":43,"value":214},{"type":43,"value":4462}," can return any of:",{"type":37,"tag":554,"props":4464,"children":4465},{},[4466,4473,4481],{"type":37,"tag":558,"props":4467,"children":4468},{},[4469],{"type":37,"tag":1275,"props":4470,"children":4471},{},[4472],{"type":43,"value":1789},{"type":37,"tag":558,"props":4474,"children":4475},{},[4476],{"type":37,"tag":1275,"props":4477,"children":4478},{},[4479],{"type":43,"value":4480},"polars DataFrame",{"type":37,"tag":558,"props":4482,"children":4483},{},[4484,4489,4491],{"type":37,"tag":1275,"props":4485,"children":4486},{},[4487],{"type":43,"value":4488},"list of dicts",{"type":43,"value":4490}," - e.g. ",{"type":37,"tag":52,"props":4492,"children":4494},{"className":4493},[],[4495],{"type":43,"value":4496},"[{\"id\": 1, \"name\": \"Alice\"}, ...]",{"type":37,"tag":46,"props":4498,"children":4499},{},[4500],{"type":43,"value":4501},"Pick whichever fits your upstream code. Polars is great for larger datasets; pandas has the widest ecosystem; a list of dicts is fine for small API results.",{"type":37,"tag":66,"props":4503,"children":4505},{"id":4504},"_3-choose-a-materialization-strategy",[4506],{"type":43,"value":4507},"3) Choose a materialization strategy",{"type":37,"tag":46,"props":4509,"children":4510},{},[4511,4513,4519,4521,4526,4528,4533,4535,4541],{"type":43,"value":4512},"Python assets support four strategies. The ",{"type":37,"tag":52,"props":4514,"children":4516},{"className":4515},[],[4517],{"type":43,"value":4518},"time_interval",{"type":43,"value":4520}," strategy is ",{"type":37,"tag":1275,"props":4522,"children":4523},{},[4524],{"type":43,"value":4525},"not",{"type":43,"value":4527}," supported for Python - use ",{"type":37,"tag":52,"props":4529,"children":4531},{"className":4530},[],[4532],{"type":43,"value":498},{"type":43,"value":4534}," with an ",{"type":37,"tag":52,"props":4536,"children":4538},{"className":4537},[],[4539],{"type":43,"value":4540},"incremental_key",{"type":43,"value":4542}," instead if you need time-bucketed incremental loads.",{"type":37,"tag":4544,"props":4545,"children":4547},"h4",{"id":4546},"createreplace-full-refresh",[4548,4553],{"type":37,"tag":52,"props":4549,"children":4551},{"className":4550},[],[4552],{"type":43,"value":484},{"type":43,"value":4554}," - full refresh",{"type":37,"tag":46,"props":4556,"children":4557},{},[4558],{"type":43,"value":4559},"Rebuilds the table on every run. Simple, predictable, and expensive for large tables.",{"type":37,"tag":86,"props":4561,"children":4565},{"className":4562,"code":4563,"language":4564,"meta":7,"style":7},"language-yaml shiki shiki-themes github-dark","materialization:\n  type: table\n  strategy: create+replace\n","yaml",[4566],{"type":37,"tag":52,"props":4567,"children":4568},{"__ignoreMap":7},[4569,4581,4599],{"type":37,"tag":96,"props":4570,"children":4571},{"class":98,"line":99},[4572,4577],{"type":37,"tag":96,"props":4573,"children":4575},{"style":4574},"--shiki-default:#85E89D",[4576],{"type":43,"value":206},{"type":37,"tag":96,"props":4578,"children":4579},{"style":155},[4580],{"type":43,"value":2141},{"type":37,"tag":96,"props":4582,"children":4583},{"class":98,"line":109},[4584,4589,4594],{"type":37,"tag":96,"props":4585,"children":4586},{"style":4574},[4587],{"type":43,"value":4588},"  type",{"type":37,"tag":96,"props":4590,"children":4591},{"style":155},[4592],{"type":43,"value":4593},": ",{"type":37,"tag":96,"props":4595,"children":4596},{"style":103},[4597],{"type":43,"value":4598},"table\n",{"type":37,"tag":96,"props":4600,"children":4601},{"class":98,"line":118},[4602,4607,4611],{"type":37,"tag":96,"props":4603,"children":4604},{"style":4574},[4605],{"type":43,"value":4606},"  strategy",{"type":37,"tag":96,"props":4608,"children":4609},{"style":155},[4610],{"type":43,"value":4593},{"type":37,"tag":96,"props":4612,"children":4613},{"style":103},[4614],{"type":43,"value":4615},"create+replace\n",{"type":37,"tag":4544,"props":4617,"children":4619},{"id":4618},"append-add-only",[4620,4625],{"type":37,"tag":52,"props":4621,"children":4623},{"className":4622},[],[4624],{"type":43,"value":491},{"type":43,"value":4626}," - add only",{"type":37,"tag":46,"props":4628,"children":4629},{},[4630],{"type":43,"value":4631},"Inserts new rows, never removes. Use for audit logs or event streams where history must be preserved.",{"type":37,"tag":86,"props":4633,"children":4635},{"className":4562,"code":4634,"language":4564,"meta":7,"style":7},"materialization:\n  type: table\n  strategy: append\n",[4636],{"type":37,"tag":52,"props":4637,"children":4638},{"__ignoreMap":7},[4639,4650,4665],{"type":37,"tag":96,"props":4640,"children":4641},{"class":98,"line":99},[4642,4646],{"type":37,"tag":96,"props":4643,"children":4644},{"style":4574},[4645],{"type":43,"value":206},{"type":37,"tag":96,"props":4647,"children":4648},{"style":155},[4649],{"type":43,"value":2141},{"type":37,"tag":96,"props":4651,"children":4652},{"class":98,"line":109},[4653,4657,4661],{"type":37,"tag":96,"props":4654,"children":4655},{"style":4574},[4656],{"type":43,"value":4588},{"type":37,"tag":96,"props":4658,"children":4659},{"style":155},[4660],{"type":43,"value":4593},{"type":37,"tag":96,"props":4662,"children":4663},{"style":103},[4664],{"type":43,"value":4598},{"type":37,"tag":96,"props":4666,"children":4667},{"class":98,"line":118},[4668,4672,4676],{"type":37,"tag":96,"props":4669,"children":4670},{"style":4574},[4671],{"type":43,"value":4606},{"type":37,"tag":96,"props":4673,"children":4674},{"style":155},[4675],{"type":43,"value":4593},{"type":37,"tag":96,"props":4677,"children":4678},{"style":103},[4679],{"type":43,"value":4680},"append\n",{"type":37,"tag":4544,"props":4682,"children":4684},{"id":4683},"deleteinsert-replace-by-key",[4685,4690],{"type":37,"tag":52,"props":4686,"children":4688},{"className":4687},[],[4689],{"type":43,"value":498},{"type":43,"value":4691}," - replace by key",{"type":37,"tag":46,"props":4693,"children":4694},{},[4695],{"type":43,"value":4696},"Deletes rows matching your incremental key's distinct values, then inserts the new batch. Use for reprocessing a specific partition (e.g. \"today's rows\").",{"type":37,"tag":86,"props":4698,"children":4700},{"className":4562,"code":4699,"language":4564,"meta":7,"style":7},"materialization:\n  type: table\n  strategy: delete+insert\n  incremental_key: event_date\n",[4701],{"type":37,"tag":52,"props":4702,"children":4703},{"__ignoreMap":7},[4704,4715,4730,4746],{"type":37,"tag":96,"props":4705,"children":4706},{"class":98,"line":99},[4707,4711],{"type":37,"tag":96,"props":4708,"children":4709},{"style":4574},[4710],{"type":43,"value":206},{"type":37,"tag":96,"props":4712,"children":4713},{"style":155},[4714],{"type":43,"value":2141},{"type":37,"tag":96,"props":4716,"children":4717},{"class":98,"line":109},[4718,4722,4726],{"type":37,"tag":96,"props":4719,"children":4720},{"style":4574},[4721],{"type":43,"value":4588},{"type":37,"tag":96,"props":4723,"children":4724},{"style":155},[4725],{"type":43,"value":4593},{"type":37,"tag":96,"props":4727,"children":4728},{"style":103},[4729],{"type":43,"value":4598},{"type":37,"tag":96,"props":4731,"children":4732},{"class":98,"line":118},[4733,4737,4741],{"type":37,"tag":96,"props":4734,"children":4735},{"style":4574},[4736],{"type":43,"value":4606},{"type":37,"tag":96,"props":4738,"children":4739},{"style":155},[4740],{"type":43,"value":4593},{"type":37,"tag":96,"props":4742,"children":4743},{"style":103},[4744],{"type":43,"value":4745},"delete+insert\n",{"type":37,"tag":96,"props":4747,"children":4748},{"class":98,"line":127},[4749,4754,4758],{"type":37,"tag":96,"props":4750,"children":4751},{"style":4574},[4752],{"type":43,"value":4753},"  incremental_key",{"type":37,"tag":96,"props":4755,"children":4756},{"style":155},[4757],{"type":43,"value":4593},{"type":37,"tag":96,"props":4759,"children":4760},{"style":103},[4761],{"type":43,"value":4762},"event_date\n",{"type":37,"tag":4544,"props":4764,"children":4766},{"id":4765},"merge-upsert",[4767,4772],{"type":37,"tag":52,"props":4768,"children":4770},{"className":4769},[],[4771],{"type":43,"value":506},{"type":43,"value":4773}," - upsert",{"type":37,"tag":46,"props":4775,"children":4776},{},[4777,4779,4785],{"type":43,"value":4778},"Updates existing rows and inserts new ones based on ",{"type":37,"tag":52,"props":4780,"children":4782},{"className":4781},[],[4783],{"type":43,"value":4784},"primary_key",{"type":43,"value":4786},". Use when upstream records can change and you need to keep the latest version.",{"type":37,"tag":86,"props":4788,"children":4790},{"className":4562,"code":4789,"language":4564,"meta":7,"style":7},"materialization:\n  type: table\n  strategy: merge\n\ncolumns:\n  - name: id\n    type: integer\n    primary_key: true\n  - name: name\n    type: string\n    update_on_merge: true\n",[4791],{"type":37,"tag":52,"props":4792,"children":4793},{"__ignoreMap":7},[4794,4805,4820,4836,4843,4855,4877,4894,4911,4931,4947],{"type":37,"tag":96,"props":4795,"children":4796},{"class":98,"line":99},[4797,4801],{"type":37,"tag":96,"props":4798,"children":4799},{"style":4574},[4800],{"type":43,"value":206},{"type":37,"tag":96,"props":4802,"children":4803},{"style":155},[4804],{"type":43,"value":2141},{"type":37,"tag":96,"props":4806,"children":4807},{"class":98,"line":109},[4808,4812,4816],{"type":37,"tag":96,"props":4809,"children":4810},{"style":4574},[4811],{"type":43,"value":4588},{"type":37,"tag":96,"props":4813,"children":4814},{"style":155},[4815],{"type":43,"value":4593},{"type":37,"tag":96,"props":4817,"children":4818},{"style":103},[4819],{"type":43,"value":4598},{"type":37,"tag":96,"props":4821,"children":4822},{"class":98,"line":118},[4823,4827,4831],{"type":37,"tag":96,"props":4824,"children":4825},{"style":4574},[4826],{"type":43,"value":4606},{"type":37,"tag":96,"props":4828,"children":4829},{"style":155},[4830],{"type":43,"value":4593},{"type":37,"tag":96,"props":4832,"children":4833},{"style":103},[4834],{"type":43,"value":4835},"merge\n",{"type":37,"tag":96,"props":4837,"children":4838},{"class":98,"line":127},[4839],{"type":37,"tag":96,"props":4840,"children":4841},{"emptyLinePlaceholder":13},[4842],{"type":43,"value":142},{"type":37,"tag":96,"props":4844,"children":4845},{"class":98,"line":136},[4846,4851],{"type":37,"tag":96,"props":4847,"children":4848},{"style":4574},[4849],{"type":43,"value":4850},"columns",{"type":37,"tag":96,"props":4852,"children":4853},{"style":155},[4854],{"type":43,"value":2141},{"type":37,"tag":96,"props":4856,"children":4857},{"class":98,"line":145},[4858,4863,4868,4872],{"type":37,"tag":96,"props":4859,"children":4860},{"style":155},[4861],{"type":43,"value":4862},"  - ",{"type":37,"tag":96,"props":4864,"children":4865},{"style":4574},[4866],{"type":43,"value":4867},"name",{"type":37,"tag":96,"props":4869,"children":4870},{"style":155},[4871],{"type":43,"value":4593},{"type":37,"tag":96,"props":4873,"children":4874},{"style":103},[4875],{"type":43,"value":4876},"id\n",{"type":37,"tag":96,"props":4878,"children":4879},{"class":98,"line":273},[4880,4885,4889],{"type":37,"tag":96,"props":4881,"children":4882},{"style":4574},[4883],{"type":43,"value":4884},"    type",{"type":37,"tag":96,"props":4886,"children":4887},{"style":155},[4888],{"type":43,"value":4593},{"type":37,"tag":96,"props":4890,"children":4891},{"style":103},[4892],{"type":43,"value":4893},"integer\n",{"type":37,"tag":96,"props":4895,"children":4896},{"class":98,"line":282},[4897,4902,4906],{"type":37,"tag":96,"props":4898,"children":4899},{"style":4574},[4900],{"type":43,"value":4901},"    primary_key",{"type":37,"tag":96,"props":4903,"children":4904},{"style":155},[4905],{"type":43,"value":4593},{"type":37,"tag":96,"props":4907,"children":4908},{"style":149},[4909],{"type":43,"value":4910},"true\n",{"type":37,"tag":96,"props":4912,"children":4913},{"class":98,"line":291},[4914,4918,4922,4926],{"type":37,"tag":96,"props":4915,"children":4916},{"style":155},[4917],{"type":43,"value":4862},{"type":37,"tag":96,"props":4919,"children":4920},{"style":4574},[4921],{"type":43,"value":4867},{"type":37,"tag":96,"props":4923,"children":4924},{"style":155},[4925],{"type":43,"value":4593},{"type":37,"tag":96,"props":4927,"children":4928},{"style":103},[4929],{"type":43,"value":4930},"name\n",{"type":37,"tag":96,"props":4932,"children":4933},{"class":98,"line":300},[4934,4938,4942],{"type":37,"tag":96,"props":4935,"children":4936},{"style":4574},[4937],{"type":43,"value":4884},{"type":37,"tag":96,"props":4939,"children":4940},{"style":155},[4941],{"type":43,"value":4593},{"type":37,"tag":96,"props":4943,"children":4944},{"style":103},[4945],{"type":43,"value":4946},"string\n",{"type":37,"tag":96,"props":4948,"children":4949},{"class":98,"line":309},[4950,4955,4959],{"type":37,"tag":96,"props":4951,"children":4952},{"style":4574},[4953],{"type":43,"value":4954},"    update_on_merge",{"type":37,"tag":96,"props":4956,"children":4957},{"style":155},[4958],{"type":43,"value":4593},{"type":37,"tag":96,"props":4960,"children":4961},{"style":149},[4962],{"type":43,"value":4910},{"type":37,"tag":46,"props":4964,"children":4965},{},[4966,4971],{"type":37,"tag":52,"props":4967,"children":4969},{"className":4968},[],[4970],{"type":43,"value":506},{"type":43,"value":4972}," is the most common production strategy and is supported on BigQuery, Snowflake, Postgres, MSSQL, MySQL, Athena (Iceberg), Databricks, ClickHouse, Trino, and DuckDB (limited).",{"type":37,"tag":66,"props":4974,"children":4976},{"id":4975},"_4-enforce-column-types",[4977],{"type":43,"value":4978},"4) Enforce column types",{"type":37,"tag":46,"props":4980,"children":4981},{},[4982,4984,4990],{"type":43,"value":4983},"By default, types are inferred from the DataFrame. To enforce them at the destination, set ",{"type":37,"tag":52,"props":4985,"children":4987},{"className":4986},[],[4988],{"type":43,"value":4989},"parameters.enforce_schema: true",{"type":43,"value":3406},{"type":37,"tag":86,"props":4992,"children":4994},{"className":88,"code":4993,"language":90,"meta":7,"style":7},"\"\"\"@bruin\nname: tier1.users_api\nimage: python:3.13\nconnection: my_bigquery\n\nmaterialization:\n  type: table\n  strategy: merge\n\nparameters:\n  enforce_schema: true\n\ncolumns:\n  - name: id\n    type: integer\n    primary_key: true\n  - name: name\n    type: string\n  - name: email\n    type: string\n  - name: created_at\n    type: timestamp\n@bruin\"\"\"\n\nimport pandas as pd\n\ndef materialize():\n    return pd.DataFrame({\n        \"id\": [1, 2, 3],\n        \"name\": [\"Alice\", \"Bob\", \"Charlie\"],\n        \"email\": [\"alice@example.com\", \"bob@example.com\", \"charlie@example.com\"],\n        \"created_at\": pd.to_datetime([\"2026-01-01\", \"2026-01-02\", \"2026-01-03\"]),\n    })\n",[4995],{"type":37,"tag":52,"props":4996,"children":4997},{"__ignoreMap":7},[4998,5005,5013,5020,5027,5034,5041,5048,5055,5062,5070,5078,5085,5092,5099,5106,5113,5120,5127,5135,5142,5150,5158,5165,5172,5191,5198,5213,5224,5259,5295,5335,5377],{"type":37,"tag":96,"props":4999,"children":5000},{"class":98,"line":99},[5001],{"type":37,"tag":96,"props":5002,"children":5003},{"style":103},[5004],{"type":43,"value":106},{"type":37,"tag":96,"props":5006,"children":5007},{"class":98,"line":109},[5008],{"type":37,"tag":96,"props":5009,"children":5010},{"style":103},[5011],{"type":43,"value":5012},"name: tier1.users_api\n",{"type":37,"tag":96,"props":5014,"children":5015},{"class":98,"line":118},[5016],{"type":37,"tag":96,"props":5017,"children":5018},{"style":103},[5019],{"type":43,"value":124},{"type":37,"tag":96,"props":5021,"children":5022},{"class":98,"line":127},[5023],{"type":37,"tag":96,"props":5024,"children":5025},{"style":103},[5026],{"type":43,"value":246},{"type":37,"tag":96,"props":5028,"children":5029},{"class":98,"line":136},[5030],{"type":37,"tag":96,"props":5031,"children":5032},{"emptyLinePlaceholder":13},[5033],{"type":43,"value":142},{"type":37,"tag":96,"props":5035,"children":5036},{"class":98,"line":145},[5037],{"type":37,"tag":96,"props":5038,"children":5039},{"style":103},[5040],{"type":43,"value":254},{"type":37,"tag":96,"props":5042,"children":5043},{"class":98,"line":273},[5044],{"type":37,"tag":96,"props":5045,"children":5046},{"style":103},[5047],{"type":43,"value":262},{"type":37,"tag":96,"props":5049,"children":5050},{"class":98,"line":282},[5051],{"type":37,"tag":96,"props":5052,"children":5053},{"style":103},[5054],{"type":43,"value":270},{"type":37,"tag":96,"props":5056,"children":5057},{"class":98,"line":291},[5058],{"type":37,"tag":96,"props":5059,"children":5060},{"emptyLinePlaceholder":13},[5061],{"type":43,"value":142},{"type":37,"tag":96,"props":5063,"children":5064},{"class":98,"line":300},[5065],{"type":37,"tag":96,"props":5066,"children":5067},{"style":103},[5068],{"type":43,"value":5069},"parameters:\n",{"type":37,"tag":96,"props":5071,"children":5072},{"class":98,"line":309},[5073],{"type":37,"tag":96,"props":5074,"children":5075},{"style":103},[5076],{"type":43,"value":5077},"  enforce_schema: true\n",{"type":37,"tag":96,"props":5079,"children":5080},{"class":98,"line":317},[5081],{"type":37,"tag":96,"props":5082,"children":5083},{"emptyLinePlaceholder":13},[5084],{"type":43,"value":142},{"type":37,"tag":96,"props":5086,"children":5087},{"class":98,"line":325},[5088],{"type":37,"tag":96,"props":5089,"children":5090},{"style":103},[5091],{"type":43,"value":279},{"type":37,"tag":96,"props":5093,"children":5094},{"class":98,"line":350},[5095],{"type":37,"tag":96,"props":5096,"children":5097},{"style":103},[5098],{"type":43,"value":288},{"type":37,"tag":96,"props":5100,"children":5101},{"class":98,"line":358},[5102],{"type":37,"tag":96,"props":5103,"children":5104},{"style":103},[5105],{"type":43,"value":297},{"type":37,"tag":96,"props":5107,"children":5108},{"class":98,"line":378},[5109],{"type":37,"tag":96,"props":5110,"children":5111},{"style":103},[5112],{"type":43,"value":306},{"type":37,"tag":96,"props":5114,"children":5115},{"class":98,"line":2770},[5116],{"type":37,"tag":96,"props":5117,"children":5118},{"style":103},[5119],{"type":43,"value":3010},{"type":37,"tag":96,"props":5121,"children":5122},{"class":98,"line":2798},[5123],{"type":37,"tag":96,"props":5124,"children":5125},{"style":103},[5126],{"type":43,"value":3018},{"type":37,"tag":96,"props":5128,"children":5129},{"class":98,"line":2816},[5130],{"type":37,"tag":96,"props":5131,"children":5132},{"style":103},[5133],{"type":43,"value":5134},"  - name: email\n",{"type":37,"tag":96,"props":5136,"children":5137},{"class":98,"line":2838},[5138],{"type":37,"tag":96,"props":5139,"children":5140},{"style":103},[5141],{"type":43,"value":3018},{"type":37,"tag":96,"props":5143,"children":5144},{"class":98,"line":3069},[5145],{"type":37,"tag":96,"props":5146,"children":5147},{"style":103},[5148],{"type":43,"value":5149},"  - name: created_at\n",{"type":37,"tag":96,"props":5151,"children":5152},{"class":98,"line":3085},[5153],{"type":37,"tag":96,"props":5154,"children":5155},{"style":103},[5156],{"type":43,"value":5157},"    type: timestamp\n",{"type":37,"tag":96,"props":5159,"children":5160},{"class":98,"line":3098},[5161],{"type":37,"tag":96,"props":5162,"children":5163},{"style":103},[5164],{"type":43,"value":133},{"type":37,"tag":96,"props":5166,"children":5167},{"class":98,"line":3120},[5168],{"type":37,"tag":96,"props":5169,"children":5170},{"emptyLinePlaceholder":13},[5171],{"type":43,"value":142},{"type":37,"tag":96,"props":5173,"children":5174},{"class":98,"line":3128},[5175,5179,5183,5187],{"type":37,"tag":96,"props":5176,"children":5177},{"style":329},[5178],{"type":43,"value":332},{"type":37,"tag":96,"props":5180,"children":5181},{"style":155},[5182],{"type":43,"value":337},{"type":37,"tag":96,"props":5184,"children":5185},{"style":329},[5186],{"type":43,"value":342},{"type":37,"tag":96,"props":5188,"children":5189},{"style":155},[5190],{"type":43,"value":347},{"type":37,"tag":96,"props":5192,"children":5193},{"class":98,"line":3148},[5194],{"type":37,"tag":96,"props":5195,"children":5196},{"emptyLinePlaceholder":13},[5197],{"type":43,"value":142},{"type":37,"tag":96,"props":5199,"children":5200},{"class":98,"line":3157},[5201,5205,5209],{"type":37,"tag":96,"props":5202,"children":5203},{"style":329},[5204],{"type":43,"value":364},{"type":37,"tag":96,"props":5206,"children":5207},{"style":367},[5208],{"type":43,"value":370},{"type":37,"tag":96,"props":5210,"children":5211},{"style":155},[5212],{"type":43,"value":375},{"type":37,"tag":96,"props":5214,"children":5215},{"class":98,"line":3166},[5216,5220],{"type":37,"tag":96,"props":5217,"children":5218},{"style":329},[5219],{"type":43,"value":384},{"type":37,"tag":96,"props":5221,"children":5222},{"style":155},[5223],{"type":43,"value":4286},{"type":37,"tag":96,"props":5225,"children":5226},{"class":98,"line":3207},[5227,5231,5235,5239,5243,5247,5251,5255],{"type":37,"tag":96,"props":5228,"children":5229},{"style":103},[5230],{"type":43,"value":4294},{"type":37,"tag":96,"props":5232,"children":5233},{"style":155},[5234],{"type":43,"value":399},{"type":37,"tag":96,"props":5236,"children":5237},{"style":149},[5238],{"type":43,"value":404},{"type":37,"tag":96,"props":5240,"children":5241},{"style":155},[5242],{"type":43,"value":409},{"type":37,"tag":96,"props":5244,"children":5245},{"style":149},[5246],{"type":43,"value":414},{"type":37,"tag":96,"props":5248,"children":5249},{"style":155},[5250],{"type":43,"value":409},{"type":37,"tag":96,"props":5252,"children":5253},{"style":149},[5254],{"type":43,"value":423},{"type":37,"tag":96,"props":5256,"children":5257},{"style":155},[5258],{"type":43,"value":2795},{"type":37,"tag":96,"props":5260,"children":5262},{"class":98,"line":5261},30,[5263,5267,5271,5275,5279,5283,5287,5291],{"type":37,"tag":96,"props":5264,"children":5265},{"style":103},[5266],{"type":43,"value":4330},{"type":37,"tag":96,"props":5268,"children":5269},{"style":155},[5270],{"type":43,"value":399},{"type":37,"tag":96,"props":5272,"children":5273},{"style":103},[5274],{"type":43,"value":442},{"type":37,"tag":96,"props":5276,"children":5277},{"style":155},[5278],{"type":43,"value":409},{"type":37,"tag":96,"props":5280,"children":5281},{"style":103},[5282],{"type":43,"value":451},{"type":37,"tag":96,"props":5284,"children":5285},{"style":155},[5286],{"type":43,"value":409},{"type":37,"tag":96,"props":5288,"children":5289},{"style":103},[5290],{"type":43,"value":460},{"type":37,"tag":96,"props":5292,"children":5293},{"style":155},[5294],{"type":43,"value":2795},{"type":37,"tag":96,"props":5296,"children":5298},{"class":98,"line":5297},31,[5299,5304,5308,5313,5317,5322,5326,5331],{"type":37,"tag":96,"props":5300,"children":5301},{"style":103},[5302],{"type":43,"value":5303},"        \"email\"",{"type":37,"tag":96,"props":5305,"children":5306},{"style":155},[5307],{"type":43,"value":399},{"type":37,"tag":96,"props":5309,"children":5310},{"style":103},[5311],{"type":43,"value":5312},"\"alice@example.com\"",{"type":37,"tag":96,"props":5314,"children":5315},{"style":155},[5316],{"type":43,"value":409},{"type":37,"tag":96,"props":5318,"children":5319},{"style":103},[5320],{"type":43,"value":5321},"\"bob@example.com\"",{"type":37,"tag":96,"props":5323,"children":5324},{"style":155},[5325],{"type":43,"value":409},{"type":37,"tag":96,"props":5327,"children":5328},{"style":103},[5329],{"type":43,"value":5330},"\"charlie@example.com\"",{"type":37,"tag":96,"props":5332,"children":5333},{"style":155},[5334],{"type":43,"value":2795},{"type":37,"tag":96,"props":5336,"children":5338},{"class":98,"line":5337},32,[5339,5344,5349,5354,5358,5363,5367,5372],{"type":37,"tag":96,"props":5340,"children":5341},{"style":103},[5342],{"type":43,"value":5343},"        \"created_at\"",{"type":37,"tag":96,"props":5345,"children":5346},{"style":155},[5347],{"type":43,"value":5348},": pd.to_datetime([",{"type":37,"tag":96,"props":5350,"children":5351},{"style":103},[5352],{"type":43,"value":5353},"\"2026-01-01\"",{"type":37,"tag":96,"props":5355,"children":5356},{"style":155},[5357],{"type":43,"value":409},{"type":37,"tag":96,"props":5359,"children":5360},{"style":103},[5361],{"type":43,"value":5362},"\"2026-01-02\"",{"type":37,"tag":96,"props":5364,"children":5365},{"style":155},[5366],{"type":43,"value":409},{"type":37,"tag":96,"props":5368,"children":5369},{"style":103},[5370],{"type":43,"value":5371},"\"2026-01-03\"",{"type":37,"tag":96,"props":5373,"children":5374},{"style":155},[5375],{"type":43,"value":5376},"]),\n",{"type":37,"tag":96,"props":5378,"children":5380},{"class":98,"line":5379},33,[5381],{"type":37,"tag":96,"props":5382,"children":5383},{"style":155},[5384],{"type":43,"value":4366},{"type":37,"tag":66,"props":5386,"children":5388},{"id":5387},"_5-add-quality-checks",[5389],{"type":43,"value":5390},"5) Add quality checks",{"type":37,"tag":46,"props":5392,"children":5393},{},[5394],{"type":43,"value":5395},"Materialized Python assets get the same column-level checks as SQL assets:",{"type":37,"tag":86,"props":5397,"children":5399},{"className":4562,"code":5398,"language":4564,"meta":7,"style":7},"columns:\n  - name: id\n    type: integer\n    primary_key: true\n    checks:\n      - name: unique\n      - name: not_null\n  - name: email\n    type: string\n    checks:\n      - name: not_null\n",[5400],{"type":37,"tag":52,"props":5401,"children":5402},{"__ignoreMap":7},[5403,5414,5433,5448,5463,5475,5496,5516,5536,5551,5562],{"type":37,"tag":96,"props":5404,"children":5405},{"class":98,"line":99},[5406,5410],{"type":37,"tag":96,"props":5407,"children":5408},{"style":4574},[5409],{"type":43,"value":4850},{"type":37,"tag":96,"props":5411,"children":5412},{"style":155},[5413],{"type":43,"value":2141},{"type":37,"tag":96,"props":5415,"children":5416},{"class":98,"line":109},[5417,5421,5425,5429],{"type":37,"tag":96,"props":5418,"children":5419},{"style":155},[5420],{"type":43,"value":4862},{"type":37,"tag":96,"props":5422,"children":5423},{"style":4574},[5424],{"type":43,"value":4867},{"type":37,"tag":96,"props":5426,"children":5427},{"style":155},[5428],{"type":43,"value":4593},{"type":37,"tag":96,"props":5430,"children":5431},{"style":103},[5432],{"type":43,"value":4876},{"type":37,"tag":96,"props":5434,"children":5435},{"class":98,"line":118},[5436,5440,5444],{"type":37,"tag":96,"props":5437,"children":5438},{"style":4574},[5439],{"type":43,"value":4884},{"type":37,"tag":96,"props":5441,"children":5442},{"style":155},[5443],{"type":43,"value":4593},{"type":37,"tag":96,"props":5445,"children":5446},{"style":103},[5447],{"type":43,"value":4893},{"type":37,"tag":96,"props":5449,"children":5450},{"class":98,"line":127},[5451,5455,5459],{"type":37,"tag":96,"props":5452,"children":5453},{"style":4574},[5454],{"type":43,"value":4901},{"type":37,"tag":96,"props":5456,"children":5457},{"style":155},[5458],{"type":43,"value":4593},{"type":37,"tag":96,"props":5460,"children":5461},{"style":149},[5462],{"type":43,"value":4910},{"type":37,"tag":96,"props":5464,"children":5465},{"class":98,"line":136},[5466,5471],{"type":37,"tag":96,"props":5467,"children":5468},{"style":4574},[5469],{"type":43,"value":5470},"    checks",{"type":37,"tag":96,"props":5472,"children":5473},{"style":155},[5474],{"type":43,"value":2141},{"type":37,"tag":96,"props":5476,"children":5477},{"class":98,"line":145},[5478,5483,5487,5491],{"type":37,"tag":96,"props":5479,"children":5480},{"style":155},[5481],{"type":43,"value":5482},"      - ",{"type":37,"tag":96,"props":5484,"children":5485},{"style":4574},[5486],{"type":43,"value":4867},{"type":37,"tag":96,"props":5488,"children":5489},{"style":155},[5490],{"type":43,"value":4593},{"type":37,"tag":96,"props":5492,"children":5493},{"style":103},[5494],{"type":43,"value":5495},"unique\n",{"type":37,"tag":96,"props":5497,"children":5498},{"class":98,"line":273},[5499,5503,5507,5511],{"type":37,"tag":96,"props":5500,"children":5501},{"style":155},[5502],{"type":43,"value":5482},{"type":37,"tag":96,"props":5504,"children":5505},{"style":4574},[5506],{"type":43,"value":4867},{"type":37,"tag":96,"props":5508,"children":5509},{"style":155},[5510],{"type":43,"value":4593},{"type":37,"tag":96,"props":5512,"children":5513},{"style":103},[5514],{"type":43,"value":5515},"not_null\n",{"type":37,"tag":96,"props":5517,"children":5518},{"class":98,"line":282},[5519,5523,5527,5531],{"type":37,"tag":96,"props":5520,"children":5521},{"style":155},[5522],{"type":43,"value":4862},{"type":37,"tag":96,"props":5524,"children":5525},{"style":4574},[5526],{"type":43,"value":4867},{"type":37,"tag":96,"props":5528,"children":5529},{"style":155},[5530],{"type":43,"value":4593},{"type":37,"tag":96,"props":5532,"children":5533},{"style":103},[5534],{"type":43,"value":5535},"email\n",{"type":37,"tag":96,"props":5537,"children":5538},{"class":98,"line":291},[5539,5543,5547],{"type":37,"tag":96,"props":5540,"children":5541},{"style":4574},[5542],{"type":43,"value":4884},{"type":37,"tag":96,"props":5544,"children":5545},{"style":155},[5546],{"type":43,"value":4593},{"type":37,"tag":96,"props":5548,"children":5549},{"style":103},[5550],{"type":43,"value":4946},{"type":37,"tag":96,"props":5552,"children":5553},{"class":98,"line":300},[5554,5558],{"type":37,"tag":96,"props":5555,"children":5556},{"style":4574},[5557],{"type":43,"value":5470},{"type":37,"tag":96,"props":5559,"children":5560},{"style":155},[5561],{"type":43,"value":2141},{"type":37,"tag":96,"props":5563,"children":5564},{"class":98,"line":309},[5565,5569,5573,5577],{"type":37,"tag":96,"props":5566,"children":5567},{"style":155},[5568],{"type":43,"value":5482},{"type":37,"tag":96,"props":5570,"children":5571},{"style":4574},[5572],{"type":43,"value":4867},{"type":37,"tag":96,"props":5574,"children":5575},{"style":155},[5576],{"type":43,"value":4593},{"type":37,"tag":96,"props":5578,"children":5579},{"style":103},[5580],{"type":43,"value":5515},{"type":37,"tag":46,"props":5582,"children":5583},{},[5584],{"type":43,"value":5585},"After the load, Bruin runs the checks and fails the asset if any fail.",{"type":37,"tag":66,"props":5587,"children":5589},{"id":5588},"_6-declare-column-level-lineage",[5590],{"type":43,"value":5591},"6) Declare column-level lineage",{"type":37,"tag":46,"props":5593,"children":5594},{},[5595],{"type":43,"value":5596},"Link columns back to their upstream sources so lineage shows up correctly in the UI:",{"type":37,"tag":86,"props":5598,"children":5600},{"className":4562,"code":5599,"language":4564,"meta":7,"style":7},"columns:\n  - name: id\n    type: integer\n    upstreams:\n      - table: raw.users\n        column: user_id\n",[5601],{"type":37,"tag":52,"props":5602,"children":5603},{"__ignoreMap":7},[5604,5615,5634,5649,5661,5681],{"type":37,"tag":96,"props":5605,"children":5606},{"class":98,"line":99},[5607,5611],{"type":37,"tag":96,"props":5608,"children":5609},{"style":4574},[5610],{"type":43,"value":4850},{"type":37,"tag":96,"props":5612,"children":5613},{"style":155},[5614],{"type":43,"value":2141},{"type":37,"tag":96,"props":5616,"children":5617},{"class":98,"line":109},[5618,5622,5626,5630],{"type":37,"tag":96,"props":5619,"children":5620},{"style":155},[5621],{"type":43,"value":4862},{"type":37,"tag":96,"props":5623,"children":5624},{"style":4574},[5625],{"type":43,"value":4867},{"type":37,"tag":96,"props":5627,"children":5628},{"style":155},[5629],{"type":43,"value":4593},{"type":37,"tag":96,"props":5631,"children":5632},{"style":103},[5633],{"type":43,"value":4876},{"type":37,"tag":96,"props":5635,"children":5636},{"class":98,"line":118},[5637,5641,5645],{"type":37,"tag":96,"props":5638,"children":5639},{"style":4574},[5640],{"type":43,"value":4884},{"type":37,"tag":96,"props":5642,"children":5643},{"style":155},[5644],{"type":43,"value":4593},{"type":37,"tag":96,"props":5646,"children":5647},{"style":103},[5648],{"type":43,"value":4893},{"type":37,"tag":96,"props":5650,"children":5651},{"class":98,"line":127},[5652,5657],{"type":37,"tag":96,"props":5653,"children":5654},{"style":4574},[5655],{"type":43,"value":5656},"    upstreams",{"type":37,"tag":96,"props":5658,"children":5659},{"style":155},[5660],{"type":43,"value":2141},{"type":37,"tag":96,"props":5662,"children":5663},{"class":98,"line":136},[5664,5668,5672,5676],{"type":37,"tag":96,"props":5665,"children":5666},{"style":155},[5667],{"type":43,"value":5482},{"type":37,"tag":96,"props":5669,"children":5670},{"style":4574},[5671],{"type":43,"value":4406},{"type":37,"tag":96,"props":5673,"children":5674},{"style":155},[5675],{"type":43,"value":4593},{"type":37,"tag":96,"props":5677,"children":5678},{"style":103},[5679],{"type":43,"value":5680},"raw.users\n",{"type":37,"tag":96,"props":5682,"children":5683},{"class":98,"line":145},[5684,5689,5693],{"type":37,"tag":96,"props":5685,"children":5686},{"style":4574},[5687],{"type":43,"value":5688},"        column",{"type":37,"tag":96,"props":5690,"children":5691},{"style":155},[5692],{"type":43,"value":4593},{"type":37,"tag":96,"props":5694,"children":5695},{"style":103},[5696],{"type":43,"value":5697},"user_id\n",{"type":37,"tag":66,"props":5699,"children":5701},{"id":5700},"_7-combine-materialization-with-the-python-sdk",[5702],{"type":43,"value":5703},"7) Combine materialization with the Python SDK",{"type":37,"tag":46,"props":5705,"children":5706},{},[5707,5709,5714,5716,5720,5722,5727],{"type":43,"value":5708},"Materialization handles the ",{"type":37,"tag":1275,"props":5710,"children":5711},{},[5712],{"type":43,"value":5713},"write",{"type":43,"value":5715},". The ",{"type":37,"tag":518,"props":5717,"children":5718},{"href":539},[5719],{"type":43,"value":542},{"type":43,"value":5721}," handles the ",{"type":37,"tag":1275,"props":5723,"children":5724},{},[5725],{"type":43,"value":5726},"read",{"type":43,"value":5728}," and everything in between. They compose naturally:",{"type":37,"tag":86,"props":5730,"children":5732},{"className":88,"code":5731,"language":90,"meta":7,"style":7},"\"\"\"@bruin\nname: analytics.active_users\nimage: python:3.13\nconnection: my_bigquery\n\nmaterialization:\n  type: table\n  strategy: merge\n\nparameters:\n  enforce_schema: true\n\ncolumns:\n  - name: id\n    type: integer\n    primary_key: true\n  - name: name\n    type: string\n    update_on_merge: true\n  - name: last_seen_at\n    type: timestamp\n    update_on_merge: true\n@bruin\"\"\"\n\nfrom bruin import query, context\n\ndef materialize():\n    if context.is_full_refresh:\n        return query(\"SELECT id, name, last_seen_at FROM raw.users WHERE active = true\")\n\n    return query(f\"\"\"\n        SELECT id, name, last_seen_at\n        FROM raw.users\n        WHERE active = true\n          AND last_seen_at BETWEEN '{context.start_date}' AND '{context.end_date}'\n    \"\"\")\n",[5733],{"type":37,"tag":52,"props":5734,"children":5735},{"__ignoreMap":7},[5736,5743,5750,5757,5764,5771,5778,5785,5792,5799,5806,5813,5820,5827,5834,5841,5848,5855,5862,5869,5877,5884,5891,5898,5905,5924,5931,5946,5957,5977,5984,6003,6011,6019,6027,6067],{"type":37,"tag":96,"props":5737,"children":5738},{"class":98,"line":99},[5739],{"type":37,"tag":96,"props":5740,"children":5741},{"style":103},[5742],{"type":43,"value":106},{"type":37,"tag":96,"props":5744,"children":5745},{"class":98,"line":109},[5746],{"type":37,"tag":96,"props":5747,"children":5748},{"style":103},[5749],{"type":43,"value":2925},{"type":37,"tag":96,"props":5751,"children":5752},{"class":98,"line":118},[5753],{"type":37,"tag":96,"props":5754,"children":5755},{"style":103},[5756],{"type":43,"value":124},{"type":37,"tag":96,"props":5758,"children":5759},{"class":98,"line":127},[5760],{"type":37,"tag":96,"props":5761,"children":5762},{"style":103},[5763],{"type":43,"value":246},{"type":37,"tag":96,"props":5765,"children":5766},{"class":98,"line":136},[5767],{"type":37,"tag":96,"props":5768,"children":5769},{"emptyLinePlaceholder":13},[5770],{"type":43,"value":142},{"type":37,"tag":96,"props":5772,"children":5773},{"class":98,"line":145},[5774],{"type":37,"tag":96,"props":5775,"children":5776},{"style":103},[5777],{"type":43,"value":254},{"type":37,"tag":96,"props":5779,"children":5780},{"class":98,"line":273},[5781],{"type":37,"tag":96,"props":5782,"children":5783},{"style":103},[5784],{"type":43,"value":262},{"type":37,"tag":96,"props":5786,"children":5787},{"class":98,"line":282},[5788],{"type":37,"tag":96,"props":5789,"children":5790},{"style":103},[5791],{"type":43,"value":270},{"type":37,"tag":96,"props":5793,"children":5794},{"class":98,"line":291},[5795],{"type":37,"tag":96,"props":5796,"children":5797},{"emptyLinePlaceholder":13},[5798],{"type":43,"value":142},{"type":37,"tag":96,"props":5800,"children":5801},{"class":98,"line":300},[5802],{"type":37,"tag":96,"props":5803,"children":5804},{"style":103},[5805],{"type":43,"value":5069},{"type":37,"tag":96,"props":5807,"children":5808},{"class":98,"line":309},[5809],{"type":37,"tag":96,"props":5810,"children":5811},{"style":103},[5812],{"type":43,"value":5077},{"type":37,"tag":96,"props":5814,"children":5815},{"class":98,"line":317},[5816],{"type":37,"tag":96,"props":5817,"children":5818},{"emptyLinePlaceholder":13},[5819],{"type":43,"value":142},{"type":37,"tag":96,"props":5821,"children":5822},{"class":98,"line":325},[5823],{"type":37,"tag":96,"props":5824,"children":5825},{"style":103},[5826],{"type":43,"value":279},{"type":37,"tag":96,"props":5828,"children":5829},{"class":98,"line":350},[5830],{"type":37,"tag":96,"props":5831,"children":5832},{"style":103},[5833],{"type":43,"value":288},{"type":37,"tag":96,"props":5835,"children":5836},{"class":98,"line":358},[5837],{"type":37,"tag":96,"props":5838,"children":5839},{"style":103},[5840],{"type":43,"value":297},{"type":37,"tag":96,"props":5842,"children":5843},{"class":98,"line":378},[5844],{"type":37,"tag":96,"props":5845,"children":5846},{"style":103},[5847],{"type":43,"value":306},{"type":37,"tag":96,"props":5849,"children":5850},{"class":98,"line":2770},[5851],{"type":37,"tag":96,"props":5852,"children":5853},{"style":103},[5854],{"type":43,"value":3010},{"type":37,"tag":96,"props":5856,"children":5857},{"class":98,"line":2798},[5858],{"type":37,"tag":96,"props":5859,"children":5860},{"style":103},[5861],{"type":43,"value":3018},{"type":37,"tag":96,"props":5863,"children":5864},{"class":98,"line":2816},[5865],{"type":37,"tag":96,"props":5866,"children":5867},{"style":103},[5868],{"type":43,"value":3026},{"type":37,"tag":96,"props":5870,"children":5871},{"class":98,"line":2838},[5872],{"type":37,"tag":96,"props":5873,"children":5874},{"style":103},[5875],{"type":43,"value":5876},"  - name: last_seen_at\n",{"type":37,"tag":96,"props":5878,"children":5879},{"class":98,"line":3069},[5880],{"type":37,"tag":96,"props":5881,"children":5882},{"style":103},[5883],{"type":43,"value":5157},{"type":37,"tag":96,"props":5885,"children":5886},{"class":98,"line":3085},[5887],{"type":37,"tag":96,"props":5888,"children":5889},{"style":103},[5890],{"type":43,"value":3026},{"type":37,"tag":96,"props":5892,"children":5893},{"class":98,"line":3098},[5894],{"type":37,"tag":96,"props":5895,"children":5896},{"style":103},[5897],{"type":43,"value":133},{"type":37,"tag":96,"props":5899,"children":5900},{"class":98,"line":3120},[5901],{"type":37,"tag":96,"props":5902,"children":5903},{"emptyLinePlaceholder":13},[5904],{"type":43,"value":142},{"type":37,"tag":96,"props":5906,"children":5907},{"class":98,"line":3128},[5908,5912,5916,5920],{"type":37,"tag":96,"props":5909,"children":5910},{"style":329},[5911],{"type":43,"value":605},{"type":37,"tag":96,"props":5913,"children":5914},{"style":155},[5915],{"type":43,"value":610},{"type":37,"tag":96,"props":5917,"children":5918},{"style":329},[5919],{"type":43,"value":332},{"type":37,"tag":96,"props":5921,"children":5922},{"style":155},[5923],{"type":43,"value":619},{"type":37,"tag":96,"props":5925,"children":5926},{"class":98,"line":3148},[5927],{"type":37,"tag":96,"props":5928,"children":5929},{"emptyLinePlaceholder":13},[5930],{"type":43,"value":142},{"type":37,"tag":96,"props":5932,"children":5933},{"class":98,"line":3157},[5934,5938,5942],{"type":37,"tag":96,"props":5935,"children":5936},{"style":329},[5937],{"type":43,"value":364},{"type":37,"tag":96,"props":5939,"children":5940},{"style":367},[5941],{"type":43,"value":370},{"type":37,"tag":96,"props":5943,"children":5944},{"style":155},[5945],{"type":43,"value":375},{"type":37,"tag":96,"props":5947,"children":5948},{"class":98,"line":3166},[5949,5953],{"type":37,"tag":96,"props":5950,"children":5951},{"style":329},[5952],{"type":43,"value":3091},{"type":37,"tag":96,"props":5954,"children":5955},{"style":155},[5956],{"type":43,"value":2103},{"type":37,"tag":96,"props":5958,"children":5959},{"class":98,"line":3207},[5960,5964,5968,5973],{"type":37,"tag":96,"props":5961,"children":5962},{"style":329},[5963],{"type":43,"value":3104},{"type":37,"tag":96,"props":5965,"children":5966},{"style":155},[5967],{"type":43,"value":644},{"type":37,"tag":96,"props":5969,"children":5970},{"style":103},[5971],{"type":43,"value":5972},"\"SELECT id, name, last_seen_at FROM raw.users WHERE active = true\"",{"type":37,"tag":96,"props":5974,"children":5975},{"style":155},[5976],{"type":43,"value":168},{"type":37,"tag":96,"props":5978,"children":5979},{"class":98,"line":5261},[5980],{"type":37,"tag":96,"props":5981,"children":5982},{"emptyLinePlaceholder":13},[5983],{"type":43,"value":142},{"type":37,"tag":96,"props":5985,"children":5986},{"class":98,"line":5297},[5987,5991,5995,5999],{"type":37,"tag":96,"props":5988,"children":5989},{"style":329},[5990],{"type":43,"value":384},{"type":37,"tag":96,"props":5992,"children":5993},{"style":155},[5994],{"type":43,"value":644},{"type":37,"tag":96,"props":5996,"children":5997},{"style":329},[5998],{"type":43,"value":649},{"type":37,"tag":96,"props":6000,"children":6001},{"style":103},[6002],{"type":43,"value":2165},{"type":37,"tag":96,"props":6004,"children":6005},{"class":98,"line":5337},[6006],{"type":37,"tag":96,"props":6007,"children":6008},{"style":103},[6009],{"type":43,"value":6010},"        SELECT id, name, last_seen_at\n",{"type":37,"tag":96,"props":6012,"children":6013},{"class":98,"line":5379},[6014],{"type":37,"tag":96,"props":6015,"children":6016},{"style":103},[6017],{"type":43,"value":6018},"        FROM raw.users\n",{"type":37,"tag":96,"props":6020,"children":6022},{"class":98,"line":6021},34,[6023],{"type":37,"tag":96,"props":6024,"children":6025},{"style":103},[6026],{"type":43,"value":3163},{"type":37,"tag":96,"props":6028,"children":6030},{"class":98,"line":6029},35,[6031,6035,6039,6043,6047,6051,6055,6059,6063],{"type":37,"tag":96,"props":6032,"children":6033},{"style":103},[6034],{"type":43,"value":3172},{"type":37,"tag":96,"props":6036,"children":6037},{"style":149},[6038],{"type":43,"value":659},{"type":37,"tag":96,"props":6040,"children":6041},{"style":155},[6042],{"type":43,"value":664},{"type":37,"tag":96,"props":6044,"children":6045},{"style":149},[6046],{"type":43,"value":669},{"type":37,"tag":96,"props":6048,"children":6049},{"style":103},[6050],{"type":43,"value":2198},{"type":37,"tag":96,"props":6052,"children":6053},{"style":149},[6054],{"type":43,"value":659},{"type":37,"tag":96,"props":6056,"children":6057},{"style":155},[6058],{"type":43,"value":2207},{"type":37,"tag":96,"props":6060,"children":6061},{"style":149},[6062],{"type":43,"value":669},{"type":37,"tag":96,"props":6064,"children":6065},{"style":103},[6066],{"type":43,"value":2216},{"type":37,"tag":96,"props":6068,"children":6070},{"class":98,"line":6069},36,[6071,6075],{"type":37,"tag":96,"props":6072,"children":6073},{"style":103},[6074],{"type":43,"value":2224},{"type":37,"tag":96,"props":6076,"children":6077},{"style":155},[6078],{"type":43,"value":168},{"type":37,"tag":46,"props":6080,"children":6081},{},[6082,6084,6089,6091,6096,6098,6103],{"type":43,"value":6083},"Here the SDK reads from the upstream table (with date filtering via ",{"type":37,"tag":52,"props":6085,"children":6087},{"className":6086},[],[6088],{"type":43,"value":577},{"type":43,"value":6090},") and materialization writes the result into ",{"type":37,"tag":52,"props":6092,"children":6094},{"className":6093},[],[6095],{"type":43,"value":3234},{"type":43,"value":6097}," using ",{"type":37,"tag":52,"props":6099,"children":6101},{"className":6100},[],[6102],{"type":43,"value":506},{"type":43,"value":1851},{"type":37,"tag":66,"props":6105,"children":6107},{"id":6106},"_8-run-it",[6108],{"type":43,"value":6109},"8) Run it",{"type":37,"tag":86,"props":6111,"children":6115},{"className":6112,"code":6113,"language":6114,"meta":7,"style":7},"language-bash shiki shiki-themes github-dark","bruin run assets/my_python_asset.py\n","bash",[6116],{"type":37,"tag":52,"props":6117,"children":6118},{"__ignoreMap":7},[6119],{"type":37,"tag":96,"props":6120,"children":6121},{"class":98,"line":99},[6122,6127,6132],{"type":37,"tag":96,"props":6123,"children":6124},{"style":367},[6125],{"type":43,"value":6126},"bruin",{"type":37,"tag":96,"props":6128,"children":6129},{"style":103},[6130],{"type":43,"value":6131}," run",{"type":37,"tag":96,"props":6133,"children":6134},{"style":103},[6135],{"type":43,"value":6136}," assets/my_python_asset.py\n",{"type":37,"tag":46,"props":6138,"children":6139},{},[6140],{"type":43,"value":6141},"For a full rebuild:",{"type":37,"tag":86,"props":6143,"children":6145},{"className":6112,"code":6144,"language":6114,"meta":7,"style":7},"bruin run --full-refresh assets/my_python_asset.py\n",[6146],{"type":37,"tag":52,"props":6147,"children":6148},{"__ignoreMap":7},[6149],{"type":37,"tag":96,"props":6150,"children":6151},{"class":98,"line":99},[6152,6156,6160,6165],{"type":37,"tag":96,"props":6153,"children":6154},{"style":367},[6155],{"type":43,"value":6126},{"type":37,"tag":96,"props":6157,"children":6158},{"style":103},[6159],{"type":43,"value":6131},{"type":37,"tag":96,"props":6161,"children":6162},{"style":149},[6163],{"type":43,"value":6164}," --full-refresh",{"type":37,"tag":96,"props":6166,"children":6167},{"style":103},[6168],{"type":43,"value":6136},{"type":37,"tag":46,"props":6170,"children":6171},{},[6172,6174,6179],{"type":43,"value":6173},"For a specific date window (use with ",{"type":37,"tag":52,"props":6175,"children":6177},{"className":6176},[],[6178],{"type":43,"value":498},{"type":43,"value":6180},"):",{"type":37,"tag":86,"props":6182,"children":6184},{"className":6112,"code":6183,"language":6114,"meta":7,"style":7},"bruin run --start-date 2026-04-01 --end-date 2026-04-23 assets/my_python_asset.py\n",[6185],{"type":37,"tag":52,"props":6186,"children":6187},{"__ignoreMap":7},[6188],{"type":37,"tag":96,"props":6189,"children":6190},{"class":98,"line":99},[6191,6195,6199,6204,6209,6214,6219],{"type":37,"tag":96,"props":6192,"children":6193},{"style":367},[6194],{"type":43,"value":6126},{"type":37,"tag":96,"props":6196,"children":6197},{"style":103},[6198],{"type":43,"value":6131},{"type":37,"tag":96,"props":6200,"children":6201},{"style":149},[6202],{"type":43,"value":6203}," --start-date",{"type":37,"tag":96,"props":6205,"children":6206},{"style":103},[6207],{"type":43,"value":6208}," 2026-04-01",{"type":37,"tag":96,"props":6210,"children":6211},{"style":149},[6212],{"type":43,"value":6213}," --end-date",{"type":37,"tag":96,"props":6215,"children":6216},{"style":103},[6217],{"type":43,"value":6218}," 2026-04-23",{"type":37,"tag":96,"props":6220,"children":6221},{"style":103},[6222],{"type":43,"value":6136},{"type":37,"tag":685,"props":6224,"children":6225},{},[],{"type":37,"tag":38,"props":6227,"children":6229},{"id":6228},"how-it-works-under-the-hood",[6230],{"type":43,"value":6231},"How it works under the hood",{"type":37,"tag":46,"props":6233,"children":6234},{},[6235],{"type":43,"value":6236},"Bruin uses Apache Arrow as the bridge between Python and the warehouse. On each run:",{"type":37,"tag":4037,"props":6238,"children":6239},{},[6240,6257,6269,6274,6284],{"type":37,"tag":558,"props":6241,"children":6242},{},[6243,6245,6250,6252],{"type":43,"value":6244},"Dependencies from your asset's ",{"type":37,"tag":52,"props":6246,"children":6248},{"className":6247},[],[6249],{"type":43,"value":179},{"type":43,"value":6251}," are installed via ",{"type":37,"tag":52,"props":6253,"children":6255},{"className":6254},[],[6256],{"type":43,"value":187},{"type":37,"tag":558,"props":6258,"children":6259},{},[6260,6262,6267],{"type":43,"value":6261},"Your ",{"type":37,"tag":52,"props":6263,"children":6265},{"className":6264},[],[6266],{"type":43,"value":214},{"type":43,"value":6268}," function runs",{"type":37,"tag":558,"props":6270,"children":6271},{},[6272],{"type":43,"value":6273},"The return value is serialized to a temporary Arrow file",{"type":37,"tag":558,"props":6275,"children":6276},{},[6277,6282],{"type":37,"tag":52,"props":6278,"children":6280},{"className":6279},[],[6281],{"type":43,"value":476},{"type":43,"value":6283}," loads the file into the destination with your chosen strategy",{"type":37,"tag":558,"props":6285,"children":6286},{},[6287],{"type":43,"value":6288},"The temporary file is deleted",{"type":37,"tag":46,"props":6290,"children":6291},{},[6292,6294,6299,6301,6306],{"type":43,"value":6293},"This means your Python code never needs warehouse credentials directly - ",{"type":37,"tag":52,"props":6295,"children":6297},{"className":6296},[],[6298],{"type":43,"value":476},{"type":43,"value":6300}," handles the load using the connection you declared in the ",{"type":37,"tag":52,"props":6302,"children":6304},{"className":6303},[],[6305],{"type":43,"value":82},{"type":43,"value":6307}," block.",{"type":37,"tag":685,"props":6309,"children":6310},{},[],{"type":37,"tag":38,"props":6312,"children":6313},{"id":3776},[6314],{"type":43,"value":3779},{"type":37,"tag":554,"props":6316,"children":6317},{},[6318,6338,6380,6390,6401],{"type":37,"tag":558,"props":6319,"children":6320},{},[6321,6323,6329,6331,6336],{"type":43,"value":6322},"Declare ",{"type":37,"tag":52,"props":6324,"children":6326},{"className":6325},[],[6327],{"type":43,"value":6328},"materialization.type: table",{"type":43,"value":6330}," plus a ",{"type":37,"tag":52,"props":6332,"children":6334},{"className":6333},[],[6335],{"type":43,"value":4429},{"type":43,"value":6337}," and Bruin loads your DataFrame for you",{"type":37,"tag":558,"props":6339,"children":6340},{},[6341,6343,6348,6349,6354,6355,6360,6361,6366,6368,6373,6374,6378],{"type":43,"value":6342},"Supported strategies: ",{"type":37,"tag":52,"props":6344,"children":6346},{"className":6345},[],[6347],{"type":43,"value":484},{"type":43,"value":409},{"type":37,"tag":52,"props":6350,"children":6352},{"className":6351},[],[6353],{"type":43,"value":491},{"type":43,"value":409},{"type":37,"tag":52,"props":6356,"children":6358},{"className":6357},[],[6359],{"type":43,"value":506},{"type":43,"value":409},{"type":37,"tag":52,"props":6362,"children":6364},{"className":6363},[],[6365],{"type":43,"value":498},{"type":43,"value":6367},". ",{"type":37,"tag":52,"props":6369,"children":6371},{"className":6370},[],[6372],{"type":43,"value":4518},{"type":43,"value":4400},{"type":37,"tag":1275,"props":6375,"children":6376},{},[6377],{"type":43,"value":4525},{"type":43,"value":6379}," supported for Python",{"type":37,"tag":558,"props":6381,"children":6382},{},[6383,6385],{"type":43,"value":6384},"Return a pandas DataFrame, polars DataFrame, or list of dicts from ",{"type":37,"tag":52,"props":6386,"children":6388},{"className":6387},[],[6389],{"type":43,"value":214},{"type":37,"tag":558,"props":6391,"children":6392},{},[6393,6395,6399],{"type":43,"value":6394},"Pair materialization with the ",{"type":37,"tag":518,"props":6396,"children":6397},{"href":539},[6398],{"type":43,"value":542},{"type":43,"value":6400}," to read, transform, and write with almost no boilerplate",{"type":37,"tag":558,"props":6402,"children":6403},{},[6404],{"type":43,"value":6405},"Column-level checks, lineage, and schema enforcement all work the same as SQL assets",{"type":37,"tag":685,"props":6407,"children":6408},{},[],{"type":37,"tag":38,"props":6410,"children":6411},{"id":3857},[6412],{"type":43,"value":3860},{"type":37,"tag":554,"props":6414,"children":6415},{},[6416,6425,6435,6443],{"type":37,"tag":558,"props":6417,"children":6418},{},[6419],{"type":37,"tag":518,"props":6420,"children":6422},{"href":3958,"rel":6421},[1285],[6423],{"type":43,"value":6424},"Python asset reference (Materialization section)",{"type":37,"tag":558,"props":6426,"children":6427},{},[6428],{"type":37,"tag":518,"props":6429,"children":6432},{"href":6430,"rel":6431},"https://getbruin.com/docs/bruin/assets/materialization.html",[1285],[6433],{"type":43,"value":6434},"Materialization strategies overview",{"type":37,"tag":558,"props":6436,"children":6437},{},[6438],{"type":37,"tag":518,"props":6439,"children":6440},{"href":539},[6441],{"type":43,"value":6442},"Bruin Python SDK tutorial",{"type":37,"tag":558,"props":6444,"children":6445},{},[6446],{"type":37,"tag":518,"props":6447,"children":6449},{"href":28,"rel":6448},[1285],[6450],{"type":43,"value":6451},"Bruin Python SDK on PyPI",{"type":37,"tag":694,"props":6453,"children":6454},{},[6455],{"type":43,"value":698},{"title":7,"searchDepth":109,"depth":109,"links":6457},[6458,6459,6460,6470,6471,6472],{"id":1267,"depth":109,"text":1270},{"id":4020,"depth":109,"text":4023},{"id":1471,"depth":109,"text":1474,"children":6461},[6462,6463,6464,6465,6466,6467,6468,6469],{"id":4097,"depth":118,"text":4100},{"id":4449,"depth":118,"text":4452},{"id":4504,"depth":118,"text":4507},{"id":4975,"depth":118,"text":4978},{"id":5387,"depth":118,"text":5390},{"id":5588,"depth":118,"text":5591},{"id":5700,"depth":118,"text":5703},{"id":6106,"depth":118,"text":6109},{"id":6228,"depth":109,"text":6231},{"id":3776,"depth":109,"text":3779},{"id":3857,"depth":109,"text":3860},"content:tutorials:python-materialization.md","tutorials/python-materialization.md","tutorials/python-materialization",1776974975036]