dbt-metabase

repository·main·Indexed 20 days ago

https://github.com/gouline/dbt-metabase

An integration tool that synchronizes dbt metadata—including schemas, descriptions, relationships, and semantic types—with Metabase. It also allows users to extract Metabase questions and dashboards as dbt exposures to track dependencies. The tool provides a CLI, a Python API, and supports configuration via environment variables or a config.yml file.

Tokens
3.8K
Snippets
13
Records
18
Agent score
69%

What's inside dbt-metabase

  1. Authenticate with the Metabase API

    main

    All dbt-metabase commands require authentication against the Metabase API. You can authenticate using one of two methods:

    1. API Key (Recommended for automation): Use the --metabase-api-key flag. This requires Metabase 49 or later.
    2. Username and Password: Use --metabase-username and --metabase-password as a fallback for older versions or smaller instances.
  2. Extract Metabase questions and dashboards as dbt exposures

    main

    Convert Metabase questions and dashboards into dbt exposures YAML files. This allows you to track Metabase assets within your dbt project and see how they depend on your models.

    Usage: Run the exposures command. You can specify an --output-path for the generated files and use --exclude-collections to filter out specific Metabase collections.

    dbt-metabase exposures \
        --manifest-path ./target/manifest.json \
        --metabase-url https://metabase.example.com \
        --metabase-api-key mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX= \
        --output-path models/ \
        --exclude-collections "temp*"

    Output Format: The generated YAML includes descriptions (with SQL code blocks for native queries), Metabase IDs, creation timestamps, owners, and depends_on references to your dbt models.

  3. Set up the Sandbox for end-to-end testing

    main

    The Sandbox environment provides a Docker Compose setup for performing end-to-end testing of the dbt-metabase integration. It orchestrates three main components:

    1. dbt: The transformation layer.
    2. Metabase: The BI tool.
    3. PostgreSQL: The target database.

    This setup is intended to allow developers to verify how dbt-metabase interacts with a live stack.

    # Use Docker Compose to start the sandbox environment
    docker-compose up
  4. Export dbt models to Metabase

    main

    Propagate table relationships, descriptions, and semantic types from your dbt project to Metabase.

    Prerequisites: You must have a compiled manifest.json file (generated by dbt compile) located in your dbt project's target/ directory.

    Basic Usage: Run the models command providing the manifest path, Metabase URL, API key, the target Metabase database name, and optionally a schema filter.

    dbt-metabase models \
        --manifest-path target/manifest.json \
        --metabase-url https://metabase.example.com \
        --metabase-api-key mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX= \
        --metabase-database business \
        --include-schemas public
  5. Configure Foreign Keys in dbt models

    main

    While dbt-metabase can automatically detect foreign keys from dbt relationship tests or column-level constraints, you can explicitly override them using meta fields in your schema.yml. This is useful if you need to specify a target that differs from the default detection.

    Use metabase.fk_target_table and metabase.fk_target_field within the config.meta block.

    • fk_target_table can be schema_name.table_name or just table_name (to use the current schema).
    • If the model has an alias, use the alias name.
    - name: country_id
      description: FK to User's country in the dim_countries table.
      config:
        meta:
          metabase.fk_target_table: analytics_dims.dim_countries
          metabase.fk_target_field: id
  6. Configure dbt-metabase via CLI, Env Vars, or Config File

    main

    Configuration follows a hierarchy of precedence (highest to lowest):

    1. CLI arguments (e.g., --manifest-path target/manifest.json)
    2. Environment variables (e.g., MANIFEST_PATH=target/manifest.json)
    3. Configuration file

    Configuration File Setup: You can place a config.yml in ~/.dbt-metabase/config.yml for automatic loading, or specify a custom path using --config-path path/to/config.yml (this flag must appear before the command).

    Common configurations go in the top-level config: block. Command-specific settings (for models or exposures) should be placed in their own named blocks.

    config:
        manifest_path: target/manifest.json
        metabase_url: https://metabase.example.com
        metabase_api_key: mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
        # Configuration specific to models command
        models:
          metabase_database: business
        # Configuration specific to exposures command
        exposures:
          output_path: models
  7. Configure the dbt-metabase sandbox with Docker Compose

    main

    The sandbox/docker-compose.yml file provides a complete environment for testing dbt-metabase. It orchestrates three services: a PostgreSQL database, a Metabase instance, and the app (the dbt-metabase project itself).

    To run the sandbox, you must provide several environment variables to configure the database credentials, Metabase setup, and application connectivity. The services are linked via a common network and use healthchecks to ensure dependencies (like the database) are ready before dependent services (like Metabase or the app) start.

    # Example of the required environment variables for the sandbox
    POSTGRES_USER=myuser
    POSTGRES_PASSWORD=mypassword
    POSTGRES_DB=mydb
    POSTGRES_PORT=5432
    MB_SETUP_TOKEN=mytoken
    MB_PORT=3000
    MB_USER=admin
    MB_PASSWORD=adminpassword
    POSTGRES_SCHEMA=public
  8. Use the dbtmetabase Python API

    main

    You can use dbtmetabase programmatically in Python instead of the CLI.

    from dbtmetabase import DbtMetabase, Filter
    
    # Initializing instance
    c = DbtMetabase(
        manifest_path="target/manifest.json",
        metabase_url="https://metabase.example.com",
        metabase_api_key="mb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=",
    )
    
    # Exporting models
    c.export_models(
        metabase_database="business",
        schema_filter=Filter(include=["public"]),
    )
    
    # Extracting exposures
    c.extract_exposures(
        output_path=".",
        collection_filter=Filter(exclude=["temp*"]),
    )
  9. Configure dbt-metabase via config.yml

    main

    You can provide default values for all commands using a configuration file. By default, the CLI looks for a file at ~/.dbt-metabase/config.yml.

    The YAML file should have a top-level config key. You can define global settings under config or command-specific settings by nesting them under the command name.

    Example structure:

    config:
      # Global settings applied to all commands
      metabase_url: 'https://metabase.example.com'
      metabase_api_key: 'YOUR_API_KEY'
      
      # Command-specific settings
      models:
        metabase_database: 'Analytics'
        sync_timeout: 30
  10. Configure Semantic Types for Metabase

    main

    Assign semantic types (formerly special types) to columns in your schema.yml to help Metabase understand the data format (e.g., marking a column as an Email or Currency). Use the metabase.semantic_type key within config.meta.

    Supported Semantic Types:

    • type/PK (Primary Key)
    • type/FK (Foreign Key)
    • type/Number
    • type/Currency
    • type/Category
    • type/Title
    • type/Description
    • type/City
    • type/State
    • type/ZipCode
    • type/Country
    • type/Latitude
    • type/Longitude
    • type/Email
    • type/URL
    • type/ImageURL
    • type/SerializedJSON
    • type/CreationTimestamp
    - name: email
      description: User's email address.
      config:
        meta:
          metabase.semantic_type: type/Email