[{"data":1,"prerenderedAt":1517},["ShallowReactive",2],{"navigation_docs_en":3,"-en-contributing-conventions-getting-started":241,"-en-contributing-conventions-getting-started-surround":1512},[4,17,42,206,232],{"title":5,"redirect":6,"path":7,"stem":8,"children":9,"page":16},"Introduction","\u002Fen\u002Fintroduction\u002Fintroduction","\u002Fen\u002Fintroduction","en\u002F1.introduction",[10,12],{"title":5,"path":6,"stem":11},"en\u002F1.introduction\u002F1.introduction",{"title":13,"path":14,"stem":15},"Prerequisites","\u002Fen\u002Fintroduction\u002Fprerequisites","en\u002F1.introduction\u002F2.prerequisites",false,{"title":18,"redirect":19,"path":20,"stem":21,"children":22,"page":16},"Installation","\u002Fen\u002Finstallation\u002Fsetup","\u002Fen\u002Finstallation","en\u002F2.installation",[23,26,30,34,38],{"title":24,"path":19,"stem":25},"Machine set-up","en\u002F2.installation\u002F1.setup",{"title":27,"path":28,"stem":29},"A Tale of Two Repos","\u002Fen\u002Finstallation\u002Ftale-repos","en\u002F2.installation\u002F2.tale-repos",{"title":31,"path":32,"stem":33},"Database connection","\u002Fen\u002Finstallation\u002Fdbt-profile","en\u002F2.installation\u002F3.dbt-profile",{"title":35,"path":36,"stem":37},"Smoke-testing","\u002Fen\u002Finstallation\u002Fsmoke-testing","en\u002F2.installation\u002F4.smoke-testing",{"title":39,"path":40,"stem":41},"What now ?","\u002Fen\u002Finstallation\u002Fwhat-now","en\u002F2.installation\u002F5.what-now",{"title":43,"path":44,"stem":45,"children":46,"page":16},"Users Guide","\u002Fen\u002Fusing","en\u002F3.using",[47,50,54,88,188,202],{"title":5,"path":48,"stem":49},"\u002Fen\u002Fusing\u002Fintroduction","en\u002F3.using\u002F1.introduction",{"title":51,"path":52,"stem":53},"Running the ETL","\u002Fen\u002Fusing\u002Frunning","en\u002F3.using\u002F2.running",{"title":55,"path":56,"stem":57,"children":58,"page":16},"Configuration","\u002Fen\u002Fusing\u002Fconfiguration","en\u002F3.using\u002F3.configuration",[59,72,76,80,84],{"title":60,"path":61,"stem":62,"children":63,"page":16},"Architecture","\u002Fen\u002Fusing\u002Fconfiguration\u002Farchitecture","en\u002F3.using\u002F3.configuration\u002F1.architecture",[64,68],{"title":65,"path":66,"stem":67},"Overview","\u002Fen\u002Fusing\u002Fconfiguration\u002Farchitecture\u002Foverview","en\u002F3.using\u002F3.configuration\u002F1.architecture\u002F1.overview",{"title":69,"path":70,"stem":71},"Marts and reporting layer","\u002Fen\u002Fusing\u002Fconfiguration\u002Farchitecture\u002Fmarts-reporting","en\u002F3.using\u002F3.configuration\u002F1.architecture\u002F2.marts-reporting",{"title":73,"path":74,"stem":75},"Linking the databases","\u002Fen\u002Fusing\u002Fconfiguration\u002Fdatabases","en\u002F3.using\u002F3.configuration\u002F2.databases",{"title":77,"path":78,"stem":79},"Adapters and seeds","\u002Fen\u002Fusing\u002Fconfiguration\u002Fadapts-seeds","en\u002F3.using\u002F3.configuration\u002F3.adapts-seeds",{"title":81,"path":82,"stem":83},"Enabling a resource","\u002Fen\u002Fusing\u002Fconfiguration\u002Fenabling","en\u002F3.using\u002F3.configuration\u002F4.enabling",{"title":85,"path":86,"stem":87},"Overriding","\u002Fen\u002Fusing\u002Fconfiguration\u002Foverriding","en\u002F3.using\u002F3.configuration\u002F5.overriding",{"title":89,"redirect":90,"path":91,"stem":92,"children":93,"page":16},"Dashboards","\u002Fen\u002Fusing\u002F","\u002Fen\u002Fusing\u002Fdashboards","en\u002F3.using\u002F4.dashboards",[94,97,126,167,176,184],{"title":5,"path":95,"stem":96},"\u002Fen\u002Fusing\u002Fdashboards\u002Fintroduction","en\u002F3.using\u002F4.dashboards\u002F1.introduction",{"title":98,"redirect":99,"path":99,"stem":100,"children":101,"page":16},"Human resources","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr","en\u002F3.using\u002F4.dashboards\u002F2. hr",[102,106,110,114,118,122],{"title":103,"path":104,"stem":105},"Employees leaves","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Femp_conge","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F1.emp_conge",{"title":107,"path":108,"stem":109},"Active employees","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Fempl_actif","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F2.empl_actif",{"title":111,"path":112,"stem":113},"Retirement","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Fretirement","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F3.retirement",{"title":115,"path":116,"stem":117},"Efficacité","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Fefficacite","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F4.efficacite",{"title":119,"path":120,"stem":121},"Absences des employé(e)s","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Femp_abs","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F5.emp_abs",{"title":123,"path":124,"stem":125},"Resignation","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Fresignation","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F6.resignation",{"title":127,"redirect":128,"path":128,"stem":129,"children":130,"page":16},"Educational service","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv",[131,135,139,143,147,151,155,159,163],{"title":132,"path":133,"stem":134},"Res epreuves","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fres_epreuves","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F1.res_epreuves",{"title":136,"path":137,"stem":138},"Students results monitoring","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fsuivi_resultats","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F2.suivi_resultats",{"title":140,"path":141,"stem":142},"Students headcount","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Feffectif_css","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F3.effectif_css",{"title":144,"path":145,"stem":146},"Students absenteeism","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fchronic_absenteeism","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F4.chronic_absenteeism",{"title":148,"path":149,"stem":150},"Academic results","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fres_scolaires","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F5.res_scolaires",{"title":152,"path":153,"stem":154},"Predictive modelling - aggregated","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fpredictive-aggregated","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F6.predictive-aggregated",{"title":156,"path":157,"stem":158},"PEVR","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fpevr","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F7.pevr",{"title":160,"path":161,"stem":162},"Absenteeism","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fabsenteeism","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F8.absenteeism",{"title":164,"path":165,"stem":166},"Diplôme","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fdiplome","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F9.diplome",{"title":168,"redirect":169,"path":169,"stem":170,"children":171,"page":16},"School organisation","\u002Fen\u002Fusing\u002Fdashboards\u002Fschool-org","en\u002F3.using\u002F4.dashboards\u002F4.school-org",[172],{"title":173,"path":174,"stem":175},"Anomalies","\u002Fen\u002Fusing\u002Fdashboards\u002Fschool-org\u002Fanomalies","en\u002F3.using\u002F4.dashboards\u002F4.school-org\u002F1.anomalies",{"title":177,"path":178,"stem":179,"children":180,"page":16},"DirectionGenerale","\u002Fen\u002Fusing\u002Fdashboards\u002Fdirection_generale","en\u002F3.using\u002F4.dashboards\u002F5.direction_generale",[181],{"title":156,"path":182,"stem":183},"\u002Fen\u002Fusing\u002Fdashboards\u002Fdirection_generale\u002Fpevr","en\u002F3.using\u002F4.dashboards\u002F5.direction_generale\u002F1.pevr",{"title":185,"path":186,"stem":187},"Row Level Security","\u002Fen\u002Fusing\u002Fdashboards\u002Frls","en\u002F3.using\u002F4.dashboards\u002F5.rls",{"title":189,"redirect":90,"path":190,"stem":191,"children":192,"page":16},"Data marts","\u002Fen\u002Fusing\u002Fmarts","en\u002F3.using\u002F6.marts",[193,196,199],{"title":5,"path":194,"stem":195},"\u002Fen\u002Fusing\u002Fmarts\u002Fmarts","en\u002F3.using\u002F6.marts\u002F1.marts",{"title":127,"path":197,"stem":198},"\u002Fen\u002Fusing\u002Fmarts\u002Feducational-service","en\u002F3.using\u002F6.marts\u002F2.educational-service",{"title":98,"path":200,"stem":201},"\u002Fen\u002Fusing\u002Fmarts\u002Fhuman-resources","en\u002F3.using\u002F6.marts\u002F3.human-resources",{"title":203,"path":204,"stem":205},"Production checklist","\u002Fen\u002Fusing\u002Fproduction","en\u002F3.using\u002F7.production",{"title":207,"redirect":208,"path":209,"stem":210,"children":211,"page":16},"Developers Guide","\u002Fen\u002Fcontributing\u002Fgetting-started","\u002Fen\u002Fcontributing","en\u002F4.contributing",[212,215,223],{"title":213,"path":208,"stem":214},"Getting Started","en\u002F4.contributing\u002F1.getting-started",{"title":216,"redirect":217,"path":218,"stem":219,"children":220,"page":16},"Conventions","\u002Fen\u002Fcontributing\u002Fconventions\u002Fgetting-started","\u002Fen\u002Fcontributing\u002Fconventions","en\u002F4.contributing\u002F2.conventions",[221],{"title":213,"path":217,"stem":222},"en\u002F4.contributing\u002F2.conventions\u002F1.getting-started",{"title":224,"path":225,"stem":226,"children":227,"page":16},"Docs Ref","\u002Fen\u002Fcontributing\u002Fdocs","en\u002F4.contributing\u002F99.docs",[228],{"title":229,"path":230,"stem":231},"Components","\u002Fen\u002Fcontributing\u002Fdocs\u002Fcomponents","en\u002F4.contributing\u002F99.docs\u002F1.components",{"title":233,"redirect":6,"path":234,"stem":235,"children":236,"page":16},"Migrations","\u002Fen\u002Fmigrations","en\u002F5.migrations",[237],{"title":238,"path":239,"stem":240},"V0.17 -> V0.18","\u002Fen\u002Fmigrations\u002Fv0.17_to_v0.18","en\u002F5.migrations\u002F1.v0.17_to_v0.18",{"id":242,"title":213,"body":243,"description":280,"extension":1507,"links":1508,"meta":1509,"navigation":596,"path":217,"seo":1510,"stem":222,"__hash__":1511},"docs_en\u002Fen\u002F4.contributing\u002F2.conventions\u002F1.getting-started.md",{"type":244,"value":245,"toc":1495},"minimark",[246,251,256,260,271,274,295,305,309,314,317,375,379,394,403,409,417,420,452,456,461,480,483,488,493,498,511,518,545,552,578,668,677,680,685,689,698,708,714,721,725,737,744,752,759,812,819,824,833,836,845,872,880,967,972,979,986,990,1011,1015,1024,1050,1122,1126,1134,1138,1152,1281,1286,1290,1295,1298,1307,1313,1396,1403,1419,1442,1451,1455,1458,1464,1468,1473,1492],[247,248,250],"h2",{"id":249},"conventions-and-development-guidelines","Conventions and development guidelines",[252,253,255],"h3",{"id":254},"committing","Committing",[257,258,259],"h4",{"id":259},"sqlfmt",[261,262,263],"blockquote",{},[264,265,266,267,270],"p",{},"We use ",[268,269,259],"code",{}," as an SQL formatter. Whether we love it or not, we have to use it, so everybody's code will look the same, making collaboration easier. Some linting rules might be controversial, but at least they are consistent and explicit.",[264,272,273],{},"Before committing, make sure to run the following command",[275,276,281],"pre",{"className":277,"code":278,"language":279,"meta":280,"style":280},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","sqlfmt .\n","bash","",[268,282,283],{"__ignoreMap":280},[284,285,288,291],"span",{"class":286,"line":287},"line",1,[284,289,259],{"class":290},"sBMFI",[284,292,294],{"class":293},"sfazB"," .\n",[264,296,297,298,301,302,304],{},"... You might want to rerun a ",[268,299,300],{},"dbt build"," after formatting everything. ",[268,303,259],{}," shouldn't break anything, but we are better safe than sorry.",[257,306,308],{"id":307},"commit-message","Commit message",[261,310,311],{},[264,312,313],{},"Commit messages use the Commitizen convention.",[264,315,316],{},"Please make sure all of your commit messages start with a type. The following types are available:",[318,319,320,327,333,339,345,351,357,363,369],"ul",{},[321,322,323,326],"li",{},[268,324,325],{},"feat"," : A new feature",[321,328,329,332],{},[268,330,331],{},"fix"," : A bug fix",[321,334,335,338],{},[268,336,337],{},"docs"," : Documentation only changes",[321,340,341,344],{},[268,342,343],{},"style"," : Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)",[321,346,347,350],{},[268,348,349],{},"refactor"," : A code change that neither fixes a bug nor adds a feature",[321,352,353,356],{},[268,354,355],{},"perf"," : A code change that improves performance",[321,358,359,362],{},[268,360,361],{},"test"," : Adding missing or correcting existing tests",[321,364,365,368],{},[268,366,367],{},"chore"," : Changes to the build process or auxiliary tools and libraries such as documentation generation",[321,370,371,374],{},[268,372,373],{},"revert"," : Reverts a previous commit",[252,376,378],{"id":377},"folder-structure-and-convention","Folder structure and convention",[318,380,381,388],{},[321,382,383,384,387],{},"All the SQL \u002F Python code lives in the ",[268,385,386],{},"models"," folder.",[321,389,390,391,387],{},"All dashboards and reports live in the ",[268,392,393],{},"reporting",[264,395,396],{},[397,398,399,400,402],"strong",{},"About the ",[268,401,386],{}," folder",[264,404,405,406,408],{},"The ",[268,407,386],{}," folder is organized as follows:",[275,410,415],{"className":411,"code":413,"language":414},[412],"language-text",".\n└── models\u002F\n    ├── interfaces\u002F\n    │   └── database_spame\u002F\n    │       └── mart_foobar\n    ├── marts\u002F\n    │   └── mart_foobar\n    └── dashboards\u002F\n        ├── spam\u002F\n        │   ├── features\u002F\n        │   │   └── fact_absences.sql\n        │   └── pbi_tables\u002F\n        │      └── fact_absences.sql\n        └── egg\u002F\n            ...\n","text",[268,416,413],{"__ignoreMap":280},[264,418,419],{},"Where :",[318,421,422,436,442],{},[321,423,424,427,428,431,432,435],{},[268,425,426],{},"dashboards",": each subfolder of ",[268,429,430],{},"models\u002Fdashboards"," should be named after the corresponding dashboard it belongs to (",[397,433,434],{},"one dashboard, one folder containing its SQL code",").",[321,437,438,441],{},[268,439,440],{},"interfaces",": contains mappings to the interface tables. Each interface table can be overridden to add custom connection logic to the underlying database.",[321,443,444,447,448,451],{},[268,445,446],{},"marts",": contains the marts. A ",[268,449,450],{},"mart"," is a collection of tables reused\u002Fshared across dashboards.",[252,453,455],{"id":454},"integration-test-and-the-nightly-build","Integration test and the nightly build",[261,457,458],{},[264,459,460],{},"The nightly build is an automated check on the repo happening at the end of each day.",[264,462,463,464,467,468,471,472,475,476,479],{},"When introducing a new ",[397,465,466],{},"NON-OPTIONAL"," seed in the ",[268,469,470],{},"core.dashboards_store"," repo, you must add it into ",[268,473,474],{},"core.dashboards_store\u002Fnightly\u002Fdbt\u002Fseeds"," folder, so the next Nightly build won't fail because of a missing seed. The seed must be populated with data from CSSVDC, as the CSSVDC is used as a target database for the integration tests.\nYou can also run the integration suite locally. Please, refer to the ",[268,477,478],{},"core.dashboards_store\u002Fnightly\u002FREADME.md"," file for more details.",[252,481,482],{"id":446},"Marts",[257,484,486],{"id":485},"educ_serv",[268,487,485],{},[261,489,490],{},[264,491,492],{},"This mart gathers all the data related to the education service.",[494,495,497],"h5",{"id":496},"populations","Populations",[264,499,500,502,503,510],{},[268,501,497],{}," are sets of students used as a filter by various dashboards. ",[397,504,505,506,509],{},"You can refer to the ",[268,507,508],{},"analyses\u002Fmarts\u002Feduc_serv\u002Fstaging\u002Fpopulations"," folder and use the population template to build\u002Fdefine your populations",".",[264,512,513,514,517],{},"The following populations are mandatory (cf ",[268,515,516],{},"adapters",") and should be defined :",[318,519,520,525,530,535,540],{},[321,521,522],{},[268,523,524],{},"stg_ele_prescolaire",[321,526,527],{},[268,528,529],{},"stg_ele_primaire_reg",[321,531,532],{},[268,533,534],{},"stg_ele_primaire_adapt",[321,536,537],{},[268,538,539],{},"stg_ele_secondaire_reg",[321,541,542],{},[268,543,544],{},"stg_ele_secondaire_adapt",[264,546,547,548,551],{},"The integrator can add new populations by overriding the ",[268,549,550],{},"custom_fgj_populations.sql"," model. To do so:",[553,554,555,564,571],"ol",{},[321,556,557,558,561,562],{},"Create a new file in ",[268,559,560],{},"cssXX.dashboards_store\u002Fmodels\u002Fmarts\u002Feduc_serv\u002Fstaging\u002Fpopulations"," named ",[268,563,550],{},[321,565,566,567,570],{},"Your ",[268,568,569],{},"custom_fgj_populations"," model should be implemented as a union of your own custom populations.",[321,572,573,574,577],{},"Disable the core's placeholder in the ",[268,575,576],{},"cssXX.dashboards_store",":",[275,579,583],{"className":580,"code":581,"language":582,"meta":280,"style":280},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# cssXX.dashboards_store\u002Fdbt_project.yml\n\nmodels:\n  core_dashboards_store:\n    marts:\n      educ_serv:\n        staging:\n          populations:\n            custom_fgj_populations:\n              +enabled: false\n","yaml",[268,584,585,591,598,608,616,624,632,640,648,656],{"__ignoreMap":280},[284,586,587],{"class":286,"line":287},[284,588,590],{"class":589},"sHwdD","# cssXX.dashboards_store\u002Fdbt_project.yml\n",[284,592,594],{"class":286,"line":593},2,[284,595,597],{"emptyLinePlaceholder":596},true,"\n",[284,599,601,604],{"class":286,"line":600},3,[284,602,386],{"class":603},"swJcz",[284,605,607],{"class":606},"sMK4o",":\n",[284,609,611,614],{"class":286,"line":610},4,[284,612,613],{"class":603},"  core_dashboards_store",[284,615,607],{"class":606},[284,617,619,622],{"class":286,"line":618},5,[284,620,621],{"class":603},"    marts",[284,623,607],{"class":606},[284,625,627,630],{"class":286,"line":626},6,[284,628,629],{"class":603},"      educ_serv",[284,631,607],{"class":606},[284,633,635,638],{"class":286,"line":634},7,[284,636,637],{"class":603},"        staging",[284,639,607],{"class":606},[284,641,643,646],{"class":286,"line":642},8,[284,644,645],{"class":603},"          populations",[284,647,607],{"class":606},[284,649,651,654],{"class":286,"line":650},9,[284,652,653],{"class":603},"            custom_fgj_populations",[284,655,607],{"class":606},[284,657,659,662,664],{"class":286,"line":658},10,[284,660,661],{"class":603},"              +enabled",[284,663,577],{"class":606},[284,665,667],{"class":666},"sfNiH"," false\n",[264,669,670],{},[397,671,672,673,676],{},"Developers: when creating a new dashboard using the population mechanism, you must register its tag in the ",[268,674,675],{},"marts\u002Feduc_serv\u002Fadapters.yml"," file so it triggers the population computation.",[252,678,98],{"id":679},"human-resources",[261,681,682],{},[264,683,684],{},"This mart gathers all the data related to the human resources department.",[494,686,688],{"id":687},"populating-the-marts-seed","Populating the marts seed",[261,690,691],{},[264,692,693,694,697],{},"This dashboard requires the specification of the seeds in the ",[268,695,696],{},"human_resources"," mart.",[264,699,700,701,704,705,697],{},"The seed must be populated in ",[268,702,703],{},"cssXX.dashboards_store\u002Fseeds\u002Fmarts\u002Fhuman_resources\u002F"," and as per the definition of the ",[268,706,707],{},"core.dashboards_store\u002Fseeds\u002Fmarts\u002Fhuman_resources\u002Fschema.yml",[264,709,710,711,713],{},"Please refer to the ",[268,712,707],{}," mart documentation to get the concrete implementation.",[264,715,716,717,720],{},"Do not forget to refresh your seeds with the ",[268,718,719],{},"dbt seed --select tag:human_resources --full-refresh"," command.",[252,722,724],{"id":723},"exposing-the-freshness-of-the-data-into-the-dashboard","Exposing the freshness of the data into the dashboard",[261,726,727],{},[264,728,405,729,732,733,736],{},[268,730,731],{},"core"," provides a mechanism to expose the freshness of the data in the dashboard. This mechanism is called ",[268,734,735],{},"the stamper"," and can be enabled and used through macros.",[257,738,740,741],{"id":739},"enabling-the-stamper","Enabling the ",[268,742,743],{},"stamper",[261,745,746],{},[264,747,748,749,510],{},"Must be done ONCE in your ",[268,750,751],{},"cssXX.dashboards_store\u002Fdbt_project.yml",[264,753,754,755,758],{},"The stamper is a table collecting metadata about your ETL runs. To enable data collection, you first enable it in your ",[268,756,757],{},"dbt_project.yml"," by adding the following two hooks:",[275,760,762],{"className":580,"code":761,"language":582,"meta":280,"style":280},"# cssXX.dashboards_store\u002Fdbt_project.yml\n# Hooks\non-run-start:\n  - \"{{ core_dashboards_store.init_metadata_table() }}\"\non-run-end:\n  - \"{{ core_dashboards_store.purge_metadata_table() }}\"\n",[268,763,764,768,773,780,794,801],{"__ignoreMap":280},[284,765,766],{"class":286,"line":287},[284,767,590],{"class":589},[284,769,770],{"class":286,"line":593},[284,771,772],{"class":589},"# Hooks\n",[284,774,775,778],{"class":286,"line":600},[284,776,777],{"class":603},"on-run-start",[284,779,607],{"class":606},[284,781,782,785,788,791],{"class":286,"line":610},[284,783,784],{"class":606},"  -",[284,786,787],{"class":606}," \"",[284,789,790],{"class":293},"{{ core_dashboards_store.init_metadata_table() }}",[284,792,793],{"class":606},"\"\n",[284,795,796,799],{"class":286,"line":618},[284,797,798],{"class":603},"on-run-end",[284,800,607],{"class":606},[284,802,803,805,807,810],{"class":286,"line":626},[284,804,784],{"class":606},[284,806,787],{"class":606},[284,808,809],{"class":293},"{{ core_dashboards_store.purge_metadata_table() }}",[284,811,793],{"class":606},[257,813,815,818],{"id":814},"stamping-my-new-dashboard",[268,816,817],{},"stamping"," my new dashboard",[261,820,821],{},[264,822,823],{},"A good practice is to only stamp the reporting tables.",[264,825,826],{},[397,827,828,829,832],{},"Only successful runs will be stamped. This means that taking the ",[268,830,831],{},"MIN(run_ended_at)"," will give you the last time your ETL run was successful. This is the worst-case freshness scenario.",[264,834,835],{},"To add a stamp to your dashboard, you can either:",[318,837,838],{},[321,839,840,841,844],{},"Add the following ",[268,842,843],{},"post_hook"," into your model :",[275,846,850],{"className":847,"code":848,"language":849,"meta":280,"style":280},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# model.sql\n{{ config(\n    post_hook='{{ core_dashboards_store.stamp_model(\"my_dashboard\") }}',\n) }}\n","sql",[268,851,852,857,862,867],{"__ignoreMap":280},[284,853,854],{"class":286,"line":287},[284,855,856],{},"# model.sql\n",[284,858,859],{"class":286,"line":593},[284,860,861],{},"{{ config(\n",[284,863,864],{"class":286,"line":600},[284,865,866],{},"    post_hook='{{ core_dashboards_store.stamp_model(\"my_dashboard\") }}',\n",[284,868,869],{"class":286,"line":610},[284,870,871],{},") }}\n",[318,873,874],{},[321,875,876,877],{},"Stamp multiple models at once by adding the hook directly into the ",[268,878,879],{},"core\u002Fdbt_project",[275,881,883],{"className":580,"code":882,"language":582,"meta":280,"style":280},"models:\n  core_dashboards_store:\n    dashboards:\n      my_dashboard:\n        +tags: [\"my_dashboard\"]\n        +schema: dashboard_my_dashboard\n        pbi_tables:\n          +post_hook: [\"{{ core_dashboards_store.stamp_model('my_dashboard') }}\"]\n",[268,884,885,891,897,904,911,932,942,949],{"__ignoreMap":280},[284,886,887,889],{"class":286,"line":287},[284,888,386],{"class":603},[284,890,607],{"class":606},[284,892,893,895],{"class":286,"line":593},[284,894,613],{"class":603},[284,896,607],{"class":606},[284,898,899,902],{"class":286,"line":600},[284,900,901],{"class":603},"    dashboards",[284,903,607],{"class":606},[284,905,906,909],{"class":286,"line":610},[284,907,908],{"class":603},"      my_dashboard",[284,910,607],{"class":606},[284,912,913,916,918,921,924,927,929],{"class":286,"line":618},[284,914,915],{"class":603},"        +tags",[284,917,577],{"class":606},[284,919,920],{"class":606}," [",[284,922,923],{"class":606},"\"",[284,925,926],{"class":293},"my_dashboard",[284,928,923],{"class":606},[284,930,931],{"class":606},"]\n",[284,933,934,937,939],{"class":286,"line":626},[284,935,936],{"class":603},"        +schema",[284,938,577],{"class":606},[284,940,941],{"class":293}," dashboard_my_dashboard\n",[284,943,944,947],{"class":286,"line":634},[284,945,946],{"class":603},"        pbi_tables",[284,948,607],{"class":606},[284,950,951,954,956,958,960,963,965],{"class":286,"line":642},[284,952,953],{"class":603},"          +post_hook",[284,955,577],{"class":606},[284,957,920],{"class":606},[284,959,923],{"class":606},[284,961,962],{"class":293},"{{ core_dashboards_store.stamp_model('my_dashboard') }}",[284,964,923],{"class":606},[284,966,931],{"class":606},[264,968,969],{},[397,970,971],{},"The second option is preferred if all of your report models are under a common folder.",[257,973,975,976,978],{"id":974},"using-the-stamper-in-your-dashboard","Using the ",[268,977,743],{}," in your dashboard",[264,980,981,982,985],{},"In Power BI, you can easily fetch the last run of your ETL by filtering on the argument provided to the ",[268,983,984],{},"stamp_model"," macro.",[257,987,989],{"id":988},"variable-conventions","Variable conventions",[318,991,992,995,1008],{},[321,993,994],{},"Don't use spaces in your variable names",[321,996,997,998,1002,1003],{},"Please, stick to a ",[999,1000,1001],"em",{},"snake_case"," naming convention\n",[318,1004,1005],{},[321,1006,1007],{},"Use the interface tables to set the right names for the variables.",[321,1009,1010],{},"Reserved keywords should be written in caps.",[257,1012,1014],{"id":1013},"dbt_projectyml-conventions","dbt_project.yml conventions",[261,1016,1017],{},[264,1018,405,1019,1021,1022,510],{},[268,1020,757],{}," has to be updated every time a new dashboard is added to ",[268,1023,470],{},[318,1025,1026],{},[321,1027,1028,1029,1031,1032,1035,1036,1039,1040,1042,1043,1046,1047,1049],{},"Each dashboard (i.e. each subfolder of the ",[268,1030,386],{}," folder) should be given a ",[999,1033,1034],{},"tag"," and a ",[999,1037,1038],{},"schema",". The following example shows the minimal lines to add to the ",[268,1041,757],{}," file to add ",[268,1044,1045],{},"dummy_dashboard"," to ",[268,1048,470],{},". The rationale behind this convention is to ease filtering information in either the database or the documentation.",[275,1051,1053],{"className":580,"code":1052,"language":582,"meta":280,"style":280},"models: # Already here, for reference only\n  core_dashboards_store: # Already here, for reference only\n    +enabled: False # Already here, for reference only\n    dummy:\n      +tags: [\"dummy\"]\n      +schema: \"dummy\"\n",[268,1054,1055,1064,1072,1084,1091,1109],{"__ignoreMap":280},[284,1056,1057,1059,1061],{"class":286,"line":287},[284,1058,386],{"class":603},[284,1060,577],{"class":606},[284,1062,1063],{"class":589}," # Already here, for reference only\n",[284,1065,1066,1068,1070],{"class":286,"line":593},[284,1067,613],{"class":603},[284,1069,577],{"class":606},[284,1071,1063],{"class":589},[284,1073,1074,1077,1079,1082],{"class":286,"line":600},[284,1075,1076],{"class":603},"    +enabled",[284,1078,577],{"class":606},[284,1080,1081],{"class":666}," False",[284,1083,1063],{"class":589},[284,1085,1086,1089],{"class":286,"line":610},[284,1087,1088],{"class":603},"    dummy",[284,1090,607],{"class":606},[284,1092,1093,1096,1098,1100,1102,1105,1107],{"class":286,"line":618},[284,1094,1095],{"class":603},"      +tags",[284,1097,577],{"class":606},[284,1099,920],{"class":606},[284,1101,923],{"class":606},[284,1103,1104],{"class":293},"dummy",[284,1106,923],{"class":606},[284,1108,931],{"class":606},[284,1110,1111,1114,1116,1118,1120],{"class":286,"line":626},[284,1112,1113],{"class":603},"      +schema",[284,1115,577],{"class":606},[284,1117,787],{"class":606},[284,1119,1104],{"class":293},[284,1121,793],{"class":606},[252,1123,1125],{"id":1124},"naming-conventions","Naming conventions",[318,1127,1128],{},[321,1129,1130,1131,1133],{},"Use ",[999,1132,1001],{}," to name your variables.",[257,1135,1137],{"id":1136},"table-conventions","Table conventions",[318,1139,1140,1145],{},[321,1141,1130,1142,1144],{},[999,1143,1001],{}," naming conventions.",[321,1146,1147,1148,1151],{},"Use a ",[397,1149,1150],{},"prefix"," to indicate the high-level objective of the table. The following table prefixing conventions should be used.",[1153,1154,1155,1174],"table",{},[1156,1157,1158],"thead",{},[1159,1160,1161,1165,1168,1171],"tr",{},[1162,1163,1164],"th",{},"Table type",[1162,1166,1167],{},"Description",[1162,1169,1170],{},"Prefix",[1162,1172,1173],{},"Example",[1175,1176,1177,1192,1206,1220,1233,1254,1268],"tbody",{},[1159,1178,1179,1183,1186,1189],{},[1180,1181,1182],"td",{},"fact",[1180,1184,1185],{},"Contains tables of facts",[1180,1187,1188],{},"fact_",[1180,1190,1191],{},"fact_eleve",[1159,1193,1194,1197,1200,1203],{},[1180,1195,1196],{},"dimension",[1180,1198,1199],{},"A map between an arbitrary ID and a friendly name",[1180,1201,1202],{},"dim_",[1180,1204,1205],{},"dim_subject_category",[1159,1207,1208,1211,1214,1217],{},[1180,1209,1210],{},"bridge",[1180,1212,1213],{},"A mapping of primary-ish keys between systems",[1180,1215,1216],{},"bridge_",[1180,1218,1219],{},"NA",[1159,1221,1222,1225,1228,1231],{},[1180,1223,1224],{},"base",[1180,1226,1227],{},"A base table is a skeleton table used to build fact tables",[1180,1229,1230],{},"base_",[1180,1232,1219],{},[1159,1234,1235,1238,1248,1251],{},[1180,1236,1237],{},"staging",[1180,1239,1240,1241,1244,1245,1247],{},"A staging table is a by-product of the construction of a fact table. ",[1242,1243],"br",{},"The table kind of acts as a fact table, but is not queried by itself.",[1242,1246],{},"Staging tables are generally combined together or joined on a base table to create a fact table",[1180,1249,1250],{},"stg_",[1180,1252,1253],{},"stg_droppers_raw",[1159,1255,1256,1259,1262,1265],{},[1180,1257,1258],{},"interface",[1180,1260,1261],{},"The all mighty. Interfaces are tables mapping to the raw data from the operational system. It's basically a select clause followed by a list of the fields used in the downstream tasks. Those tables can be overridden in the inherited package to map the CSS requirements. Please, only add the columns you need.",[1180,1263,1264],{},"target_",[1180,1266,1267],{},"target_perseverance",[1159,1269,1270,1272,1275,1278],{},[1180,1271,393],{},[1180,1273,1274],{},"Reporting table. Used as an eye-catcher to easily detect the tables we need to plug the dashboard on.",[1180,1276,1277],{},"rprt_",[1180,1279,1280],{},"rprt_emp65_ann_bdgt",[1282,1283,1285],"h1",{"id":1284},"how-to","How to",[247,1287,1289],{"id":1288},"between-projects-conflicting-tables-names","Between projects conflicting tables names",[261,1291,1292],{},[264,1293,1294],{},"Some table names are quite generic (spine, dim_school) and can be used in various contexts without referring to the same underlying table. To avoid confusion, please use the following pattern to disambiguate the tables.",[494,1296,1173],{"id":1297},"example",[264,1299,1300,1301,1304,1305,510],{},"Let's consider the following two dashboards: ",[268,1302,1303],{},"employees_absences"," and ",[268,1306,1104],{},[275,1308,1311],{"className":1309,"code":1310,"language":414},[412],".\n└── core.store\u002F\n    ├── reporting\u002F\n    │   └── employees_absences.pbit\n    └── models\u002F\n        ├── employees_absences\u002F\n        │   └── fact_absences.sql\n        └── dummy\u002F\n            └── fact_absences.sql\n",[268,1312,1310],{"__ignoreMap":280},[275,1314,1316],{"className":580,"code":1315,"language":582,"meta":280,"style":280},"models:\n  +employees_absences:\n    +schema: \"employees_absences\"\n    +tags: [\"employees_absences\"]\n  +dummy:\n    +schema: \"dummy\"\n    +tags: [\"dummy\"]\n",[268,1317,1318,1324,1331,1344,1361,1368,1380],{"__ignoreMap":280},[284,1319,1320,1322],{"class":286,"line":287},[284,1321,386],{"class":603},[284,1323,607],{"class":606},[284,1325,1326,1329],{"class":286,"line":593},[284,1327,1328],{"class":603},"  +employees_absences",[284,1330,607],{"class":606},[284,1332,1333,1336,1338,1340,1342],{"class":286,"line":600},[284,1334,1335],{"class":603},"    +schema",[284,1337,577],{"class":606},[284,1339,787],{"class":606},[284,1341,1303],{"class":293},[284,1343,793],{"class":606},[284,1345,1346,1349,1351,1353,1355,1357,1359],{"class":286,"line":610},[284,1347,1348],{"class":603},"    +tags",[284,1350,577],{"class":606},[284,1352,920],{"class":606},[284,1354,923],{"class":606},[284,1356,1303],{"class":293},[284,1358,923],{"class":606},[284,1360,931],{"class":606},[284,1362,1363,1366],{"class":286,"line":618},[284,1364,1365],{"class":603},"  +dummy",[284,1367,607],{"class":606},[284,1369,1370,1372,1374,1376,1378],{"class":286,"line":626},[284,1371,1335],{"class":603},[284,1373,577],{"class":606},[284,1375,787],{"class":606},[284,1377,1104],{"class":293},[284,1379,793],{"class":606},[284,1381,1382,1384,1386,1388,1390,1392,1394],{"class":286,"line":634},[284,1383,1348],{"class":603},[284,1385,577],{"class":606},[284,1387,920],{"class":606},[284,1389,923],{"class":606},[284,1391,1104],{"class":293},[284,1393,923],{"class":606},[284,1395,931],{"class":606},[264,1397,1398,1399,1402],{},"The two dashboards are using a table named ",[268,1400,1401],{},"fact_absences"," but the SQL code is not the same, so I do need those two tables. Unfortunately, dbt will raise an error as each name has to be unique.",[264,1404,1405,1406,1408,1409,1046,1412,1415,1416,510],{},"An easy fix is to rename one of the ",[268,1407,1401],{}," tables. Let's say we rename ",[268,1410,1411],{},"models\u002Fdummy\u002Ffact_absences",[268,1413,1414],{},"dummy_fact_absences",". dbt will now be able to compile the code and any downstream task of the dummy project could refer to the table using ",[268,1417,1418],{},"{{ ref('dummy_fact_absence') }}",[264,1420,1421,1422,1424,1425,1427,1428,1431,1432,1435,1436,1438,1439,510],{},"The issue with this fix is that dbt will output a ",[268,1423,1414],{}," table in the ",[268,1426,1104],{}," schema. This is redundant, as the conflict happens ",[999,1429,1430],{},"between"," schemas, and not ",[999,1433,1434],{},"within"," the ",[268,1437,1104],{}," schema. Fortunately, we can override the output name in the SQL code by adding the following line into ",[268,1440,1441],{},"dummy_fact_absences.sql",[275,1443,1445],{"className":847,"code":1444,"language":849,"meta":280,"style":280},"{{ config(alias='fact_absences') }}\n",[268,1446,1447],{"__ignoreMap":280},[284,1448,1449],{"class":286,"line":287},[284,1450,1444],{},[257,1452,1454],{"id":1453},"dbt-error-message","dbt error message",[264,1456,1457],{},"In such case, dbt would output an error message similar to the following one.",[275,1459,1462],{"className":1460,"code":1461,"language":414},[412],"Compilation Error\n  dbt found two models with the name \"\u003Cfoobar>\".\n\n  Since these resources have the same name, dbt will be unable to find the correct resource\n  when looking for ref(\"foobar\").\n\n  To fix this, change the name of one of these resources:\n  - model.core_dashboards_store.removeme (models\u002Fprospectif_cdp\u002Ffeatures\u002Ffoobar.sql)\n  - model.core_dashboards_store.removeme (models\u002Femp_conge\u002Ffeature\u002Ffoobar.sql)\n",[268,1463,1461],{"__ignoreMap":280},[494,1465,1467],{"id":1466},"pattern","Pattern",[261,1469,1470],{},[264,1471,1472],{},"The generic pattern to solve the between-project-conflicting-tables-names issue is the following:",[553,1474,1475,1489],{},[321,1476,1477,1478],{},"Prefix your table with the (unique) friendly name of your dashboard.\n",[318,1479,1480],{},[321,1481,1482,1483,1485,1486],{},"The friendly name should be short. Maybe 3-to-10 letters. ",[268,1484,1104],{}," could become ",[268,1487,1488],{},"dmy",[321,1490,1491],{},"Add a dbt directive into your table code to output the table under its original name by setting the alias property",[343,1493,1494],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":280,"searchDepth":593,"depth":593,"links":1496},[1497,1506],{"id":249,"depth":593,"text":250,"children":1498},[1499,1500,1501,1502,1503,1504,1505],{"id":254,"depth":600,"text":255},{"id":377,"depth":600,"text":378},{"id":454,"depth":600,"text":455},{"id":446,"depth":600,"text":482},{"id":679,"depth":600,"text":98},{"id":723,"depth":600,"text":724},{"id":1124,"depth":600,"text":1125},{"id":1288,"depth":593,"text":1289},"md",null,{},{"description":280},"oLYxvSIvsGISy_aAXiTkrGCr00SWZulPTcJx_I9zkhc",[1513,1515],{"title":213,"path":208,"stem":214,"description":1514,"children":-1},"TODO",{"title":229,"path":230,"stem":231,"description":1516,"children":-1},"Discover every component you can use in your content.",1781106583320]