[{"data":1,"prerenderedAt":1163},["ShallowReactive",2],{"doc:\u002Fdocs\u002Fsql-scripts":3,"docs-nav":940},{"id":4,"title":5,"body":6,"description":16,"extension":932,"meta":933,"navigation":935,"path":936,"seo":937,"stem":938,"__hash__":939},"docs\u002Fdocs\u002Fsql-scripts.md","SQL scripts",{"type":7,"value":8,"toc":919},"minimark",[9,13,17,22,30,37,47,54,176,191,205,209,219,246,313,320,346,350,367,378,382,399,406,410,420,430,443,448,460,464,475,479,497,501,509,843,847,871,912,915],[10,11,5],"h1",{"id":12},"sql-scripts",[14,15,16],"p",{},"A SQL script is SQL kept in a folder, like a flow or a saved view: written in an editor,\nrun with one key, saved with its versions and shared through the folder's permissions.\nIt reads the datasources of the catalog on the engine you choose, or a database through\none of its connections. Every installation has it, Docker Compose included. The design is\nin the spec.",[18,19,21],"h2",{"id":20},"writing-one","Writing one",[14,23,24,25,29],{},"Explore → ",[26,27,28],"strong",{},"New → SQL script"," in a folder. The page has the editor, the result under it,\nand on the side the datasources you can read with their columns: a click on a name writes\nit where the cursor is, the arrow shows the columns, a click on a column writes it too.\nThe editor also completes names and columns as you type.",[14,31,32],{},[33,34],"img",{"alt":35,"src":36},"A SQL script page: the SQL on the sample orders, the result of 185 rows read from order_rows and orders on DuckDB, the Datasource card writing revenue_by_channel, and the list of datasources","\u002Fmedia\u002Fguide\u002Fsql\u002Fsql-script-revenue-by-channel.png",[14,38,39],{},[40,41,42,43,46],"em",{},"The script of the example below: the SQL, the result with its time and the datasources it read, and on the side the ",[26,44,45],{},"Datasource"," card and the catalog.",[14,48,49,50,53],{},"A datasource is a table by its ",[26,51,52],{},"name",". A name with spaces or capitals goes in double\nquotes; unquoted names match regardless of case:",[55,56,61],"pre",{"className":57,"code":58,"language":59,"meta":60,"style":60},"language-sql shiki shiki-themes github-dark-dimmed github-light","SELECT c.canale, count(*) AS ordini\nFROM \"orders\" o\nJOIN \"customers\" c ON o.cliente_id = c.id\nGROUP BY c.canale\nORDER BY ordini DESC\n","sql","",[62,63,64,105,118,151,164],"code",{"__ignoreMap":60},[65,66,69,73,77,81,84,87,90,93,96,99,102],"span",{"class":67,"line":68},"line",1,[65,70,72],{"class":71},"s6PUj","SELECT",[65,74,76],{"class":75},"swcJU"," c",[65,78,80],{"class":79},"ssh_m",".",[65,82,83],{"class":75},"canale",[65,85,86],{"class":79},", ",[65,88,89],{"class":75},"count",[65,91,92],{"class":79},"(",[65,94,95],{"class":71},"*",[65,97,98],{"class":79},") ",[65,100,101],{"class":71},"AS",[65,103,104],{"class":79}," ordini\n",[65,106,108,111,115],{"class":67,"line":107},2,[65,109,110],{"class":71},"FROM",[65,112,114],{"class":113},"sXfbr"," \"orders\"",[65,116,117],{"class":79}," o\n",[65,119,121,124,127,130,133,136,138,141,144,146,148],{"class":67,"line":120},3,[65,122,123],{"class":71},"JOIN",[65,125,126],{"class":113}," \"customers\"",[65,128,129],{"class":79}," c ",[65,131,132],{"class":71},"ON",[65,134,135],{"class":75}," o",[65,137,80],{"class":79},[65,139,140],{"class":75},"cliente_id",[65,142,143],{"class":71}," =",[65,145,76],{"class":75},[65,147,80],{"class":79},[65,149,150],{"class":75},"id\n",[65,152,154,157,159,161],{"class":67,"line":153},4,[65,155,156],{"class":71},"GROUP BY",[65,158,76],{"class":75},[65,160,80],{"class":79},[65,162,163],{"class":75},"canale\n",[65,165,167,170,173],{"class":67,"line":166},5,[65,168,169],{"class":71},"ORDER BY",[65,171,172],{"class":79}," ordini ",[65,174,175],{"class":71},"DESC\n",[14,177,178,179,182,183,186,187,190],{},"A name is unique only in its folder. When two datasources you can read share it, write the\nfolder's name in front, ",[62,180,181],{},"\"Marketing\".\"Clienti\"",": the error says so and lists the folders.\nWhen the two folders have the same name too (",[62,184,185],{},"Vendite \u002F Dati"," and ",[62,188,189],{},"Acquisti \u002F Dati","), the\nfolder's name does not tell them apart: the error says so, and one of the folders or of the\ndatasources needs another name. Renaming a datasource breaks the scripts that name it, as\nit would any SQL.",[14,192,193,194,197,198,186,201,204],{},"The dialect is the engine's: Polars SQL, DuckDB, ClickHouse or BigQuery, chosen at the top\nof the page (the administrator decides which engines may be chosen). On BigQuery a name is\nquoted in backticks, ",[62,195,196],{},"`Importo totale`"," (in double quotes it is a text): the list\nbeside the editor writes it so. ",[62,199,200],{},"--",[62,202,203],{},"\u002F* *\u002F"," comments are fine.",[18,206,208],{"id":207},"on-a-database-connection","On a database connection",[14,210,211,214,215,218],{},[26,212,213],{},"Where the SQL runs",", at the top of the page, is either ",[26,216,217],{},"Datasources"," (the catalog) or\none of the database connections you may use: PostgreSQL, MySQL, MariaDB, ClickHouse,\nTrino, Oracle or SQL Server. On a connection:",[220,221,222,230,243],"ul",{},[223,224,225,226,229],"li",{},"the SQL goes to the database ",[26,227,228],{},"as it is",", in the database's own dialect, and the\ndatabase's own message comes back when it refuses it;",[223,231,232,233,86,236,86,239,242],{},"the side lists the connection's tables; the arrow reads a table's columns and their\ntypes, and a click writes the name in the database's quoting\n(",[62,234,235],{},"catalogo.prodotti",[62,237,238],{},"`Orders 2024`",[62,240,241],{},"[dbo].[Orders]",");",[223,244,245],{},"there is no engine to choose: the database computes.",[55,247,249],{"className":57,"code":248,"language":59,"meta":60,"style":60},"SELECT p.categoria, count(*) AS prodotti\nFROM catalogo.prodotti p\nGROUP BY p.categoria\nORDER BY prodotti DESC\n",[62,250,251,278,293,304],{"__ignoreMap":60},[65,252,253,255,258,260,263,265,267,269,271,273,275],{"class":67,"line":68},[65,254,72],{"class":71},[65,256,257],{"class":75}," p",[65,259,80],{"class":79},[65,261,262],{"class":75},"categoria",[65,264,86],{"class":79},[65,266,89],{"class":75},[65,268,92],{"class":79},[65,270,95],{"class":71},[65,272,98],{"class":79},[65,274,101],{"class":71},[65,276,277],{"class":79}," prodotti\n",[65,279,280,282,285,287,290],{"class":67,"line":107},[65,281,110],{"class":71},[65,283,284],{"class":75}," catalogo",[65,286,80],{"class":79},[65,288,289],{"class":75},"prodotti",[65,291,292],{"class":79}," p\n",[65,294,295,297,299,301],{"class":67,"line":120},[65,296,156],{"class":71},[65,298,257],{"class":75},[65,300,80],{"class":79},[65,302,303],{"class":75},"categoria\n",[65,305,306,308,311],{"class":67,"line":153},[65,307,169],{"class":71},[65,309,310],{"class":79}," prodotti ",[65,312,175],{"class":71},[14,314,315,316,319],{},"Running SQL on a connection needs the ",[26,317,318],{},"CONNECT"," permission on the connection's folder,\nas importing from it does. A script is shared with its folder as any other, but a person\nwith VIEW on the folder and no CONNECT on the connection reads its SQL and cannot run it;\nchoosing a connection for a script needs CONNECT on it too.",[14,321,322,323,326,327,330,331,334,335,338,339,341,342,345],{},"The SQL runs inside ",[62,324,325],{},"SELECT * FROM (…)",", as a SQL datasource's, so a statement that is not\na query fails; on PostgreSQL, MySQL and MariaDB it also runs in a read-only transaction, so\na function it calls cannot write either. That is not the barrier: the barrier is a\n",[26,328,329],{},"read-only database user"," on the connection, as for database datasources. Give that user a time limit on the database\ntoo (PostgreSQL: ",[62,332,333],{},"ALTER ROLE lettore SET statement_timeout = '60s'","; MySQL:\n",[62,336,337],{},"max_execution_time","; ClickHouse: a settings profile with ",[62,340,337],{},"). Tabularia\nstops waiting after the preview time limit (",[62,343,344],{},"PREVIEW_TIMEOUT_SECONDS",") and asks the\ndatabase for no more rows than it shows, but a query the database is still computing ends\nonly by the database's own limit.",[18,347,349],{"id":348},"running","Running",[14,351,352,355,356,359,360,362,363,366],{},[26,353,354],{},"Run",", or ",[26,357,358],{},"Ctrl+Enter"," in the editor, runs the selection when there is one, otherwise\nthe whole script, and shows the first 200 rows with the time taken and the datasources\nread (or the connection). On the catalog only one query that reads data runs: a ",[62,361,72],{},"\n(a ",[62,364,365],{},"WITH"," before it too). It reads the datasources you name and nothing else: the engine\nchecks every table against the ones the gateway resolved, as for the SQL step of a flow.\nA new run of the same script stops the one still running.",[14,368,369,370,373,374,377],{},"A run reads with ",[26,371,372],{},"your"," permissions, whoever wrote the script: a datasource you cannot\nread gives the same error as one that does not exist. Every run is in the audit log\n(",[62,375,376],{},"sql_script.run",") with its SQL and the datasources it read, or the connection.",[18,379,381],{"id":380},"exporting-the-whole-result","Exporting the whole result",[14,383,384,385,186,388,391,392,394,395,398],{},"The run shows the first 200 rows; ",[26,386,387],{},"CSV",[26,389,390],{},"Excel",", beside the result, download all\nof them. The export runs what ",[40,393,354],{}," runs (the selection, or the whole script), with the\nsame checks: the datasources you may read, CONNECT on the connection. A worker writes the\nfile, as for the Viewer's export, and the browser saves it when it is ready, named after\nthe script. Every export is in the audit log (",[62,396,397],{},"sql_script.export",") with its SQL.",[14,400,401,402,405],{},"The caps are the Viewer's: a CSV holds at most ",[62,403,404],{},"EXPORT__MAX_ROWS"," rows (5 million by\ndefault), an Excel file the format's ~1 million. Over the cap the export stops and says\nso; on a connection the database is asked for no more rows than the cap and one. A result\nlarger than that belongs in a datasource.",[18,407,409],{"id":408},"writing-the-result-into-a-datasource","Writing the result into a datasource",[14,411,412,413,415,416,419],{},"A script can keep its whole result in a datasource, for flows, saved views and the\nother scripts to read. In the ",[26,414,45],{}," card beside the editor give it a name and a\nfolder, then ",[26,417,418],{},"Save",": the name and the folder are part of the script, and of its\nversions. Choosing the folder needs Edit on it; a datasource already there under that\nname is overwritten only when a flow or a script wrote it, never a database's or a\nfile's.",[14,421,422,425,426,429],{},[26,423,424],{},"Refresh now"," writes the whole result of the ",[26,427,428],{},"saved"," version (save first: unsaved\nchanges are not written). The first write creates the datasource; every write after\nreplaces its data and keeps its id, so whatever reads it keeps working. The datasource\nchanges only when a write succeeds, and its data contract, when it has one, is checked\nbefore. A description written on the datasource stays across the writes (the first one\nsays which script writes it). On the catalog the script's engine writes it; on a connection the database's\nwhole result is read, as for a SQL datasource. The card shows the last write: when, how\nmany rows, who started it, and why it failed.",[14,431,432,433,435,436,439,440,398],{},"Writing needs ",[26,434,354],{}," on the script's folder and ",[26,437,438],{},"Edit"," on the datasource's, and what\na run needs: the datasources the SQL names readable by whoever writes, CONNECT on the\nconnection. One write at a time: a second one waits for the first to end. Every write is\nin the audit log (",[62,441,442],{},"sql_script.publish",[444,445,447],"h3",{"id":446},"on-a-schedule","On a schedule",[14,449,450,453,454,459],{},[26,451,452],{},"Schedule"," sets a cron (",[455,456,458],"a",{"href":457},"\u002Fdocs\u002Fcapabilities\u002Fscheduling","scheduling","): the scheduler writes the datasource from the saved version,\nwith the rights of whoever set it, checked again every time. A write that those rights\nno longer allow is not started: it shows as a failed write with its reason, and the\nschedule stays, to write again once the rights are back. When someone else changes the\nscript's SQL, its connection or the datasource's folder, or moves the script, the\nschedule switches itself off (the audit log says why), because it would run their SQL\nwith the author's rights; the author's own changes keep it.",[444,461,463],{"id":462},"in-a-flow-group","In a flow group",[14,465,466,467,471,472,474],{},"A script that writes a datasource goes in a ",[455,468,470],{"href":469},"\u002Fdocs\u002Fcapabilities\u002Fflow-groups","flow group"," as a cell\n(",[26,473,5],{}," in the panel on the right): the cell writes the datasource in its step,\nafter the steps before it, and the next step reads the new data. Its failure stops the\ngroup as any cell's. Use a group when the script reads what flows produce: the group\nruns them first, then the script, on one schedule. A script in a group cannot be\ndeleted, nor lose its datasource, until it is taken out.",[444,476,478],{"id":477},"lineage","Lineage",[14,480,481,482,484,485,489,490,493,494,496],{},"The ",[26,483,478],{}," page draws a SQL script with the datasources its SQL names (or the\nconnection it runs on), the datasource it writes and the flow groups that run it.\nWith ",[455,486,488],{"href":487},"\u002Fdocs\u002Fopenlineage","OpenLineage"," on, every write is a run of the job\n",[62,491,492],{},"\u003Cfolder>\u002F\u003Cname> (SQL script)",": the datasources the write read (on a connection, the\ntables of the SQL), the datasource it wrote, the SQL in the ",[62,495,59],{}," facet.",[18,498,500],{"id":499},"example-the-revenue-by-channel-every-morning","Example: the revenue by channel, every morning",[14,502,503,504,508],{},"On the sample data (",[455,505,507],{"href":506},"\u002Fdocs\u002Fgetting-started-docker-compose#a-the-sample-data-already-there","the «Sample» folder","):\nthe net revenue of the orders by sales channel and month, kept as a datasource that the\nother flows, the Viewer and the assistant can read.",[510,511,512,531,794,799,820,828],"ol",{},[223,513,514,515,518,519,521,522,524,525,527,528,80],{},"In Explore, open ",[62,516,517],{},"Sample \u002F Private tables",", then ",[26,520,28],{},". At the top,\n",[26,523,213],{}," stays on ",[26,526,217],{},"; choose the engine ",[26,529,530],{},"DuckDB",[223,532,533,534,537,538,541,542],{},"Write the SQL (a click on ",[62,535,536],{},"order_rows"," or ",[62,539,540],{},"orders"," in the side list writes the name):",[55,543,545],{"className":57,"code":544,"language":59,"meta":60,"style":60},"-- Net revenue by sales channel and month, cancelled orders left out\nSELECT o.canale,\n       EXTRACT(YEAR FROM o.data_ordine) * 100 + EXTRACT(MONTH FROM o.data_ordine) AS anno_mese,\n       round(sum(CAST(r.quantita AS DOUBLE) * CAST(r.prezzo_unitario AS DOUBLE)\n                 * (1 - CAST(r.sconto_pct AS DOUBLE) \u002F 100)), 2) AS ricavo_netto\nFROM \"order_rows\" r\nJOIN \"orders\" o ON r.ordine_id = o.id\nWHERE o.stato \u003C> 'annullato'\nGROUP BY o.canale, anno_mese\nORDER BY anno_mese, ricavo_netto DESC\n",[62,546,547,553,566,615,665,712,723,751,770,784],{"__ignoreMap":60},[65,548,549],{"class":67,"line":68},[65,550,552],{"class":551},"sgHix","-- Net revenue by sales channel and month, cancelled orders left out\n",[65,554,555,557,559,561,563],{"class":67,"line":107},[65,556,72],{"class":71},[65,558,135],{"class":75},[65,560,80],{"class":79},[65,562,83],{"class":75},[65,564,565],{"class":79},",\n",[65,567,568,571,574,577,579,581,584,586,588,591,594,597,600,602,604,606,608,610,612],{"class":67,"line":120},[65,569,570],{"class":79},"       EXTRACT(",[65,572,573],{"class":71},"YEAR",[65,575,576],{"class":71}," FROM",[65,578,135],{"class":75},[65,580,80],{"class":79},[65,582,583],{"class":75},"data_ordine",[65,585,98],{"class":79},[65,587,95],{"class":71},[65,589,590],{"class":75}," 100",[65,592,593],{"class":71}," +",[65,595,596],{"class":79}," EXTRACT(",[65,598,599],{"class":71},"MONTH",[65,601,576],{"class":71},[65,603,135],{"class":75},[65,605,80],{"class":79},[65,607,583],{"class":75},[65,609,98],{"class":79},[65,611,101],{"class":71},[65,613,614],{"class":79}," anno_mese,\n",[65,616,617,620,622,625,627,630,632,635,637,640,643,646,648,651,653,655,657,660,662],{"class":67,"line":153},[65,618,619],{"class":75},"       round",[65,621,92],{"class":79},[65,623,624],{"class":75},"sum",[65,626,92],{"class":79},[65,628,629],{"class":75},"CAST",[65,631,92],{"class":79},[65,633,634],{"class":75},"r",[65,636,80],{"class":79},[65,638,639],{"class":75},"quantita",[65,641,642],{"class":71}," AS",[65,644,645],{"class":79}," DOUBLE) ",[65,647,95],{"class":71},[65,649,650],{"class":75}," CAST",[65,652,92],{"class":79},[65,654,634],{"class":75},[65,656,80],{"class":79},[65,658,659],{"class":75},"prezzo_unitario",[65,661,642],{"class":71},[65,663,664],{"class":79}," DOUBLE)\n",[65,666,667,670,673,676,679,681,683,685,687,690,692,694,697,699,702,705,707,709],{"class":67,"line":166},[65,668,669],{"class":71},"                 *",[65,671,672],{"class":79}," (",[65,674,675],{"class":75},"1",[65,677,678],{"class":71}," -",[65,680,650],{"class":75},[65,682,92],{"class":79},[65,684,634],{"class":75},[65,686,80],{"class":79},[65,688,689],{"class":75},"sconto_pct",[65,691,642],{"class":71},[65,693,645],{"class":79},[65,695,696],{"class":71},"\u002F",[65,698,590],{"class":75},[65,700,701],{"class":79},")), ",[65,703,704],{"class":75},"2",[65,706,98],{"class":79},[65,708,101],{"class":71},[65,710,711],{"class":79}," ricavo_netto\n",[65,713,715,717,720],{"class":67,"line":714},6,[65,716,110],{"class":71},[65,718,719],{"class":113}," \"order_rows\"",[65,721,722],{"class":79}," r\n",[65,724,726,728,730,733,735,738,740,743,745,747,749],{"class":67,"line":725},7,[65,727,123],{"class":71},[65,729,114],{"class":113},[65,731,732],{"class":79}," o ",[65,734,132],{"class":71},[65,736,737],{"class":75}," r",[65,739,80],{"class":79},[65,741,742],{"class":75},"ordine_id",[65,744,143],{"class":71},[65,746,135],{"class":75},[65,748,80],{"class":79},[65,750,150],{"class":75},[65,752,754,757,759,761,764,767],{"class":67,"line":753},8,[65,755,756],{"class":71},"WHERE",[65,758,135],{"class":75},[65,760,80],{"class":79},[65,762,763],{"class":75},"stato",[65,765,766],{"class":71}," \u003C>",[65,768,769],{"class":113}," 'annullato'\n",[65,771,773,775,777,779,781],{"class":67,"line":772},9,[65,774,156],{"class":71},[65,776,135],{"class":75},[65,778,80],{"class":79},[65,780,83],{"class":75},[65,782,783],{"class":79},", anno_mese\n",[65,785,787,789,792],{"class":67,"line":786},10,[65,788,169],{"class":71},[65,790,791],{"class":79}," anno_mese, ricavo_netto ",[65,793,175],{"class":71},[223,795,796,798],{},[26,797,358],{},". The result says «185 rows in 584 ms · DuckDB · read: order_rows,\norders»: one row per channel and month, the biggest channel of each month first.",[223,800,801,804,805,808,809,811,812,815,816,86,818,80],{},[26,802,803],{},"Create",", with the name ",[62,806,807],{},"Revenue by channel",". In the ",[26,810,45],{}," card write the\nname ",[62,813,814],{},"revenue_by_channel",", keep the folder ",[62,817,517],{},[26,819,418],{},[223,821,822,824,825,827],{},[26,823,424],{},". The card shows «Written …: 185 rows · by» you, and\n",[62,826,814],{}," is in the catalog.",[223,829,830,832,833,832,836,838,839,842],{},[26,831,452],{}," → ",[62,834,835],{},"0 6 * * 1-5",[26,837,418],{},": every working day at six the datasource is\nwritten again from the saved SQL. When it must wait for fresh orders, put it in a\n",[455,840,470],{"href":841},"\u002Fdocs\u002Fcapabilities\u002Fflow-groups#example-the-morning-sales-email"," after the\nrefreshes instead.",[18,844,846],{"id":845},"saving-and-sharing","Saving and sharing",[14,848,849,851,852,854,855,858,859,862,863,866,867,870],{},[26,850,803],{}," the first time, then ",[26,853,418],{}," (Ctrl+S): a save that changes the SQL, the\nengine, the connection or the datasource is a new version. ",[26,856,857],{},"Versions"," on the side lists them; ",[40,860,861],{},"View","\nshows an older one read-only, ",[40,864,865],{},"Restore"," makes it the newest. Old versions beyond\n",[62,868,869],{},"ORCHESTRATOR__VERSIONS_KEPT"," are pruned, the current one never.",[872,873,874,887],"table",{},[875,876,877],"thead",{},[878,879,880,884],"tr",{},[881,882,883],"th",{},"On the script's folder",[881,885,886],{},"You can",[888,889,890,898,905],"tbody",{},[878,891,892,895],{},[893,894,861],"td",{},[893,896,897],{},"open it, read its SQL, run it (on a connection: with CONNECT on it), try changes without saving them",[878,899,900,902],{},[893,901,354],{},[893,903,904],{},"write its datasource now, schedule it",[878,906,907,909],{},[893,908,438],{},[893,910,911],{},"save, rename, move, duplicate, delete it",[14,913,914],{},"Administrators see every script. SQL scripts show in Explore and in the search. A folder\nthat holds one cannot be deleted until it is moved or deleted.",[916,917,918],"style",{},"html pre.shiki code .s6PUj, html code.shiki .s6PUj{--shiki-default:#F47067;--shiki-light:#D73A49}html pre.shiki code .swcJU, html code.shiki .swcJU{--shiki-default:#6CB6FF;--shiki-light:#005CC5}html pre.shiki code .ssh_m, html code.shiki .ssh_m{--shiki-default:#ADBAC7;--shiki-light:#24292E}html pre.shiki code .sXfbr, html code.shiki .sXfbr{--shiki-default:#96D0FF;--shiki-light:#032F62}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);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .sgHix, html code.shiki .sgHix{--shiki-default:#768390;--shiki-light:#6A737D}",{"title":60,"searchDepth":107,"depth":120,"links":920},[921,922,923,924,925,930,931],{"id":20,"depth":107,"text":21},{"id":207,"depth":107,"text":208},{"id":348,"depth":107,"text":349},{"id":380,"depth":107,"text":381},{"id":408,"depth":107,"text":409,"children":926},[927,928,929],{"id":446,"depth":120,"text":447},{"id":462,"depth":120,"text":463},{"id":477,"depth":120,"text":478},{"id":499,"depth":107,"text":500},{"id":845,"depth":107,"text":846},"md",{"source":934},"docs\u002Fsql-scripts.md",true,"\u002Fdocs\u002Fsql-scripts",{"title":5,"description":16},"docs\u002Fsql-scripts","TmS39FTLL37kJE1lO0St8vgu80u-scQb24niNU7Dkik",[941,960,1012,1044,1076,1103,1129,1155],{"title":942,"icon":943,"intro":944,"items":945},"Getting started","start","Install it on one machine, learn the few ideas everything else is built on, and run a first flow.",[946,948,951,954,957],{"path":947,"title":942},"\u002Fdocs\u002Fgetting-started",{"path":949,"title":950},"\u002Fdocs\u002Fgetting-started-docker-compose","Walkthrough with Docker Compose",{"path":952,"title":953},"\u002Fdocs\u002Fdeploy\u002Fminikube","Try it on your computer (minikube)",{"path":955,"title":956},"\u002Fdocs\u002Fconcepts","Concepts",{"path":958,"title":959},"\u002Fdocs\u002Foverview","Overview (README)",{"title":961,"icon":962,"intro":963,"items":964},"Capabilities","capabilities","What you can build: visual flows, analysis on any step, AI questions, pixel-perfect reports, dashboards, Python, R and SQL scripts, containers and the orchestration that ties them together.",[965,968,971,974,977,980,983,986,989,990,993,996,998,1000,1003,1006,1009],{"path":966,"title":967},"\u002Fdocs\u002Fcapabilities","All capabilities",{"path":969,"title":970},"\u002Fdocs\u002Fcapabilities\u002Fflows","Low-code flows",{"path":972,"title":973},"\u002Fdocs\u002Fcapabilities\u002Fpreview-and-analysis","Preview and analysis",{"path":975,"title":976},"\u002Fdocs\u002Fcapabilities\u002Fask-your-data","Ask your data with AI",{"path":978,"title":979},"\u002Fdocs\u002Fcapabilities\u002Freports","Pixel-perfect reports",{"path":981,"title":982},"\u002Fdocs\u002Fcapabilities\u002Freport-functions","Report functions",{"path":984,"title":985},"\u002Fdocs\u002Fcapabilities\u002Fdashboards","Dashboards",{"path":987,"title":988},"\u002Fdocs\u002Fscripting","Python and R",{"path":936,"title":5},{"path":991,"title":992},"\u002Fdocs\u002Fcapabilities\u002Fnotebooks","marimo notebooks as apps",{"path":994,"title":995},"\u002Fdocs\u002Fcontainer-node","Docker images in flows",{"path":469,"title":997},"Flow groups: orchestration",{"path":457,"title":999},"Scheduling",{"path":1001,"title":1002},"\u002Fdocs\u002Fpushmail","Pushmail: datasources, reports and dashboards by email",{"path":1004,"title":1005},"\u002Fdocs\u002Fplaceholders","Dynamic dates",{"path":1007,"title":1008},"\u002Fdocs\u002Fcapabilities\u002Fengines","Engines",{"path":1010,"title":1011},"\u002Fdocs\u002Fengines\u002Fengine-differences","Engine differences",{"title":1013,"icon":1014,"intro":1015,"items":1016},"Sources","sources","Every way data comes in: files, databases, buckets, SFTP folders, HTTP APIs, SharePoint, Google Sheets, and the results of your own flows.",[1017,1020,1023,1026,1029,1032,1035,1038,1041],{"path":1018,"title":1019},"\u002Fdocs\u002Fsources","All sources",{"path":1021,"title":1022},"\u002Fdocs\u002Fsources\u002Ffiles","Uploaded files",{"path":1024,"title":1025},"\u002Fdocs\u002Fsources\u002Fdatabases","Database tables and queries",{"path":1027,"title":1028},"\u002Fdocs\u002Fs3-datasource","S3 buckets",{"path":1030,"title":1031},"\u002Fdocs\u002Fsftp","SFTP folders",{"path":1033,"title":1034},"\u002Fdocs\u002Fapi-datasource","HTTP APIs",{"path":1036,"title":1037},"\u002Fdocs\u002Fsources\u002Fsharepoint","Excel on SharePoint",{"path":1039,"title":1040},"\u002Fdocs\u002Fsources\u002Fgoogle-sheets","Google Sheets",{"path":1042,"title":1043},"\u002Fdocs\u002Fsources\u002Fflow-outputs","Results of flows and scripts",{"title":1045,"icon":1046,"intro":1047,"items":1048},"Connections","connections","The systems Tabularia reads from and writes to, how each connection is set up, and who may use it.",[1049,1052,1055,1058,1061,1063,1064,1066,1067,1070,1073],{"path":1050,"title":1051},"\u002Fdocs\u002Fconnections","All connections",{"path":1053,"title":1054},"\u002Fdocs\u002Fconnections\u002Fdatabases","Databases",{"path":1056,"title":1057},"\u002Fdocs\u002Fsqlserver","Microsoft SQL Server driver",{"path":1059,"title":1060},"\u002Fdocs\u002Fconnections\u002Fs3","S3 and compatible storage",{"path":1030,"title":1062},"SFTP servers",{"path":1033,"title":1034},{"path":1036,"title":1065},"SharePoint",{"path":1039,"title":1040},{"path":1068,"title":1069},"\u002Fdocs\u002Fconnections\u002Fsmtp","SMTP email",{"path":1071,"title":1072},"\u002Fdocs\u002Fcontainer-registries","Container registries",{"path":1074,"title":1075},"\u002Fdocs\u002Fconnections\u002Fdestinations","Writing data out",{"title":1077,"icon":1078,"intro":1079,"items":1080},"Integrations","integrations","How Tabularia fits your stack: AI providers, the REST API and webhooks, dbt, OpenLineage, single sign-on, SIEM and monitoring.",[1081,1084,1087,1090,1093,1094,1097,1100],{"path":1082,"title":1083},"\u002Fdocs\u002Fintegrations","All integrations",{"path":1085,"title":1086},"\u002Fdocs\u002Fintegrations\u002Fai","AI: where it is used",{"path":1088,"title":1089},"\u002Fdocs\u002Fapi","API, tokens and webhooks",{"path":1091,"title":1092},"\u002Fdocs\u002Fdbt-export","Export to dbt",{"path":487,"title":488},{"path":1095,"title":1096},"\u002Fdocs\u002Fsso-keycloak","Single sign-on with Keycloak",{"path":1098,"title":1099},"\u002Fdocs\u002Fsiem-splunk","Audit log to Splunk",{"path":1101,"title":1102},"\u002Fdocs\u002Fintegrations\u002Fmonitoring","Monitoring",{"title":1104,"icon":1105,"intro":1106,"items":1107},"Security & governance","governance","Who may see and do what, what is recorded, and how data quality and personal data are kept in check.",[1108,1111,1114,1117,1120,1123,1126],{"path":1109,"title":1110},"\u002Fdocs\u002Fgovernance","Overview",{"path":1112,"title":1113},"\u002Fdocs\u002Fgovernance\u002Fpermissions","Permissions",{"path":1115,"title":1116},"\u002Fdocs\u002Fgovernance\u002Faudit-log","Audit log",{"path":1118,"title":1119},"\u002Fdocs\u002Fgovernance\u002Fdata-contracts","Data contracts",{"path":1121,"title":1122},"\u002Fdocs\u002Fdesign\u002Fsso-group-mapping","SSO and group mapping",{"path":1124,"title":1125},"\u002Fdocs\u002Fexamples\u002Fkeycloak","Keycloak example on a laptop",{"path":1127,"title":1128},"\u002Fdocs\u002Fengines\u002Fclickhouse-ai-user","A ClickHouse user for the AI assistant",{"title":1130,"icon":1131,"intro":1132,"items":1133},"Install & operate","operate","Run it in production on Kubernetes, configure it, upgrade it and keep it healthy.",[1134,1137,1140,1143,1146,1149,1152],{"path":1135,"title":1136},"\u002Fdocs\u002Fdeploy\u002Fkubernetes","Kubernetes and Helm",{"path":1138,"title":1139},"\u002Fdocs\u002Fdeploy\u002Fkind","A company-like cluster on one computer (kind)",{"path":1141,"title":1142},"\u002Fdocs\u002Fdeploy\u002Fupgrading","Upgrading, backups and restore",{"path":1144,"title":1145},"\u002Fdocs\u002Fdeploy\u002Frelease-checklist","Install and upgrade checklist",{"path":1147,"title":1148},"\u002Fdocs\u002Fconfiguration","Configuration reference",{"path":1150,"title":1151},"\u002Fdocs\u002Fengine-settings","Settings from the panel",{"path":1153,"title":1154},"\u002Fdocs\u002Fdatabase-migrations","Database migrations",{"title":1156,"icon":1157,"intro":1158,"items":1159},"Reference","reference","Release process and the remaining reference pages.",[1160],{"path":1161,"title":1162},"\u002Fdocs\u002Frelease-process","Release process",1793656371663]