Package: dbt-metabase
dbt-metabaseIntegration betweendbtandMetabase.If dbt is your source of truth for database schemas and you use Metabase as your analytics tool, dbt-metabase can propagate table relationships, model and column descriptions and semantic types (e.g. currency, category, URL) to your Metabase data model, and extract questions and dashboards as exposures in your dbt project.RequirementsRequires Python 3.8 or above.UsageYou can install dbt-metabase fromPyPI:pip install dbt-metabaseSections below demonstrate basic usage examples, for all CLI options:dbt-metabase --helpManifestBefore running dbt-metabase, you need a compiledmanifest.jsonfile to parse. These are part of thedbt artifactgenerated during compilation.Oncedbt compilefinishes,manifest.jsoncan be found in thetarget/directory of your dbt project.Seedbt documentationfor more information.Exporting ModelsLet's start by defining a short sampleschema.ymlas below.models:-name:stg_usersdescription:User records.columns:-name:iddescription:Primary key.tests:-not_null-unique-name:emaildescription:User's email address.-name:group_iddescription:Foreign key to user group.tests:-not_null-relationships:to:ref('groups')field:id-name:stg_groupsdescription:User groups.columns:-name:iddescription:Primary key.tests:-not_null-unique-name:namedescription:Group name.This is already enough to propagate the primary keys, foreign keys and descriptions to Metabase:dbt-metabase models \
    --manifest-path target/manifest.json \
    --metabase-url https://metabase.example.com \
    --metabase-username user@example.com \
    --metabase-password Password123 \
    --metabase-database business \
    --include-schemas publicOpen Metabase and go to Settings > Admin Settings > Table Metadata, you will notice thatidcolumn instg_usersis now marked as "Entity Key" andgroup_idis a "Foreign Key" pointing toidinstg_groups.Try runningdbt-metabase models --helpto see all the options available for fine tuning.Foreign KeysNativerelationship testsandcolumn-level constraintsare the recommended ways of defining foreign keys, however you can override them withfk_target_tableandfk_target_fieldmeta fields. If both are set for a column, meta fields take precedence.-name:country_iddescription:FK to User's country in the dim_countries table.meta:metabase.fk_target_table:analytics_dims.dim_countriesmetabase.fk_target_field:idYou can providefk_target_tableasschema_name.table_nameor justtable_nameto use the current schema. If your model has an alias, provide that alias rather than the original name.Semantic TypesNow that we have foreign keys configured, let's tell Metabase thatemailcolumn contains email addresses:-name:emaildescription:User's email address.meta:metabase.semantic_type:type/EmailOnce you rundbt-metabase modelsagain, you will notice thatemailcolumn is now marked as "Email".Below are common semantic types (formerly known asspecial types) accepted by Metabase:type/PKtype/FKtype/Numbertype/Currencytype/Categorytype/Titletype/Descriptiontype/Citytype/Statetype/ZipCodetype/Countrytype/Latitudetype/Longitudetype/Emailtype/URLtype/ImageURLtype/SerializedJSONtype/CreationTimestampSeeMetabase documentationfor a more complete list.Visibility TypesYou can optionally specify visibility for tables and columns, this controls whether they are displayed in Metabase.Here is how you would hide that email column:-name:emaildescription:User's email address.meta:metabase.semantic_type:type/Emailmetabase.visibility_type:sensitiveBelow are the visibility types supported for columns:normal(default) - This field will be displayed normally in tables and charts.details-only- This field will only be displayed when viewing the details of a single record.sensitive- This field won't be visible or selectable in questions created with the GUI interfaces.Tables support the following:No value for visible (default)hiddentechnicalcruftIf you notice any changes to these, please submit a pull request with an update.Other Meta FieldsIn addition to foreign keys, semantic types and visibility types, Metabase also accepts the following meta fields:-name:model_namemeta:metabase.display_name:another_model_namemetabase.visibility_type:normalmetabase.points_of_interest:Relevant records.metabase.caveats:Sensitive information about users.columns:-name:column_namemeta:metabase.display_name:another_column_namemetabase.visibility_type:sensitivemetabase.semantic_type:type/Numbermetabase.has_field_values:listmetabase.coercion_strategy:keywordmetabase.number_style:decimalSeeMetabase documentationfor details and accepted values.SynchronizationBy default, dbt-metabase waits for tables and columns to be synchronized between your dbt project and Metabase database, otherwise the export fails when the sync timeout expires.If you have known discrepancies between dbt and Metabase and wish to proceed without synchronization, set the sync timeout to zero (e.g.--sync-timeout 0). This is discouraged, because you will still encounter errors if you have a table or column in your dbt project that is missing from Metabase and dbt-metabase attempts to export it.Exposure Extractiondbt-metabase allows you to extract questions and dashboards from Metabase asdbt exposuresin your project:dbt-metabase exposures \
    --manifest-path ./target/manifest.json \
    --metabase-url https://metabase.example.com \
    --metabase-username user@example.com \
    --metabase-password Password123 \
    --output-path models/ \
    --exclude-collections "temp*"Once the execution completes, check your output path for exposures files containing descriptions, creator details and links for Metabase questions and dashboards:exposures:-name:number_of_orders_over_timedescription:'###Visualization:LineAlinechartdepictinghowordervolumechangesovertime####MetadataMetabaseId:__8__CreatedOn:__2021-07-21T08:01:38.016244Z__'type:analysisurl:https://metabase.example.com/card/8maturity:mediumowner:name:Indiana Jonesemail:indiana@example.comdepends_on:-ref('orders')Native query questions will have SQL code blocks inside the descriptions, formatted to look nice indbt docs. These YAML files can be committed to source control to understand how exposures change over time.Try runningdbt-metabase exposures --helpto see all the options available for fine tuning.ConfigurationThere are 3 levels of configuration in decreasing order of precedence:CLI arguments, e.g.--manifest-path target/manifest.jsonEnvironment variables, e.g.MANIFEST_PATH=target/manifest.jsonConfiguration file, e.g.manifest_path: target/manifest.jsonTry running--helpfor any command to see the full list of CLI arguments and environment variables.A configuration file can be created in~/.dbt-metabase/config.ymlfor dbt-metabase to pick it up automatically or anywhere else by specifyingdbt-metabase --config-path path/to/config.yml(must comebeforethe command). Here is an example YAML file:config:manifest_path:target/manifest.jsonmetabase_url:https://metabase.example.commetabase_username:user@example.commetabase_password:Password123# Configuration specific to models commandmodels:metabase_database:business# Configuration specific to exposures commandexposures:output_path:modelsNote that common configurations are in the outer block and command-specific ones are in separate blocks.Programmatic APIAlternatively, you can invoke dbt-metabase programmatically. Below is the equivalent of CLI examples:fromdbtmetabaseimportDbtMetabase,Filter# Initializing instancec=DbtMetabase(manifest_path="target/manifest.json",metabase_url="https://metabase.example.com",metabase_username="user@example.com",metabase_password="Password123",)# Exporting modelsc.export_models(metabase_database="business",schema_filter=Filter(include=["public"]),)# Extracting exposuresc.extract_exposures(output_path=".",collection_filter=Filter(exclude=["temp*"]),)See function header comments for information about other parameters.