diff --git a/.github/workflows/process_docs_changes.yml b/.github/workflows/process_docs_changes.yml index 56cc8b14a..893e1f41c 100644 --- a/.github/workflows/process_docs_changes.yml +++ b/.github/workflows/process_docs_changes.yml @@ -13,14 +13,33 @@ on: jobs: build-and-commit: runs-on: ubuntu-latest + env: + MAIN_REPO_BRANCH: "${{ github.event.inputs.branch_name }}" steps: - uses: actions/checkout@v4 - - name: Display received payload + - name: Set current branch name + run: echo "LOCAL_REPO_BRANCH=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_ENV + + - name: echo branch name + run: | + echo "Got (metabase) branch_name: $MAIN_REPO_BRANCH" + + - name: echo local repo branch run: | - echo "Got branch_name: ${{ github.event.inputs.branch_name }}" + echo "Running on (docs.metabase.github.io) branch: $LOCAL_REPO_BRANCH" - - name: Install dependencies + - name: Setup Babashka + uses: turtlequeue/setup-babashka@v1.7.0 + with: + babashka-version: 1.12.199 + + # - name: Filter non-documented branches + # description: This will stop the workflow if the branch isn't master or release-x.\d.x. + # run: | + # bb script/check_incoming_branchname.clj $MAIN_REPO_BRANCH + + - name: Install js dependencies run: yarn install --frozen-lockfile --prefer-offline - name: Set up Ruby # uses version from .ruby-version @@ -28,30 +47,31 @@ jobs: with: bundler-cache: true - - name: Install dependencies - run: bundle install - - - name: Update docs + - name: Install ruby dependencies run: | - ./script/docs-update - ./script/docs master --set-version master + bundle install - - name: "Lint the markdown" + - name: Update docs run: | - yarn lint-markdown + # ./script/docs-update + # ./script/docs master --set-version master + ./script/docs "$MAIN_REPO_BRANCH" --set-version "$MAIN_REPO_BRANCH" - - name: "Lint the styles" - run: | - yarn lint-styles + # - name: "Lint the markdown" + # run: | + # yarn lint-markdown - - name: "Lint the scripts" - run: | - yarn lint-scripts + # - name: "Lint the styles" + # run: | + # yarn lint-styles - - name: "Validate the links" - run: | - yarn lint-links + # - name: "Lint the scripts" + # run: | + # yarn lint-scripts + # - name: "Validate the links" + # run: | + # yarn lint-links - name: Build the Jekyll Site env: @@ -60,55 +80,24 @@ jobs: run: | # Clear the existing site: rm -rf _site - # Run the jekyll server: + # Build the jekyll site: JEKYLL_ENV=development bundle exec jekyll build --baseurl '' --config _config.docs.yml --trace - - name: Setup Babashka - uses: turtlequeue/setup-babashka@v1.7.0 - with: - babashka-version: 1.12.197 - - name: Check bb runs - run: bb --version + # - name: "Check all of the links" + # run: | + # script/links || true + # echo 'checking reported links...' + # echo "htmlproofer spit out a report of length: $(cat htmlproofer.out | wc -l)" + # bb script/analyze_links.clj --htmlproofer-output htmlproofer.out - - name: "Check all of the links" + - name: Authenticate Git with GITHUB_TOKEN run: | - script/links || true - echo 'checking reported links...' - echo "htmlproofer spit out a report of length: $(cat htmlproofer.out | wc -l)" - bb script/analyze_links.clj --htmlproofer-output htmlproofer.out + git config --global user.name "Metabase Docs bot" + git config --global user.email "metabase-bot@metabase.com" + git remote set-url origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/metabase/docs.metabase.github.io.git" - name: Create the pull request env: GH_TOKEN: ${{ secrets.METABASE_AUTOMATION_USER_TOKEN }} run: | - if git diff --quiet ; then - echo "No changes to commit." - else - git config user.email "metabase-bot@metabase.com" - git config user.name "Metabase Docs bot" - update_branch="docs-update" - - # Check out or create the update branch - if git ls-remote --exit-code --heads origin "$update_branch" > /dev/null; then - git fetch origin "$update_branch" - git switch "$update_branch" - else - git switch --create "$update_branch" - fi - - git add _site - git commit --author="Metabase Docs bot " --message="Update master and latest docs" - git push --force origin "$update_branch" - - # Check if a PR already exists for this branch - existing_pr=$(gh pr list --head "$update_branch" --json number --jq '.[0].number') - - if [ -z "$existing_pr" ]; then - gh pr create \ - --title "Refresh docs (${{ github.event.inputs.branch_name }})" \ - --body "" \ - --head "$update_branch" - else - echo "PR already exists: #$existing_pr" - fi - fi + bb script/update_or_create_pr.clj $MAIN_REPO_BRANCH diff --git a/_docs/doc-update-detection/CONTRIBUTING.md b/_docs/doc-update-detection/CONTRIBUTING.md new file mode 100644 index 000000000..90ff4c3b5 --- /dev/null +++ b/_docs/doc-update-detection/CONTRIBUTING.md @@ -0,0 +1,116 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: false +show_title_breadcrumb: true +category: 'Table of Contents' +title: 'Contributing to Metabase' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/CONTRIBUTING.md' +redirect_from: + - /docs/doc-update-detection/developers-guide/contributing +--- + +# Contributing to Metabase + +## Thank you + +First off, thanks for your interest in Metabase and for wanting to contribute! + +In this guide, we'll discuss how Metabase is built. This should give you a good sense of our process and where you might want to fit in. + +In general, we like to have an open issue for every pull request as a place to discuss the nature of any bug or proposed improvement. Each pull request should address a single issue, and contain both the fix as well as a description of the pull request and tests that validate that the PR fixes the issue in question. + +For bug fixes, please submit the pull request to target the `master` branch. From time to time, our team will backport selected critical bug fixes to the stable/release branch. + +For significant feature additions, it is expected that discussion will have taken place in the attached issue. Any feature that requires a major decision to be reached will need to have an explicit design document written. The goals of this document are to make explicit the assumptions, constraints and tradeoffs any given feature implementation will contain. The point is not to generate documentation but to allow discussion to reference a specific proposed design and to allow others to consider the implications of a given design. + +## Contributor License Agreement + +We don't like getting sued, so before merging any pull request, we'll need each person contributing code to sign a [Contributor License Agreement](https://docs.google.com/a/metabase.com/forms/d/1oV38o7b9ONFSwuzwmERRMi9SYrhYeOrkbmNaq9pOJ_E/viewform). + +## What we're trying to build + +Metabase is all about letting non-technical users get access to their organization's data. We're trying to maximize the amount of power that can be comfortably used by someone who understands their business, is quantitatively bent, but probably only comfortable with Excel. + +It's important to keep in mind these goals of the Metabase project. Many times +proposals will be marked "Out of Scope" or otherwise deprioritized. This doesn't mean the proposal isn't useful, or that we wouldn't be interested in seeing it done as a side project or as an experimental branch. However, it does mean that we won't point the core team or contributors to it in the near term. Issues that are slightly out of scope will be kept open in case there is community support (and ideally contributions). + +To get a sense for the end goals, make sure to read the [Zen of Metabase](https://github.com/metabase/metabase/blob/master/zen.md). + +## Our product process: + +The core team runs a pretty well defined product process. It is actively being tweaked, but the below is a pretty faithful description of it at the time of writing. You should have a clear idea of how we work before jumping in with a PR. + +### A) Identify product needs from the community + +We actively look for new feature ideas from our community, user base and our own use of Metabase internally. We concentrate on the underlying _problem_ or _need_ as opposed to requests for specific features. While sometimes suggested features are built as requested, often we find that they involve changes to existing features, and perhaps an entirely different solution to the underlying problem. These will typically be collected in a number of issues, and tagged [Proposal](https://github.com/metabase/metabase/labels/.Proposal) + +### B) Synthesize these needs into a concrete feature + +We typically will collect a group of issues or suggestions into a new topline feature concept. Typically we'll create a working document that collects all "Open Questions" regarding to what the feature is meant to do, and more importantly not do. We'll chat with our users, maybe do in depth interviews and generally try to tightly define the feature. If a feature seems like it will need time to be discussed and scoped, it will be tagged [Proposal/Being Discussed](https://github.com/metabase/metabase/labels/.Proposal%2FBeing%20Discussed) to signify that it is still actively under discussion. + +### C) Design the feature + +Once a feature has been defined, typically it will be taken on by a product designer. Here, they will produce low fi mocks, get feedback from our users and community, and iterate. + +Once the main UX flows have been dialed in, there will be a hi-fidelity visual design. + +Features that are ready for design are tagged [Design Needed](https://github.com/metabase/metabase/labels/.Design%20Needed). Once a feature has had a reasonably complete visual design it should be tagged [Help Wanted](https://github.com/metabase/metabase/labels/.Help%20Wanted). + +### D) Build the feature + +Once a feature is tagged [Help Wanted](https://github.com/metabase/metabase/labels/.Help%20Wanted), it is considered ready to be built. A core team member (or you, awesomely helpful person that you are) can start working on it. + +If you're building something that users will see in Metabase, please refer to the Style Guide (found at `https://storybook.metabase.com`) to learn how and when to use various Metabase UI elements. + +Once one or more people have started to work on a feature, it should be marked [In Progress](https://github.com/metabase/metabase/labels/.In%20Progress). Once there is a branch+some code, a pull request is opened, linked to the feature + any issues that were pulled together to inform the feature. + +### E) Verification and merging + +All PRs that involve more than an insignificant change should be reviewed. See our [Code Review Process](./developers-guide/code-reviews). + +If all goes well, the feature gets coded up, verified and then the pull request gets merged! High-fives all around. + +If there are tests missing, code style concerns or specific architectural issues in the pull request, they should be fixed before merging. We have a very high bar on both code and product quality and it's important that this be maintained going forward, so please be patient with us here. + +## Ways to help + +The starting point would be to get familiar with Metabase the product, and know your way around. If you're using it at work, that's great! If not, [download Metabase](/start/oss/) and play around with it. Read the docs and generally get a feel for the flow of the product. + +Here are some ways you can help, in order of increasing coordination + interaction with us: + +### Help with identifying needs and problems Metabase can solve + +If you want to help, try out Metabase. Use it at your company, and report back the things you like, dislike and any problems you run into. Help us understand your data model, required metrics and common usage patterns as much as you can. This information directly affects the quality of the product. The more you tell us about the kinds of problems you're facing, the better we'll be able to address them. + +### Help us triage and support other users + +Spend time on discourse.metabase.com and on new issues and try to reproduce the bugs reported. For people having trouble with their databases where you have significant knowledge, help them out. Who knows, maybe they'll end up helping you with something in the future. + +It is helpful if you understand our [prioritization framework](https://github.com/metabase/metabase/wiki/Bug-Prioritization) when responding. + +### Tell your friends + +Let your friends know about Metabase. Start a user group in your area. [Tweet about us](http://twitter.com/metabase). Blog about how you're using Metabase, and share what you've learned. + +### Fix bugs + +By our definition, "Bugs" are situations where the program doesn't do what it was expected to according to the design or specification. These are typically scoped to issues where there is a clearly defined correct behavior. It's usually safe to grab one of these, fix it, and submit a PR (with tests!). These will be merged without too much drama unless the PR touches a lot of code. Don't be offended if we ask you to make small modifications or add more tests. We're a bit OCD on code coverage and coding style. + +### Help with Documentation + +There are a lot of docs, which means keeping them up to date is hard. If you notice inconsistencies, errors, or outdated information, please help us keep them current! + +Note that **we cannot accept translations for documentation at this time**. We support [in-app translations](./configuring-metabase/localization), and only support languages that have 100% coverage. But 1) the in-app text is orders of magnitude shorter than our docs, 2) it changes at a slower pace, and 3) we have a lot of people help out. We may consider supporting docs in multiple languages in the future, but for now we need to focus our resources on improving our existing documentation (and expanding it to include all of the new features we're adding). + +### Working on features + +Some features, eg Database drivers, don't have any user facing pixels. These are a great place to start off contributing as they don't require as much communication, discussions about tradeoffs and process in general. + +In situations where a design has already been done, we can always use some help. Chime in on a pull request or an issue and offer to help. + +Generally speaking, any issue in [Help Wanted](https://github.com/metabase/metabase/labels/.Help%20Wanted) is fair game. + +### #YOLO JUST SUBMIT A PR + +If you come up with something really cool, and want to share it with us, just submit a PR. If it hasn't gone through the above process, we probably won't merge it as is, but if it's compelling, we're more than willing to help you via code review, design review and generally OCD nitpicking so that it fits into the rest of our codebase. diff --git a/_docs/doc-update-detection/README.md b/_docs/doc-update-detection/README.md new file mode 100644 index 000000000..3766119c0 --- /dev/null +++ b/_docs/doc-update-detection/README.md @@ -0,0 +1,346 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: false +show_title_breadcrumb: true +category: 'Table of Contents' +title: 'Metabase documentation' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/README.md' +permalink: /docs/doc-update-detection/index.html +redirect_from: + - /docs/doc-update-detection/enterprise-guide + - /docs/doc-update-detection/users-guide + - /docs/doc-update-detection/administration-guide + - /docs/doc-update-detection/operations-guide + - /docs/doc-update-detection/faq +--- + +# Metabase documentation + +![Metabase dashboard](./images/metabase-product-screenshot.png) + +Metabase is an open-source business intelligence platform. You can use Metabase to ask questions about your data, or embed Metabase in your app to let your customers explore their data on their own. + +## First steps + +### Metabase Cloud + +The easiest way to get started with Metabase is to sign up for a free trial of [Metabase Cloud](https://store.metabase.com/checkout). You get support, backups, upgrades, an SMTP server, SSL certificate, SoC2 Type 2 security auditing, and more (plus your money goes toward improving Metabase). Check out our quick overview of [cloud vs self-hosting](/docs/latest/cloud/cloud-vs-self-hosting). If you need to, you can always switch to [self-hosting](./installation-and-operation/installing-metabase) Metabase at any time (or vice versa). + +### [Installing Metabase](./installation-and-operation/installing-metabase) + +Run as a JAR, using Docker, or on [Metabase Cloud](https://store.metabase.com/checkout). + +### [Setting up Metabase](./configuring-metabase/setting-up-metabase) + +Once installed, set up your Metabase and connect to your data. + +### [Getting started](/learn/metabase-basics/getting-started/index) + +With your data connected, get started asking questions, creating dashboards, and sharing your work. + +### [A tour of Metabase](/learn/metabase-basics/overview/tour-of-metabase) + +Metabase is a deep product with a lot of tools to simplify business intelligence, from embeddable charts and interactive dashboards, to GUI and SQL editors, to auditing and data sandboxing, and more. + +## Documentation topics + +Metabase's reference documentation. + +### Installation + +- [Installation overview](./installation-and-operation/start) +- [Installing Metabase](./installation-and-operation/installing-metabase) +- [Upgrading Metabase](./installation-and-operation/upgrading-metabase) +- [Configuring the Metabase application database](./installation-and-operation/configuring-application-database) +- [Backing up Metabase](./installation-and-operation/backing-up-metabase-application-data) +- [Migrating to a production application database](./installation-and-operation/migrating-from-h2) +- [Monitoring your Metabase](./installation-and-operation/monitoring-metabase) +- [Serialization](./installation-and-operation/serialization) +- [Commands](./installation-and-operation/commands) +- [Supported browsers](./installation-and-operation/supported-browsers) +- [Privacy](./installation-and-operation/privacy) +- [About the anonymous usage data we collect](./installation-and-operation/information-collection) + +### Databases + +- [Databases overview](./databases/start) +- [Adding and managing databases](./databases/connecting) +- [Database users, roles, and privileges](./databases/users-roles-privileges) +- [Syncing and scanning databases](./databases/sync-scan) +- [Encrypting your database connection](./databases/encrypting-details-at-rest) +- [SSH tunneling](./databases/ssh-tunnel) +- [SSL certificate](./databases/ssl-certificates) +- [Uploading data](./databases/uploads) + +### Questions + +- [Questions overview](./questions/start) +- [Alerts](./questions/alerts) +- [Exporting data](./questions/exporting-results) + +#### Query builder + +- [The query editor](./questions/query-builder/editor) +- [Filtering](./questions/query-builder/filters) +- [Summarizing and grouping](./questions/query-builder/summarizing-and-grouping) +- [Custom expressions](./questions/query-builder/expressions) +- [List of expressions](./questions/query-builder/expressions-list) +- [Joining data](./questions/query-builder/join) + +#### SQL and native queries + +- [The SQL editor](./questions/native-editor/writing-sql) +- [SQL parameters](./questions/native-editor/sql-parameters) +- [Referencing models and saved questions](./questions/native-editor/referencing-saved-questions-in-queries) +- [Snippets](./questions/native-editor/snippets) +- [Snippet folder permissions](./permissions/snippets) + +#### Visualizing data + +- [Visualizing data](./questions/visualizations/visualizing-results) +- [Combo charts](./questions/visualizations/combo-chart) +- [Detail](./questions/visualizations/detail) +- [Funnel charts](./questions/visualizations/detail) +- [Gauge charts](./questions/visualizations/gauge) +- [Line, bar, and area charts](./questions/visualizations/line-bar-and-area-charts) +- [Maps](./questions/visualizations/map) +- [Numbers](./questions/visualizations/numbers) +- [Pie or donut charts](./questions/visualizations/pie-or-donut-chart) +- [Pivot table](./questions/visualizations/pivot-table) +- [Progress bar](./questions/visualizations/progress-bar) +- [Sankey chart](./questions/visualizations/sankey) +- [Scatterplot or bubble chart](./questions/visualizations/scatterplot-or-bubble-chart) +- [Table](./questions/visualizations/table) +- [Tooltips](./questions/visualizations/tooltips) +- [Trend](./questions/visualizations/trend) +- [Waterfall chart](./questions/visualizations/waterfall-chart) + +### Dashboards + +- [Dashboards overview](./dashboards/start) +- [Introduction to dashboards](./dashboards/introduction) +- [Dashboard filters](./dashboards/filters) +- [Interactive dashboards](./dashboards/interactive) +- [Charts with multiple series](./dashboards/multiple-series) +- [Dashboard subscriptions](./dashboards/subscriptions) +- [Actions on dashboards](./dashboards/actions) + +### Data modeling + +- [Data modeling overview](./data-modeling/start) +- [Models](./data-modeling/models) +- [Model persistence](./data-modeling/model-persistence) +- [Metrics](./data-modeling/metrics) +- [Table metadata admin settings](./data-modeling/metadata-editing) +- [Field types](./data-modeling/field-types) +- [Formatting defaults](./data-modeling/formatting) +- [Working with JSON](./data-modeling/json-unfolding) +- [Segments](./data-modeling/segments) + +### Actions + +- [Actions overview](./actions/start) +- [Introduction to actions](./actions/introduction) +- [Basic actions](./actions/basic) +- [Custom actions](./actions/custom) + +### Organization + +- [Organization overview](./exploration-and-organization/start) +- [Basic exploration](./exploration-and-organization/exploration) +- [Collections](./exploration-and-organization/collections) +- [History](./exploration-and-organization/history) +- [Trash](./exploration-and-organization/delete-and-restore) +- [Data reference](./exploration-and-organization/data-model-reference) +- [Events and timelines](./exploration-and-organization/events-and-timelines) +- [X-rays](./exploration-and-organization/x-rays) +- [Content verification](./exploration-and-organization/content-verification) + +### People + +- [People overview](./people-and-groups/start) +- [Account settings](./people-and-groups/account-settings) +- [Managing people and groups](./people-and-groups/managing) +- [Password complexity](./people-and-groups/changing-password-complexity) +- [Session expiration](./people-and-groups/changing-session-expiration) +- [Google Sign-In](./people-and-groups/google-sign-in) +- [LDAP](./people-and-groups/ldap) +- [API keys](./people-and-groups/api-keys) + +#### Paid SSO options + +- [JWT-based authentication](./people-and-groups/authenticating-with-jwt) +- [SAML-based authentication](./people-and-groups/authenticating-with-saml) + - [SAML with Auth0](./people-and-groups/saml-auth0) + - [SAML with Microsoft Entra ID](./people-and-groups/saml-azure) + - [SAML with Google](./people-and-groups/saml-google) + - [SAML with Keycloak](./people-and-groups/saml-keycloak) + - [SAML with Okta](./people-and-groups/saml-okta) +- [User provisioning with SCIM](./people-and-groups/user-provisioning) + +### Permissions + +- [Permissions overview](./permissions/start) +- [Permissions introduction](./permissions/introduction) +- [Data permissions](./permissions/data) +- [Collection permissions](./permissions/collections) +- [Application permissions](./permissions/application) +- [Data sandboxes](./permissions/data-sandboxes) +- [Data sandbox examples](./permissions/data-sandbox-examples) +- [Snippets folder permissions](./permissions/snippets) +- [Notification permissions](./permissions/notifications) + +### Embedding + +- [Embedding overview](./embedding/start) +- [Embedding introduction](./embedding/introduction) +- [Interactive embedding](./embedding/interactive-embedding) +- [Interactive embedding quick start](./embedding/interactive-embedding-quick-start-guide) +- [Static embedding](./embedding/static-embedding) +- [Parameters for static embeds](./embedding/static-embedding-parameters) + +### Configuration + +- [Configuration overview](./configuring-metabase/start) +- [Setting up Metabase](./configuring-metabase/setting-up-metabase) +- [General settings](./configuring-metabase/settings) +- [Email](./configuring-metabase/email) +- [Slack](./configuring-metabase/slack) +- [Webhooks](./configuring-metabase/webhooks) +- [Environment variables](./configuring-metabase/environment-variables) +- [Configuration file](./configuring-metabase/config-file) +- [Metabase log configuration](./configuring-metabase/log-configuration) +- [Timezones](./configuring-metabase/timezones) +- [Languages and localization](./configuring-metabase/localization) +- [Appearance](./configuring-metabase/appearance) +- [Caching query results](./configuring-metabase/caching) +- [Custom maps](./configuring-metabase/custom-maps) +- [Customizing the Metabase Jetty webserver](./configuring-metabase/customizing-jetty-webserver) + +### Tools + +- [Tools overview](./usage-and-performance-tools/start) +- [Usage analytics](./usage-and-performance-tools/usage-analytics) +- [Admin tools](./usage-and-performance-tools/tools) + +### Cloud + +- [Documentation for Metabase Cloud and Store](/docs/latest/cloud/start) + +### Metabase API + +- [Metabase API documentation](./api) +- [API tutorial](/learn/metabase-basics/administration/administration-and-operation/metabase-api) + +### Troubleshooting + +- [Troubleshooting guides](./troubleshooting-guide/index) + +### Developer guide + +- [Developer guide](./developers-guide/start) + +## Getting help + +### Troubleshooting + +- [Troubleshooting guides](troubleshooting-guide/index) +- [Metabase forum](https://discourse.metabase.com/) +- [Configuring logging](./configuring-metabase/log-configuration) + +### Tutorials and guides + +[Learn Metabase](/learn) has a ton of articles on how to use Metabase, data best practices, and more. + +## More resources + +### [Discussion](https://discourse.metabase.com) + +Share and connect with other Metabasers. + +### [Metabase Cloud](/cloud/docs) + +For docs specific to Metabase Cloud plans. + +### [Community stories](/community) + +Practical advice from our community. + +### [Metabase blog](/blog) + +News, updates, and ideas. + +### [Customers](/case_studies) + +Real companies, real data, real stories. + +### [Metabase Twitter](https://twitter.com/metabase) + +We tweet stuff. + +### [Source code repository on GitHub](https://github.com/metabase/metabase) + +Follow us on GitHub. + +### [List of releases](https://github.com/metabase/metabase/releases) + +A list of all Metabase releases, including both the Enterprise Edition and the Open Source Edition. + +### [Developers guide](./developers-guide/start) + +Contribute to the Metabase open source project! + +### [Data and Business Intelligence Glossary](/glossary) + +Data jargon explained. + +### [Metabase Experts](/partners/) + +If you’d like more technical resources to set up your data stack with Metabase, connect with a [Metabase Expert](/partners/). + + +hello from the new site +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi diff --git a/_docs/doc-update-detection/actions/basic.md b/_docs/doc-update-detection/actions/basic.md new file mode 100644 index 000000000..240ef758b --- /dev/null +++ b/_docs/doc-update-detection/actions/basic.md @@ -0,0 +1,79 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Actions +title: 'Basic actions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/actions/basic.md' +--- + +# Basic actions + +Basic actions are "implicit" [actions](./introduction) that do things that people typically want to do when interacting with a database: Create, Update, Delete. Basic actions auto-track the schema of the source table backing the model. By auto-track the schema, we mean that Metabase will create action forms for people to fill out that include all of the fields from the primary source table that underlies that model. + +If you only want to give people the option to update a subset of columns, or update columns in multiple tables, you can write a [custom action](./custom). + +## Creating basic actions + +Once actions are enabled, you can create basic actions on a new or existing [model](../data-modeling/models) that only wraps a single database table. + +1. Select a model and click on the **info** button, then click on **Model detail**. +2. On the model detail page, click on the **Actions** tab. +3. Click on the **...** next to the **New Action** and select **Create basic actions**. + +### Basic action limitations + +Basic actions are only available for "basic" models: + +- Models built using the graphical query builder. Basic actions are unavailable for models created with native queries (SQL). +- The model must "wrap" a single raw table in a database. The query should simply select that table in the data step of the notebook editor, and nothing more: no joins, no custom columns, no filters or summarization, no sorting. +- The underlying table can only have one primary (entity) key. + +## Basic action types + +![Basic actions](./images/basic-actions.png) + +Basic actions include: + +- [Update](#update) +- [Delete](#delete) +- [Create](#create) + +### Update + +The update action will present people with a form with editable fields for each column in the primary source table. + +When setting up an Update action on a dashboard, you must pass an entity key (like an ID) to the action from a dashboard filter. For other values, you can either prompt the person to fill in a value for each field, or have a field automatically filled in via parameters (such as values set in dashboard filters). + +### Delete + +The Delete action will create a form that prompts people for an entity key, and will delete the record (row) corresponding to that ID in the underlying table that backs the model. + +### Create + +The Create action is the `INSERT INTO` action. The Create action will present a form with editable fields for each column in the primary source table backing the model. Once filled out, the action will insert the record into the primary table that underlies the model. + +## Basic actions on dashboards + +When setting up actions on a dashboard, you can either prompt the person to fill in a value for each field, or have a field automatically filled in via parameters (such as values set in dashboard filters). + +The Update basic action requires you to pass a value for the entity key. + +See [Actions in dashboards](../dashboards/actions). + +## Archiving basic actions + +Because basic actions are made of magic, you cannot archive them. You can just toggle them on or off. From the model detail page, next to the **New action** button, click on the **...** menu and click **Disable basic actions**. + +## Basic actions from object detail view + +If you have basic actions enabled for a model, you can click on an individual record to view its object detail. From that object detail model, you can click on the ellipses (**...**) and select update or delete to modify that specific record. + +![Update record from object detail view](./images/update-record.png) + +## Further reading + +- [Introduction to actions](./introduction) +- [Custom actions](./custom) +- [Actions in dashboards](../dashboards/actions) diff --git a/_docs/doc-update-detection/actions/custom.md b/_docs/doc-update-detection/actions/custom.md new file mode 100644 index 000000000..9e98605de --- /dev/null +++ b/_docs/doc-update-detection/actions/custom.md @@ -0,0 +1,165 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Actions +title: 'Custom actions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/actions/custom.md' +--- + +# Custom actions + +Write SQL to update records in your databases. + +![Custom action](./images/custom-action.png) + +## Creating a custom action + +> You must be in a group with Native query editing access to create an action + +There are two ways to create a custom action: + +1. Click the **+ New** > **Action**. When you save your action, you'll be prompted to associate that action with a model. (NOTE: the **Action** option will only show up in the **+ New** menu if you've first created, or have access to, a [model](../data-modeling/models) in Metabase.) +2. Via the model detail page: from a model, click on the **info** button in the upper right. In the upper right of the sidebar, click **Model detail** > **Actions** > **New action**. + +In the action editor, you can write your own code to create an action, like writing an action that would only update a subset of the columns in a table. See [Example actions](#example-custom-actions). + +## Field types for action variables + +For each {% raw %}{{ variable }}{% endraw %} that you set in an action, you'll need to set the field type. + +Each of these variable field types present different options. Click on the gear icon to change options. + +If you don't require a variable, you can optionally specify a default value for Metabase to use in cases where people don't fill out the field. In the SQL code, remember to enclose any optional variables and commas in brackets, like `{% raw %}[[, column = {{ optional_variable }}]] {% endraw %}`. + +You can include placeholder text for all fields in the action form. + +**Text** + +- Text +- Long text +- Dropdown +- Inline select + +**Number** + +- Number +- Dropdown +- Inline select + +**Date** + +- Date +- Date + Time + +For both **Dropdown** and **Inline select**, you can specify a list of options to present on the form, with each option on its own line. + +![Dropdown select](./images/dropdown.png) + +## Appearance + +The appearance tab in the action editor modal will display a preview of the variable's form element. In the image below, we've clicked on the variable's **gear** and set the variable to use a text > dropdown list. The appearance section gives a preview for what the form element would look like: + +![Appearance gives a preview of the form element](./images/appearance.png) + +## Action settings + +From the model detail page, click on the **three dot menu** (...) next to the action. Once in the action editor, click on the **gear** icon to bring up the action settings. + +### Make public + +Creates a publicly shareable link to the action form. Anyone with access to that link can fill out the form and run the action. Useful for creating surveys. + +![Public action form](./images/public-form.png) + +### Set a success message + +Here you can edit the success message, which is the message Metabase will display in the toast that pops up after Metabase hears back from the database that everything went smoothly. + +If something goes wrong, Metabase will display the error message it received from the database. + +## Example custom actions + +### Example `UPDATE` action + +You could write an action that would update the `plan` column for a record in the `invoices` table in the Sample Database: + +```sql +{% raw %} +UPDATE invoices +SET plan = {{ plan }} + [[, payment = {{ payment }}]] +WHERE + id = {{ id }} +{% endraw %} +``` + +The above code will create a form that prompts people to input updated values for the (required) `plan` field and optionally the `payment` field for a given record specified by `ID`. + +The code in brackets `[[ ]]` makes the statement optional: the bracket-enclosed statement will only run if someone inserts a value in the payment field. Note the comma that separates the statements is _inside_ the brackets. + +![Example action form](./images/form.png) + +### Example `INSERT` action + +Insert statements are pretty straightforward: + +```sql +{% raw %} +INSERT INTO invoices ( + account_id + ,payment + ,expected_invoice + ,plan + ,date_received +) +VALUES ( + {{ account_id }} + ,{{ payment }} + ,CAST ({{expected_invoice}} AS boolean) + ,{{plan}} + ,({{date_received}} +); +{% endraw %} +``` + +### Casting field values in actions + +If you get a type error when you submit a form, you may need to `CAST` the data type in the query so it matches the data type of the target field in the database. Here we're casting a value to a `boolean`: + +```sql +{% raw %} +UPDATE invoices +SET expected_invoice = CAST({{expected_invoice}} AS boolean) +WHERE id = {{id}}; +{% endraw %} +``` + +### Referencing saved questions in actions + +You can also reference saved questions in actions. Here we're taking the results of a `SELECT` statement on a saved question ("Potential customers") and inserting the results into a `people_to_write` table. + +```sql +{% raw %} +WITH prospects AS {{#6-potential-customers}} + +INSERT INTO + people_to_write ( + first_name + ,last_name + ,email + ) +SELECT + first_name + ,last_name + ,email +FROM prospects; +{% endraw %} +``` + +## Further reading + +- [Introduction to actions](./introduction) +- [Basic actions](./basic) +- [Actions in dashboards](../dashboards/actions) diff --git a/_docs/doc-update-detection/actions/images/appearance.png b/_docs/doc-update-detection/actions/images/appearance.png new file mode 100644 index 000000000..3dcb976a2 Binary files /dev/null and b/_docs/doc-update-detection/actions/images/appearance.png differ diff --git a/_docs/doc-update-detection/actions/images/basic-actions.png b/_docs/doc-update-detection/actions/images/basic-actions.png new file mode 100644 index 000000000..5cd596444 Binary files /dev/null and b/_docs/doc-update-detection/actions/images/basic-actions.png differ diff --git a/_docs/doc-update-detection/actions/images/custom-action.png b/_docs/doc-update-detection/actions/images/custom-action.png new file mode 100644 index 000000000..94ba1f879 Binary files /dev/null and b/_docs/doc-update-detection/actions/images/custom-action.png differ diff --git a/_docs/doc-update-detection/actions/images/dashboard-action.gif b/_docs/doc-update-detection/actions/images/dashboard-action.gif new file mode 100644 index 000000000..dd962a5ed Binary files /dev/null and b/_docs/doc-update-detection/actions/images/dashboard-action.gif differ diff --git a/_docs/doc-update-detection/actions/images/dropdown.png b/_docs/doc-update-detection/actions/images/dropdown.png new file mode 100644 index 000000000..14094b665 Binary files /dev/null and b/_docs/doc-update-detection/actions/images/dropdown.png differ diff --git a/_docs/doc-update-detection/actions/images/example-action.png b/_docs/doc-update-detection/actions/images/example-action.png new file mode 100644 index 000000000..c713cb9cd Binary files /dev/null and b/_docs/doc-update-detection/actions/images/example-action.png differ diff --git a/_docs/doc-update-detection/actions/images/form.png b/_docs/doc-update-detection/actions/images/form.png new file mode 100644 index 000000000..b1dc59318 Binary files /dev/null and b/_docs/doc-update-detection/actions/images/form.png differ diff --git a/_docs/doc-update-detection/actions/images/public-form.png b/_docs/doc-update-detection/actions/images/public-form.png new file mode 100644 index 000000000..ebc378de8 Binary files /dev/null and b/_docs/doc-update-detection/actions/images/public-form.png differ diff --git a/_docs/doc-update-detection/actions/images/update-record.png b/_docs/doc-update-detection/actions/images/update-record.png new file mode 100644 index 000000000..d15fe6bd8 Binary files /dev/null and b/_docs/doc-update-detection/actions/images/update-record.png differ diff --git a/_docs/doc-update-detection/actions/introduction.md b/_docs/doc-update-detection/actions/introduction.md new file mode 100644 index 000000000..ef22e3849 --- /dev/null +++ b/_docs/doc-update-detection/actions/introduction.md @@ -0,0 +1,77 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Actions +title: 'Introduction to actions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/actions/introduction.md' +--- + +# Introduction to actions + +> For now, actions are only available for PostgreSQL and MySQL. + +![Example action](./images/example-action.png) + +## What are actions? + +**Actions** are entities in Metabase that let you build custom forms and business logic. + +Actions let you write parameterized SQL that writes back to your database. Actions can be attached to [buttons on dashboards](../dashboards/actions) to create custom workflows. You can even publicly share the parameterized forms that actions generate to collect data. + +Here are a few ideas for what you can do with actions: + +- Mark the customer you’re viewing in a dashboard as a VIP. +- Let team members remove redundant data. +- Create a customer feedback form and embed it on your website. + +Actions must be added to a [model](../data-modeling/models), but actions only run on the raw tables that back those models (so actions will never edit your [model definition](../data-modeling/models#edit-a-models-query)). + +## Enabling actions for a database + +For actions to work, you'll first need to do the following two things: + +1. **Enable model actions for the database connection**. To enable actions for a database connection, admins should click on the **gear** icon in the upper right and navigate to **Admin settings** > **Databases**, then click on the database you want to create actions for. On the right side of the connection settings form, toggle the **Model actions** option. For actions to work, the database user account (the account you're using to connect to the database) must have [write permissions](../databases/users-roles-privileges#privileges-to-enable-actions). And for now, actions are only supported on PostgreSQL and MySQL databases. +2. **Create at least one model from that database.** Actions are associated with models, so you'll need to have created (or have access to) at least one model before you can start creating actions. + +## Who can use actions + +- **To create or edit an action**, a person must be in a group with [Native query editing](../permissions/data) privileges for the relevant database. +- **To run an action**, all you need is view access to the action's model or dashboard (or a link to a public action). + +## Types of actions + +There are two types of actions: + +- [Basic](./basic) +- [Custom](./custom) + +## Running actions + +There are multiple ways to run actions: + +- [From the model details page](../data-modeling/models#model-details) by clicking the **run** button. +- From a [public form](./custom#make-public) of an action. +- From a [button on dashboard](../dashboards/actions). + +## Actions change data in tables, which affect models + +Just something to clarify here: actions, even though they are added to models, make their changes to the underlying table that a model queries. Which means that anyone who has access to the underlying table, or to questions or other models based on that table, will be able to see the effects of an action. Tools other than Metabase that are connected to that database will also pick up these changes. + +In this sense, models are containers for actions; models are a way to organize actions. In fact, you could (in theory) add a [custom action](./custom) to a model that performs some update unrelated to its model's data. For example, you could write a custom action that updates the `Accounts` table, and add that action to a model that only queries an unrelated table (e.g., the `Orders` table). But, you know, maybe don't do that (unless you have a really good reason). [Basic actions](./basic), however, are only be available for models that wrap a single raw table. + +Before using actions in production, consider playing around with actions on some sample data (like the Sample Database included with Metabase) to get a feel for how they work. + +## Action gotchas + +- If caching is enabled for the relevant table or model, you may not see the effects of an action in Metabase until Metabase refreshes the data (though you can always manually refresh the data). +- When creating records on a table that lacks an automatically generated primary key, you'll need to input an available ID (i.e., an ID not already in use by another record). +- You can't "undo" actions. You can, however, create and run an action to recreate a deleted record, or change an updated record back to its original values (provided you know the original values). +- Actions are unavailable for public dashboards, and dashboards in [static embeds](../embedding/static-embedding). + +## Further reading + +- [Basic actions](./basic) +- [Custom actions](./custom) +- [Actions in dashboards](../dashboards/actions) diff --git a/_docs/doc-update-detection/actions/start.md b/_docs/doc-update-detection/actions/start.md new file mode 100644 index 000000000..de255e183 --- /dev/null +++ b/_docs/doc-update-detection/actions/start.md @@ -0,0 +1,31 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: Actions +title: 'Actions overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/actions/start.md' +--- + +# Actions overview + +![An action updating a plan on a dashboard](./images/dashboard-action.gif) + +Actions let you write parameterized SQL that can then be attached to buttons, clicks, or even added on the page as form elements. + +## [Introduction to actions ](./introduction) + +Use actions to update your data based on user input or values on the page. + +## [Basic actions](./basic) + +Metabase will create basic actions that auto-track a model's schema. + +## [Custom actions](./custom) + +Write SQL to create new actions. + +## [Actions on dashboards](../dashboards/actions) + +Add actions on dashboards as buttons that you can pass filter values to. diff --git a/_docs/doc-update-detection/api.html b/_docs/doc-update-detection/api.html new file mode 100644 index 000000000..b5d0c50ef --- /dev/null +++ b/_docs/doc-update-detection/api.html @@ -0,0 +1,12912 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: false +show_title_breadcrumb: true +category: 'Table of Contents' +title: 'Metabase API documentation' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/api.html' +layout: docs-api +description: 'The official API documentation for Metabase.' +redirect_from: + - /docs/doc-update-detection/api-documentation + - /docs/doc-update-detection/api/action + - /docs/doc-update-detection/api/activity + - /docs/doc-update-detection/api/ee/advanced-config-logs + - /docs/doc-update-detection/api/ee/advanced-permissions-application + - /docs/doc-update-detection/api/ee/advanced-permissions-impersonation + - /docs/doc-update-detection/api/alert + - /docs/doc-update-detection/api/api-key + - /docs/doc-update-detection/api/ee/audit-app-user + - /docs/doc-update-detection/api/automagic-dashboards + - /docs/doc-update-detection/api/bookmark + - /docs/doc-update-detection/api/cache + - /docs/doc-update-detection/api/card + - /docs/doc-update-detection/api/channel + - /docs/doc-update-detection/api/cloud-migration + - /docs/doc-update-detection/api/collection + - /docs/doc-update-detection/api/ee/content-verification-review + - /docs/doc-update-detection/api/dashboard + - /docs/doc-update-detection/api/database + - /docs/doc-update-detection/api/dataset + - /docs/doc-update-detection/api/email + - /docs/doc-update-detection/api/embed + - /docs/doc-update-detection/api/field + - /docs/doc-update-detection/api/geojson + - /docs/doc-update-detection/api/google + - /docs/doc-update-detection/api/ldap + - /docs/doc-update-detection/api/llm + - /docs/doc-update-detection/api/login-history + - /docs/doc-update-detection/api/metabot + - /docs/doc-update-detection/api/model-index + - /docs/doc-update-detection/api/native-query-snippet + - /docs/doc-update-detection/api/notify + - /docs/doc-update-detection/api/permissions + - /docs/doc-update-detection/api/persist + - /docs/doc-update-detection/api/premium-features + - /docs/doc-update-detection/api/preview-embed + - /docs/doc-update-detection/api/public + - /docs/doc-update-detection/api/pulse + - /docs/doc-update-detection/api/ee/query-reference-validation + - /docs/doc-update-detection/api/revision + - /docs/doc-update-detection/api/routes + - /docs/doc-update-detection/api/ee/sandbox-gtap + - /docs/doc-update-detection/api/ee/sandbox-table + - /docs/doc-update-detection/api/ee/sandbox-user + - /docs/doc-update-detection/api/scim + - /docs/doc-update-detection/api/search + - /docs/doc-update-detection/api/segment + - /docs/doc-update-detection/api/serialization + - /docs/doc-update-detection/api/ee/sso + - /docs/doc-update-detection/api/sso-saml + - /docs/doc-update-detection/api/stale + - /docs/doc-update-detection/api/table + - /docs/doc-update-detection/api/task + - /docs/doc-update-detection/api/tiles + - /docs/doc-update-detection/api/timeline + - /docs/doc-update-detection/api/timeline-event + - /docs/doc-update-detection/api/user + - /docs/doc-update-detection/api/util +--- + + + + {% include head.html %} + + + + + + + diff --git a/_docs/doc-update-detection/configuring-metabase/appearance.md b/_docs/doc-update-detection/configuring-metabase/appearance.md new file mode 100644 index 000000000..3c7f56c40 --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/appearance.md @@ -0,0 +1,178 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: Appearance +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/appearance.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/whitelabeling + - /docs/doc-update-detection/enterprise-guide/whitelabeling + - /docs/doc-update-detection/enterprise-guide/customize-embeds + - /docs/doc-update-detection/embedding/whitelabeling + - /docs/doc-update-detection/embedding/fonts + - /docs/doc-update-detection/embedding/customize-embeds +--- + +# Appearance + +{% include plans-blockquote.html feature="Custom appearance" %} + +Appearance settings give admins the option to whitelabel Metabase to match your company’s branding. + +If you're looking for date, time, number, or currency formatting, see [Formatting defaults](../data-modeling/formatting). + +## Changing Metabase's appearance + +Hit cmd/ctrl + k to bring up the command palette and search for "Appearance" and click on Settings -> Appearance. + +You can also click on the **gear** icon at the bottom of the navigation sidebar and click through **Admin settings** > **Settings** > **Appearance**. + +Appearance settings are split across different tabs: + +- [Branding](#branding) +- [Conceal Metabase](#conceal-metabase) + +## Branding + +In the Branding tab, you can configure your Metabase to match your brand visuals and voice. + +- [Color palette](#color-palette) +- [User interface colors](#user-interface-colors) +- [Chart colors](#chart-colors) +- [Logo](#logo) +- [Font](#font) +- [Loading message](#loading-message) +- [Favicon](#favicon) + +## Color palette + +You can customize colors in both the application UI and in the Metabase charts. + +### User interface colors + +![User interface colors](./images/user-interface-colors.png) + +You can customize the colors that Metabase uses throughout the app: + +- **First color:** The main color used throughout the app for buttons, links, and the default chart color. +- **Second color:** The color of aggregations and breakouts in the graphical query builder. +- **Third color:** Color of filters in the query builder, buttons and links in filter widgets. + +### Chart colors + +![Chart colors](./images/chart-colors.png) + +You can choose up to 24 hex values. If you choose fewer than 24 colors, Metabase will auto-generate colors to fill in the rest of the values. And don't bother ordering the colors here, as their order doesn't apply to the order of colors for series on charts. When building a chart, Metabase will select colors to make each series easy to distinguish. + +Custom colors are unavailable for: + +- [Number charts](../questions/visualizations/numbers) +- [Trend charts](../questions/visualizations/trend) +- [Funnel charts](../questions/visualizations/funnel) +- Conditional formatting ([tables](../questions/visualizations/table) and [pivot tables](../questions/visualizations/pivot-table)) +- [Maps](../questions/visualizations/map) + +## Logo + +You can replace Metabase’s familiar, tasteful, inspired-yet-not-threateningly-avant-garde dotted M logo with your very own logo. For things to work best, the logo you upload should be an SVG file that looks good when it’s around 60px tall. (In other words, ask the nearest designer for help.) + +## Font + +This is the primary font used in charts and throughout the Metabase application (your "instance font"). See [Fonts](./fonts). + +## Loading message + +This message is the text Metabase presents when it's loading a query. Options include: + +- "Doing science..." (the default) +- "Running query..." +- "Loading results..." + +## Favicon + +The URL or image that you want to use as the favicon (the logo visible in browser tabs, address bars, bookmark lists, and other places). + +If you use a relative path, that path isn't relative to the Metabase JAR, but to the webserver. So unless you're using a reverse-proxy, the path will be relative to the frontend resources available to the JAR. + +## Conceal Metabase + +Hide or customize pieces of the Metabase product to tailor the experience to your brand and needs. + +- [Application name](#application-name) +- [Documentation and references](#documentation-and-references) +- [Help link in the settings menu](#help-link-in-the-settings-menu) +- [Metabase illustrations](#metabase-illustrations) + +## Application name + +You can change every place in the app that says “Metabase” to something like “Acme Analytics,” or whatever you want to call your Metabase app. + +## Documentation and references + +Control the visibility of links to official Metabase documentation and other references to Metabase in your instance. + +This setting affects all links in the product experience that point to Metabase.com URLs (with the exception of links and references in the Admin settings). + +## Help link in the settings menu + +The Settings menu (the "gear" menu in the upper right of your Metabase) includes a **Help** option that links to a [Metabase help page](/help/) by default. You can change this menu Help item by selecting one of the following options: + +- Link to [Metabase help](/help/) (default) +- Hide it (the Settings menu won't display the Help option at all). +- Go to a custom destination. Enter a URL that the Settings menu's Help option should link to. Valid URLs include http, https, and mailto URLs. + +## Metabase illustrations + +![Lighthouse illustration](./images/lighthouse-illustration.png) + +Customize each of the illustrations in Metabase. + +### Metabot greeting + +Turn this guy on or off: + +![Metabot greeting](./images/metabot-greeting.png) + +### Login and unsubscribe pages + +![Login page](./images/login-page.png) + +What people see when Metabase prompts them to log in. + +- Lighthouse +- No illustration +- Custom + +### Landing page + +The landing page is what people will see whenever they login. You can set the URL to a collection, question, dashboard or whatever, just make sure that everyone has access to that URL. + +- Lighthouse +- No illustration +- Custom + +### When calculations return no results + +![Sailboat](./images/sailboat.png) + +Metabase will display this illustration when questions or dashboard cards contain no results. + +- Sailboat +- No illustration +- Custom + +### When no objects can be found + +Metabase will display this illustration when searches don't return any results. + +- Sailboat +- No illustration +- Custom + +## Further reading + +- [Customer-facing analytics](/learn/metabase-basics/embedding). +- [Embedding introduction](../embedding/start). +- [Brand your Metabase](/learn/metabase-basics/embedding/brand). diff --git a/_docs/doc-update-detection/configuring-metabase/caching.md b/_docs/doc-update-detection/configuring-metabase/caching.md new file mode 100644 index 000000000..7c7fd0b06 --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/caching.md @@ -0,0 +1,175 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'Caching query results' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/caching.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/14-caching + - /docs/doc-update-detection/enterprise-guide/cache +--- + +# Caching query results + +If your question results don't change frequently, you may want to store the results so that the next time anyone visits the question, Metabase can retrieve the cached results rather than query the database again. + +For example, if your data only updates once a day, there's no point in querying the database more than once a day, as the data won't have changed. Returning cached results can be significantly faster, as your database won't have to recompute the results to load your question. + +You can set [caching invalidation policies](#cache-invalidation-policies) for [questions](#question-caching-policy), [dashboards](#dashboard-caching-policy), and [databases](#database-caching-policy). + +## How caching works in Metabase + +Let's say you set a caching policy for a particular question. You set a [duration](#duration-caching-policy) policy that says to invalidate the results (and clear the cache) after one hour. + +When you view the question for the first time, Metabase will check for stored results. When it doesn't find any, it will query your database, return the results, and store (cache) the results. Those results will remain valid for the next hour (according to the hour-long duration policy you set). + +If you run the question half an hour later, Metabase will return those stored results. + +If you run the question over an hour after that initial run, Metabase will notice that the stored results are older than your caching policy allows. Metabase will delete the stored results, run the query against your database, return the results, and store them for the future queries. This cache will remain valid for the next hour, according to the duration policy you set. To always refresh the cache when results expire, see [Refresh cache automatically](#refresh-cache-automatically). + +See how [different caching policies interact](#how-dashboard-question-database-and-default-caching-policies-interact). + +## Cache invalidation policies + +These policies determine how long cached results will remain valid. + +- [Duration](#duration-caching-policy) +- [Schedule](#schedule-caching-policy) +- [Adaptive](#adaptive-caching-policy) +- [Don't cache results](#dont-cache-results) + +### Duration caching policy + +{% include plans-blockquote.html feature="Duration caching policy" %} + +Invalidate and clear the cache after a certain number of hours. When someone runs a query, Metabase will first check whether it has cached the results, and whether those results are still valid. If not, Metabase runs the query against the database and caches the results. These cached results will remain valid for the duration you've set. + +### Schedule caching policy + +{% include plans-blockquote.html feature="Schedule caching policy" %} + +Pick when to regularly invalidate the cache. Metabase will only store results when people run a query, and it will clear the cached results according to the schedule you set here. + +You can schedule the cache to invalidate: + +- Hourly +- Daily +- Weekly +- Monthly + +We do not yet support lunar cycles. + +### Adaptive caching policy + +Use a query’s average execution time to determine how long to cache the query's results. + +- **Minimum query duration**: Metabase will cache this question if it has an average query execution time greater than this many seconds. +- **Multiplier**: To determine how long each cached result should stick around, we take that query's average execution time and multiply that by what you input here. The result is how many seconds the cache should remain valid for. For example, if a question takes on average 10 seconds to return results, and you set a multiplier of 100, Metabase will store the cache for 10 x 100 seconds: 1,000 seconds (~16 minutes). + +Metabase will recalculate a query's average execution time whenever it runs the query against the database to refresh the cached results. So if the first time Metabase runs the query against the database, it takes 5 minutes to return results, the average execution time will be 5 minutes. If the next query against the database takes 7 minutes to return, Metabase will update the average to 6 minutes (the average of 5 and 7 is 6). + +On [Pro](/product/pro) and [Enterprise](/product/enterprise) plans, you can view querying and caching stats in the [Usage analytics](../usage-and-performance-tools/usage-analytics) collection. + +### Don’t cache results + +If you select "Don't cache results" for a question, dashboard, or database, Metabase won't cache its results; it'll always run the query against the database to refresh results. + +## Refresh cache automatically + +{% include plans-blockquote.html feature="Refresh cache automatically" %} + +> **Refreshing the cache automatically doesn't apply when [data sandboxing](../permissions/data-sandboxes) or [connection impersonation](../permissions/impersonation) permissions are in effect.** In those permissions setups, Metabase ignores the automatically generated cache and runs a fresh query (which it will then cache). So _caching_ still works for sandboxing and impersonation, it's just that this preemptive, automatic caching doesn't apply in these cases, as those permissions setups filter data specific to each viewer. + +If you turn on refresh cache automatically for a question or dashboard, Metabase will rerun the query/queries as soon as the cache is invalidated by whichever caching policy you've set. Normally, Metabase only refreshes the cache when someone views the item _after_ its cache has expired. So, normally, when the cache has expired, the next person to view the question will be stuck waiting for the query to run and refresh the cache. But by automatically refreshing results to update the cache, the loading times will always be as fast as possible, and people will always get valid, cached results. + +### How Metabase handles parameter values when automatically refreshing the cache + +When automatically refreshing results, Metabase will apply the default parameter values (if any). Metabase will also cache results of up to ten of the most frequently applied parameter values that were applied _during the last caching period_ (as defined by your caching policy). If your question or dashboard has multiple parameters, Metabase will cache up to ten of the most frequently applied _combinations_ of parameter values. + +For example, let's say you have a dashboard with a category filter (default value: `Doohickey`) that's set to cache results every 24 hours. During the last 24 hours, people who viewed that dashboard applied the following values to the category filter: `Widget`, `Gizmo`. When Metabase next refreshes the cache, it will cache three sets of results, each set with one of those parameters applied: `Doohickey` (the default value), `Widget`, and `Gizmo`. If, however, _no one_ runs the query in that last 24 hours, Metabase will only refresh the cache for the results with the default parameter's value applied. + +### Automatic caching logs + +To view the queries Metabase ran to automatically refresh the cache, check out the [query log](../usage-and-performance-tools/usage-analytics#query-log-model) and filter the `Query source` by `cache-refresh`. + +## Set caching policies for dashboards, questions, and databases + +You can set caching policies for different entities. + +- [Setting a default caching policy](#default-caching-policy) +- [Database caching policy (specific to each connected database)](#database-caching-policy)\* +- [Dashboard caching](#dashboard-caching-policy)\* +- [Question caching](#question-caching-policy)\* + +_\* Denotes [Pro](/product/pro) and [Enterprise](/product/enterprise) features._ + +### Default caching policy + +To set a default caching policy for your Metabase: Hit Cmd/Ctrl + k to bring up the command palette and search for **Performance**. Or, click through **Gear** settings icon > **Admin settings** > **Performance** > **Database caching**. + +Click on the button next to **Default policy**, and select a [cache invalidation policy](#cache-invalidation-policies). + +### Database caching policy + +{% include plans-blockquote.html feature="Database caching" %} + +![Database caching settings in the Admin settings under the Performance tab](./images/data-caching-settings.png) + +Same as the default caching policy, though you can set a caching policy for specific databases. + +If you have databases connected to Metabase that are set to **Use default** policy, Metabase will update the display to reflect whatever the default policy is set to. For example, if you set the default policy to be "Adaptive", Metabase will display "Adaptive" as the current policy for those databases set to "Use default". + +### Dashboard caching policy + +{% include plans-blockquote.html feature="Dashboard caching" %} + +To set a caching policy for a dashboard, you must have [curate access](../permissions/collections#curate-access) to the dashboard's collection. + +1. Go to your dashboard. +2. Click on the **info** icon. +3. Click **Caching policy**. +4. Select the [caching invalidation policy](#cache-invalidation-policies). +5. Optional: turn on [refresh cache automatically](#refresh-cache-automatically). +6. Save your changes. + +### Question caching policy + +{% include plans-blockquote.html feature="Question caching" %} + +To set a caching policy for a question, you must have [curate access](../permissions/collections#curate-access) to the question's collection. + +1. Go to your question. +2. Click on the three-dot menu **...** and select **Edit settings**. +3. Under **Caching**, select the [caching invalidation policy](#cache-invalidation-policies). +5. Optional: if you select a Duration or Schedule policy, you'll have the option to [refresh cache automatically](#refresh-cache-automatically). +6. Save your changes. + +## How dashboard, question, database, and default caching policies interact + +If multiple caching policies affect the same question, Metabase will use the first available policy, in this order: + +1. Question +2. Dashboard +3. Database +4. Default (site-wide) + +A question policy overrides a dashboard policy, which overrides a database policy, which overrides a default policy. + +## Clearing the cache + +To clear the cache and refresh the results: + +- **Questions and dashboards**: Visit the item and click through the **Info > Caching policy > Clear cache** (the "Clear cache" button is at the bottom of the sidebar). +- **Database**: Click the **Gear** icon and click through **Admin settings** > **Performance** > **Database caching**. Select your database and click the **Clear cache** button (at the bottom of the page). + +## Caching location + +If you're self-hosting Metabase, cached question results will be saved to your [application database](../installation-and-operation/configuring-application-database). + +If you're using Metabase Cloud, cached question results will be saved to Metabase's servers in the United States (as our Cloud service manages your application database for you.) + +## Further reading + +- [Model persistence](../data-modeling/model-persistence) diff --git a/_docs/doc-update-detection/configuring-metabase/config-file.md b/_docs/doc-update-detection/configuring-metabase/config-file.md new file mode 100644 index 000000000..c0ece895f --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/config-file.md @@ -0,0 +1,284 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'Configuration file' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/config-file.md' +--- + +# Configuration file + +{% include plans-blockquote.html feature="Loading from a configuration file" self-hosted-only="true" %} + +On self-hosted [Pro](/product/pro) and [Enterprise](/product/enterprise) plans, Metabase supports initialization on launch from a config file named `config.yml`. The config file should be located at: + +- The current directory (the directory where the running Metabase JAR is located). +- The path specified by the `MB_CONFIG_FILE_PATH` [environment variable](./environment-variables). + +The settings in the config file work the same as if you'd set the settings in the Admin Settings in your Metabase. Settings defined in this configuration file will update any existing settings. If, for example, a database already exists (that is, you'd already added it via the initial set up or **Admin settings** > **Databases**, Metabase will update the database entry based on the data in the config file). Which means: if you define a setting in the config file, and then later change that setting in your Metabase application, keep in mind that the config file will overwrite that change whenever Metabase restarts. Let's reiterate that in a blockquote: + +> **Whenever Metabase restarts and loads your config file, the settings in the config file will _overwrite_ any changes to those settings made in the Metabase UI.** + +The config file settings are NOT treated as a hardcoded source of truth (like [environment variables](./environment-variables) are). Settings set by environment variables cannot be changed, even in the Admin settings in the application itself. + +## Example config template + +See [Config template](./config-template). + +## Config setup + +The config file is split up into sections: `version` and `config.` Under `config`, you can specify: + +- [Users](#users) +- [Databases](#databases) +- [Settings](#settings) + +Like so: + +```yml +version: 1 +config: + settings: + - ... + users: + - ... + databases: + - ... +``` + +The config file must also include a `version` key, which is just a convenience field for you to help you keep track of your config file versions. + +## Users + +The first user created in a Metabase instance is an Admin. The first user listed in the config file may be designated an admin, but not necessarily. If someone has already spun up and logged into that Metabase for the first time, Metabase will make that first user an admin. Additionally, you can specify a user account as an admin by using the `is_superuser: true` key. + +In the following example, assuming that the Metabase hasn't already been set up (which creates the first user) both users `first@example.com` and `admin@example.com` will be admins: `first@example.com` because it's the first user account on the list, and `admin@example.com` because that user has the `is_superuser` flag set to true. + +```yml +version: 1 +config: + users: + - first_name: First + last_name: Person + password: metabot1 + email: first@example.com + - first_name: Normal + last_name: Person + password: metabot1 + email: normal@example.com + - first_name: Admin + last_name: Person + password: metabot1 + is_superuser: true + email: admin@example.com +``` + +If the Metabase has already been set up, then `first@example.com` will be loaded as a normal user. + +## Databases + +On a new Metabase, the example below sets up an admin user account and one database connection. + +```yml +{% raw %} +version: 1 +config: + users: + - first_name: Cam + last_name: Era + password: 2cans3cans4cans + email: cam@example.com + databases: + - name: test-data (Postgres) + engine: postgres + details: + host: localhost + port: 5432 + user: dbuser + password: "{{ env POSTGRES_TEST_DATA_PASSWORD }}" + dbname: test-data +{% endraw %} +``` + +To determine which keys you can specify for a database, check out the fields available in Metabase itself for the database that you want to add. + +### Setting up uploads on a database + +You can also configure [uploads](../databases/uploads) in the config file with the following settings: + +- `uploads_enabled`: Boolean +- `uploads_schema_name`: String +- `uploads_table_prefix`: String + +Here's an example: + +```yml +{% raw %} +version: 1 +config: + users: + - first_name: Cam + last_name: Era + password: 2cans3cans4cans + email: cam@example.com + databases: + - name: test-data (Postgres) + engine: postgres + details: + host: localhost + port: 5432 + user: dbuser + password: "{{ env POSTGRES_TEST_DATA_PASSWORD }}" + dbname: test-data + uploads_enabled: true + uploads_schema_name: uploads + uploads_table_prefix: uploads_ +{% endraw %} +``` + +See [Uploads](../databases/uploads). + +## API keys + +You can use the config file to create API keys, which is useful for automated deployments and keeping API keys stable across environments. + +You can add API keys like so: + +```yaml +{% raw %} +version: 1 +config: + users: + - first_name: Cam + last_name: Era + password: 2cans3cans4cans + email: cam@example.com + api-keys: + - name: "Admin API key" + group: admin + creator: cam@example.com + key: mb_firsttestapikey + - name: "All Users API key" + group: all-users + creator: cam@example.com + key: mb_secondtestapikey +{% endraw %} +``` + +You can also use an environment variable to supply an API key, like so: + +``` +{% raw %} +api-keys: + - name: "ENV API Key" + key: "{{env API_KEY_FROM_ENV}}" + creator: "admin@example.com" + group: "admin" +{% endraw %} +``` + +See below for more on [env vars in the config file](#referring-to-environment-variables-in-the-configyml). + +API keys that you create (the value of the `key`) must have the format `mb_` followed by a [Base64](https://en.wikipedia.org/wiki/Base64) string (if you're wearing formal attire, you'd say a _tetrasexagesimal_ string). So, `mb_` followed by letters and numbers, minimum: 12 characters, maximum: 254 characters. Concretely, the API key you create must satisfy the following regular expression: `mb_[A-Za-z0-9+/=]+`. + +You can generate a handsome API key using the `openssl rand` command: + +```sh +echo "mb_$(openssl rand -base64 32)" +``` + +Which would generate something like: + +``` +mb_aDqk1Tc4ZotWb2TyjHY71glALKlB+g75dLgmSufWGLc= +``` + +Some other things to note about API keys in the config file: + +- The `creator` of an API key must be an admin. This means either a) your Metabase must already have at least one admin account, or b) you need to add an admin account in the `users` section of the config file. +- The keys themselves can be assigned to one of two groups: `admin` or `all-users`. The config file restricts `group` assignment to these groups because they're the only ones that Metabase _always_ initializes. +- The permissions for the key correspond to the permissions granted to its `group` (not its `creator`). +- If Metabase finds an existing API key with the same _name_ as a key in the config file, it will preserve the existing key (i.e., it won't overwrite the existing key with the key in the config file). For example, if you initially set up an API key, then later regenerate the key in the Metabase user interface, loading Metabase with the config file won't overwrite that regenerated key (which means the `key` in the config file will no longer work). +- If you _do_ want to overwrite the existing key from the config file, you'll need to first [delete the existing key](../people-and-groups/api-keys#deleting-api-keys). If you want to keep both keys, you'll need to rename the key in the config file. + +> The config file also contains an [`api-key`](./environment-variables#mb_api_key) key in the `settings` section of the config file. This setting _doesn't_ create API keys; it's used for string-matching in the header for authenticating requests to the `/notify` endpoint. + +## Referring to environment variables in the `config.yml` + +As shown in the Databases examples above, environment variables can be specified with `{% raw %}{{ template-tags }}{% endraw %}` like `{% raw %}{{ env POSTGRES_TEST_DATA_PASSWORD }}{% endraw %}` or `{% raw %}[[options {{template-tags}}]]{% endraw %}`. + +Metabase doesn't support recursive expansion, so if one of your environment variables references _another_ environment variable, you're going to have a bad time. + +## Values with special characters in the `config.yml` + +If a value contains double braces (`{%raw %}}}{% endraw %}` or `{%raw %}{{{% endraw %}`), you must use triple backticks to tell the config parser to use the literal value. For example, if your password was `{% raw %}MetaPa$$123{{>{% endraw %}`, you'd need to wrap the value in triple braces, like so: + +``` +{% raw %} +password: {{{ MetaPa$$123{{> }}} +{% endraw %} +``` + +## Disable initial database sync + +When loading a data model from a serialized export, you want to disable the scheduler so that the Metabase doesn't try to sync. + +To disable the initial database sync, you can add `config-from-file-sync-database` to the `settings` list and set the value to `false`. The setting `config-from-file-sync-database` must come _before_ the databases list, like so: + +```yml +version: 1 +config: + settings: + config-from-file-sync-databases: false + databases: + - name: my-database + engine: postgres + details: ... +``` + +## Settings + +In this config file, you can specify _any_ Admin setting. + +In general, the settings you can set in the `settings` section of this config file map to the [environment variables](./environment-variables), so check them out to see which settings you can use in your config file. The actual key that you include in the config file differs slightly from the format used for environment variables. For environment variables, the form is in screaming snake case, prefixed by an `MB`: + +```txt +MB_NAME_OF_VARIABLE +``` + +Whereas in the config file, you'd translate that to: + +```txt +name-of-variable +``` + +So for example, if you wanted to specify the `MB_EMAIL_FROM_NAME` in the `config.yml` file: + +```yml +version: 1 +config: + settings: + config-from-file-sync-databases: false + email-from-name: Stampy von Mails-a-lot + databases: + - name: my-database + engine: h2 + details: ... +``` + +But you can set any of the Admin settings with the config file (for a list of settings, check out the [config file template](./config-template)). You can also browse the list of [environment variable](./environment-variables) to see what you can configure (though note that not all environment variables can be set via the config file.) + +## Loading a new Metabase from a config file + +Since loading from a config file is a Pro/Enterprise feature: for new installations, you'll need to supply Metabase with a token using the `MB_PREMIUM_EMBEDDING_TOKEN` environment variable. + +```sh +MB_PREMIUM_EMBEDDING_TOKEN="[your token]" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +## Further reading + +- [Config file template](./config-template) +- [Environment variables](./environment-variables) diff --git a/_docs/doc-update-detection/configuring-metabase/config-template.md b/_docs/doc-update-detection/configuring-metabase/config-template.md new file mode 100644 index 000000000..30d2eace3 --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/config-template.md @@ -0,0 +1,266 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'Metabase config file template' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/config-template.md' +--- + +# Metabase config file template + +You can generate the following config file template by changing into the top-level Metabase directory and running: + +``` +clojure -M:doc:ee config-template +``` + +The template lists example `database`, `user`, and `settings` sections for the [config file](./config-file). + + +```yaml +# A config file template for Metabase. +# You'll need to update (or remove) the `users` and `databases` sections. +# The settings in `settings` include default values. We recommend removing +# or commenting out settings that you don't set. +# For more on the configuration file, see: +# https://www.metabase.com/docs/latest/configuring-metabase/config-file +# For more on what each setting does, check out: +# https://www.metabase.com/docs/latest/configuring-metabase/environment-variables +version: 1 +config: + users: + - first_name: First + last_name: Person + password: metabot1 + email: first@example.com + - first_name: Normal + last_name: Person + password: metabot1 + email: normal@example.com + - first_name: Admin + last_name: Person + password: metabot1 + is_superuser: true + email: admin@example.com + databases: + - name: Sample PostgreSQL + engine: postgres + details: + host: postgres-data + port: 5432 + user: metabase + password: metasample123 + dbname: sample + - name: Sample MySQL + engine: mysql + details: + host: mysql-data + port: 3306 + user: metabase + password: metasample123 + dbname: sample + api-keys: + - name: Admin API key + group: admin + creator: first@example.com + key: mb_firsttestapikey123 + - name: All Users API key + group: all-users + creator: first@example.com + key: mb_secondtestapikey456 + settings: + admin-email: null + aggregated-query-row-limit: null + allowed-iframe-hosts: |- + youtube.com, + youtu.be, + loom.com, + vimeo.com, + docs.google.com, + calendar.google.com, + airtable.com, + typeform.com, + canva.com, + codepen.io, + figma.com, + grafana.com, + miro.com, + excalidraw.com, + notion.com, + atlassian.com, + trello.com, + asana.com, + gist.github.com, + linkedin.com, + twitter.com, + x.com + anon-tracking-enabled: true + api-key: null + application-colors: {} + application-favicon-url: app/assets/img/favicon.ico + application-font: Lato + application-font-files: null + application-logo-url: app/assets/img/logo.svg + application-name: Metabase + attachment-row-limit: null + attachment-table-row-limit: 20 + backfill-entity-ids-repeat-ms: 2000 + bcc-enabled: true + breakout-bin-width: 10.0 + breakout-bins-num: 8 + check-for-updates: true + config-from-file-sync-databases: true + custom-formatting: {} + custom-geojson: null + custom-geojson-enabled: true + custom-homepage: false + custom-homepage-dashboard: null + db-connection-timeout-ms: 10000 + db-query-timeout-minutes: 20 + default-maps-enabled: true + download-row-limit: null + ee-ai-features-enabled: false + ee-openai-api-key: null + ee-openai-model: gpt-4-turbo-preview + email-from-address: notifications@metabase.com + email-from-name: null + email-max-recipients-per-second: null + email-reply-to: null + email-smtp-host: null + email-smtp-password: null + email-smtp-port: null + email-smtp-security: none + email-smtp-username: null + embedding-app-origins-interactive: null + embedding-app-origins-sdk: localhost:* + embedding-homepage: hidden + embedding-secret-key: null + enable-embedding-interactive: false + enable-embedding-sdk: false + enable-embedding-static: false + enable-field-usage-analysis: false + enable-password-login: true + enable-pivoted-exports: true + enable-public-sharing: true + enable-query-caching: true + enable-xrays: true + follow-up-email-sent: false + google-auth-auto-create-accounts-domain: null + google-auth-client-id: null + google-auth-enabled: null + gsheets: null + health-check-logging-enabled: true + help-link: metabase + help-link-custom-destination: https://www.metabase.com/help/premium + humanization-strategy: simple + jdbc-data-warehouse-max-connection-pool-size: 15 + jwt-attribute-email: email + jwt-attribute-firstname: first_name + jwt-attribute-groups: groups + jwt-attribute-lastname: last_name + jwt-enabled: false + jwt-group-mappings: {} + jwt-group-sync: false + jwt-identity-provider-uri: null + jwt-shared-secret: null + jwt-user-provisioning-enabled: true + landing-page: '' + landing-page-illustration: default + landing-page-illustration-custom: null + ldap-attribute-email: mail + ldap-attribute-firstname: givenName + ldap-attribute-lastname: sn + ldap-bind-dn: null + ldap-enabled: false + ldap-group-base: null + ldap-group-mappings: {} + ldap-group-membership-filter: (member={dn}) + ldap-group-sync: false + ldap-host: null + ldap-password: null + ldap-port: 389 + ldap-security: none + ldap-sync-user-attributes: true + ldap-sync-user-attributes-blacklist: userPassword,dn,distinguishedName + ldap-user-base: null + ldap-user-filter: (&(objectClass=inetOrgPerson)(|(uid={login})(mail={login}))) + ldap-user-provisioning-enabled: true + loading-message: doing-science + login-page-illustration: default + login-page-illustration-custom: null + map-tile-server-url: https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png + native-query-autocomplete-match-style: substring + nested-field-columns-value-length-limit: 50000 + no-data-illustration: default + no-data-illustration-custom: null + no-object-illustration: default + no-object-illustration-custom: null + not-behind-proxy: false + notification-link-base-url: null + notification-thread-pool-size: 3 + persisted-model-refresh-cron-schedule: 0 0 0/6 * * ? * + persisted-models-enabled: false + premium-embedding-token: null + query-analysis-enabled: false + query-caching-max-kb: 2000 + query-caching-max-ttl: 3024000.0 + redirect-all-requests-to-https: false + report-timezone: null + reset-token-ttl-hours: 48 + retry-initial-interval: 500 + retry-max-attempts: 7 + retry-max-interval-millis: 30000 + retry-multiplier: 2.0 + retry-randomization-factor: 0.1 + saml-application-name: Metabase + saml-attribute-email: null + saml-attribute-firstname: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname + saml-attribute-group: member_of + saml-attribute-lastname: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname + saml-enabled: false + saml-group-mappings: {} + saml-group-sync: false + saml-identity-provider-certificate: null + saml-identity-provider-issuer: null + saml-identity-provider-slo-uri: null + saml-identity-provider-uri: null + saml-keystore-alias: metabase + saml-keystore-password: changeit + saml-keystore-path: null + saml-slo-enabled: false + saml-user-provisioning-enabled: true + scim-enabled: null + search-engine: in-place + search-typeahead-enabled: true + send-new-sso-user-admin-email: null + session-cookie-samesite: lax + session-cookies: null + session-timeout: null + setup-embedding-autoenabled: false + setup-license-active-at-setup: false + show-database-syncing-modal: null + show-homepage-data: true + show-homepage-xrays: true + show-metabase-links: true + show-metabot: true + show-static-embed-terms: true + site-locale: en + site-name: Metabase + site-url: null + slack-app-token: null + slack-bug-report-channel: metabase-bugs + source-address-header: X-Forwarded-For + sql-jdbc-fetch-size: 500 + sql-parsing-enabled: true + ssh-heartbeat-interval-sec: 180 + start-of-week: sunday + subscription-allowed-domains: null + surveys-enabled: true + synchronous-batch-updates: false + unaggregated-query-row-limit: null + update-channel: latest + uploads-settings: null + user-visibility: all +``` diff --git a/_docs/doc-update-detection/configuring-metabase/custom-maps.md b/_docs/doc-update-detection/configuring-metabase/custom-maps.md new file mode 100644 index 000000000..20784a43a --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/custom-maps.md @@ -0,0 +1,64 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'Custom maps' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/custom-maps.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/20-custom-maps +--- + +# Custom maps + +By default, Metabase uses OpenStreetMaps for map visualizations, but there are a few customization options. + +## Map settings + +To find the map settings: + +1. At the top right of the screen, click **gear** icon > **Admin settings** > **Settings**. +2. Select `Maps` from the navigation on the left. + +![Map Settings](images/MapSettings.png) + +## Map tile server + +By default, Metabase uses the [OpenStreetMaps](https://www.openstreetmap.org) tile server for pin and grid maps. If your organization requires a different +look or level of detail in your map visualizations, you can change the map tile server by adding the map tile server path to the first field on the page. + +The path must either be a URL that starts with `http://` or `https://` or a relative path to a local file in the JVM's classpath. + +Currently, Metabase uses a single tile server per instance. You can't specify different tiles for different maps. + +## Custom region maps + +Metabase comes with two built-in [region maps](../questions/visualizations/map#region-maps): world map with countries and United States map with states. + +If you need a map of other regions - like EU countries or NYC neighborhoods - you can specify a GeoJSON file containing region information. You can often find GeoJSON maps by searching online for "[Your region] + geojson", like "NYC neighborhoods GeoJSON." Many community members and government organizations have already developed map files for common regions. You can also create your own GeoJSON with a tool like [MapShaper](https://mapshaper.org/) or [GeoJSON.io](http://geojson.io/). + +Your GeoJSON file should: + +- Be less than 5 MB in size. +- Contain polygon features defining regions (not just points or coordinates) +- Use geographic coordinates (latitude and longitude) to define region polygons. Metabase doesn't support projected coordinates, so you'll need to convert projected coordinates to geographic coordinates. +- Accessible by a public URL. Currently, you can't upload a GeoJSON to Metabase. + +To add a custom map: + +1. Go to **Admin Settings > Maps > Custom Maps**. +2. Click **Add a Map**. +3. Enter a name for your map. +4. Provide the URL to your GeoJSON file. +5. Specify the JSON properties that should serve as region identifier and region name. + +![Uploading a custom GeoJSON](./images/custom-geojson.png) + +- **Name of the map** will be displayed in the region selector for [custom region maps](../questions/visualizations/map#custom-regions) +- **Region's identifier** is a GeoJSON field that identifies your region. The values in this field should match how the regions are referenced in your data. The field does not need to match the display name . +- **Region's display name** is a GeoJSON field that specifies how your region name will be displayed on a map. This field can be different from region's identifier. + +To pre-load one or more region maps when Metabase starts, you can use the environment variable [`MB_CUSTOM_GEOJSON`](./environment-variables#mb_custom_geojson) or a [config file option](./config-file) `custom-geojson` . + +To disable the creation of custom maps, use the [`MB_CUSTOM_GEOJSON_ENABLED`](./environment-variables#mb_custom_geojson_enabled) or a [config file option](./config-file) `custom-geojson-enabled`. diff --git a/_docs/doc-update-detection/configuring-metabase/customizing-jetty-webserver.md b/_docs/doc-update-detection/configuring-metabase/customizing-jetty-webserver.md new file mode 100644 index 000000000..70c234212 --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/customizing-jetty-webserver.md @@ -0,0 +1,45 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'Customizing the Metabase Jetty webserver' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/customizing-jetty-webserver.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/customizing-jetty-webserver +--- + +# Customizing the Metabase Jetty webserver + +In most cases there will be no reason to modify any of the settings around how Metabase runs its embedded Jetty webserver to host the application, but if you wish to run HTTPS directly with your Metabase server or if you need to run on another port, that's all configurable. + +## Running Metabase on another port + +By default Metabase will launch on port 3000, but if you prefer to run the application on another port you can do so by setting the following environment variable: + + export MB_JETTY_PORT=12345 + java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar + +In this example once the application starts up you will access it on port `12345` instead of the default port of 3000. + +## Listening on a specific network interface + +By default, Metabase will be listening on `localhost`. In some production environments you may want to listen on a different interface, which can be done by using the `MB_JETTY_HOST` environment variable: + + export MB_JETTY_HOST=0.0.0.0 + java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar + +## Using HTTPS with Metabase + +If you have an SSL certificate and would prefer to have Metabase run over HTTPS directly using its webserver, you can do so by using the following environment variables: + + export MB_JETTY_SSL="true" + export MB_JETTY_SSL_PORT="8443" + export MB_JETTY_SSL_KEYSTORE="path/to/keystore.jks" # replace this value with your own + export MB_JETTY_SSL_KEYSTORE_PASSWORD="storepass" # replace this value with your own + java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar + +Be sure to replace `path/to/keystore.jks` and `storepass` with the correct path to and password for your [Java KeyStore](https://www.digitalocean.com/community/tutorials/java-keytool-essentials-working-with-java-keystores). With the above settings applied you will be running Metabase on port 8443 over HTTPS using the supplied certificate. + +No idea how to generate a Java KeyStore yourself? This is sort of an advanced topic, but if you're feeling froggy you can read more about how to configure SSL in Jetty [in their own documentation](https://jetty.org/docs/jetty/12/operations-guide/keystore/index.html). Otherwise, you'll probably find it easiest to handle SSL termination outside of Metabase. diff --git a/_docs/doc-update-detection/configuring-metabase/email.md b/_docs/doc-update-detection/configuring-metabase/email.md new file mode 100644 index 000000000..f63f203bb --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/email.md @@ -0,0 +1,138 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'Set up email' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/email.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/02-setting-up-email +--- + +# Set up email + +Once you connect your database to Metabase, you'll want to configure an email account to send system notifications to your organization's users. Metabase uses email to reset passwords, onboard new users, and notify you when something happens. + +To edit email settings: + +1. Click on the **gear** icon in the upper right. +2. Select **Admin Settings**. +3. From the default **Settings** tab, click on **Notification channels** in the left sidebar. +4. Select **Email**. + +## Metabase Cloud + +Metabase Cloud manages an email server for you, so you don't need to set up email (and you won't see SMTP settings in your Admin console). + +If you like, you can still set up: + +- A name for your Cloud email account (from name) +- An email address to receive email replies (reply-to address) + +## Configuring your email account + +For Metabase to send messages to your organization's users, you'll need to set up an email account to send emails via **SMTP** (simple mail transfer protocol), which is an email standard that secures emails with SSL security protection. + +To start, go to the Admin Panel from the dropdown menu in the top right of Metabase, then from the Settings page, click on **Email** in the left menu. + +You should see this form: + +![Email Credentials](images/EmailCredentials.png) + +Here you'll set: + +- **SMTP HOST**: The address of the SMTP server that handles your emails. +- **SMTP PORT**: The port your SMTP server uses for outgoing emails. +- **SMTP SECURITY**: + - None + - SSL + - TLS + - STARTTLS +- **SMTP Username**. +- **SMTP Password**. + +You'll also need to specify your: + +- **From address**: The email address you want to use for the sender of emails. +- **Reply-to address**: The email address you want the replies to go to, if different from the from address. + +## Add recipients as CC or BCC + +By default, Metabase will hide email recipients by including them in the BCC list (Blind Carbon Copy) of the email. But if you're having issues with your email provider blocking emails with BCC recipients, and you don't mind having people see who else has been copied on the email Metabase sends them, you can tell Metabase to CC (Carbon Copy) recipients instead. + +### Recommended email settings + +- SSL is strongly recommended because it’s more secure and gives your account extra protection from threats. +- If your email service has a whitelist of email addresses that are allowed to send email, be sure to whitelist the email address that you put in the **From Address** field to ensure you and your teammates receive all emails from Metabase. + +## Notes for common email services + +- [Google Apps](#google-apps) +- [Amazon SES](#amazon-ses) +- [Mandrill](#mandrill) + +### Google Apps + +1. In the **SMTP host** field, enter smtp.gmail.com +2. Fill in 465 for the **SMTP port** field +3. For the **SMTP Security** field, enter **SSL** +4. In the **SMTP username** field, enter your Google Apps email address (e.g. hello@yourdomain.com) +5. Enter your Google Apps password in the **SMTP password** field +6. Enter the email address you would like to be used as the sender of system notifications in the \*_From Address_ field. + +### Amazon SES + +1. Log on to [https://console.aws.amazon.com/ses](https://console.aws.amazon.com/ses). +2. Click **SMTP Settings** from the navigation pane. +3. Select **Create My SMTP Credentials** in the content pane. +4. Create a user in the **Create User for SMTP** dialog box and then click **Create**. +5. Next, select **Show User SMTP Credentials** to view the user's SMTP credentials. +6. Go back to the Metabase Admin Panel form and enter the info there. + +Check if [email quotas](https://docs.aws.amazon.com/ses/latest/dg/quotas.html) apply to your Amazon SES server. You may want to manage your email recipients using groups instead. + +### Mandrill + +1. Log in to your Mandrill account and locate your credentials from the **SMTP & API Info** page there. +2. Your SMTP password is any active API key for your account — _not_ your Mandrill password. +3. Although Mandrill lists **port 587**, [any port supported by Mandrill](https://mailchimp.com/developer/transactional/docs/smtp-integration/#the-basics) will work for SMTP email. +4. Now you can go back to the Metabase Admin Panel form and enter the info there. + +## Approved domains for notifications + +{% include plans-blockquote.html feature="Approved domains for notifications" %} + +Allowed email address domain(s) for new [dashboard subscriptions](../dashboards/subscriptions) and [alerts](../questions/alerts). + +Adding approved domains allows you to restrict which email addresses people can send alerts and subscriptions to. This restriction only applies to sending email to people who lack an account with that Metabase. People with accounts in a Metabase who aren't [sandboxed](../permissions/data-sandboxes) will be able to email any other person with an account in that same Metabase. + +To allow all domains, leave the field empty (allowing all domains is the default). + +To specify multiple domains, separate each domain with a comma, with no space in between (e.g., "domain1,domain2"). + +You can also set this property using the environment variable [`MB_SUBSCRIPTION_ALLOWED_DOMAINS`](../configuring-metabase/environment-variables#mb_subscription_allowed_domains). + +> This setting doesn't affect existing subscriptions and alerts. + +## Suggest recipients on dashboard subscriptions and alerts + +{% include plans-blockquote.html feature="Configuring suggested recipients" %} + +Control which recipients people can see when they create a new [dashboard subscription](../dashboards/subscriptions) or [alert](../questions/alerts). For example, you may want to restrict people to viewing potential recipients that belong to the same [groups](../people-and-groups/managing#groups) they are a member of. + +Options include: + +- Suggest all users +- Only suggest users in the same groups +- Don't show suggestions + +People who are sandboxed won't see suggestions. + +## Further reading + +- [Alerts](../questions/alerts) +- [Dashboard subscriptions](../dashboards/subscriptions) +- [Notification permissions](../permissions/notifications) +- [Setting up Slack](./slack) +- [Usage Analytics](../usage-and-performance-tools/usage-analytics) diff --git a/_docs/doc-update-detection/configuring-metabase/environment-variables.md b/_docs/doc-update-detection/configuring-metabase/environment-variables.md new file mode 100644 index 000000000..cb3a04e17 --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/environment-variables.md @@ -0,0 +1,2263 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'Environment variables' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/environment-variables.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/environment-variables +--- + +# Environment variables + +_This documentation was generated from source by running:_ + +``` +clojure -M:ee:doc environment-variables-documentation +``` + +Many settings in Metabase can be viewed and modified in the Admin Panel, or set via environment variables. The environment variables always take precedence. Note that, unlike settings configured in the Admin settings of your Metabase, the environment variables won't get written into the application database. + +## How to set environment variables + +Setting environment variables can be done in various ways depending on how you're running Metabase. + +JAR file: + +``` +# Mac, Linux and other Unix-based systems +export MB_SITE_NAME="Awesome Company" +# Windows Powershell +$env:MB_SITE_NAME="Awesome Company" +# Windows batch/cmd +set MB_SITE_NAME="Awesome Company" + +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +Or set it as Java property, which works the same across all systems: + +``` +java -DMB_SITE_NAME="Awesome Company" -jar metabase.jar +``` + +Docker: + +``` +docker run -d -p 3000:3000 -e MB_SITE_NAME="Awesome Company" --name metabase metabase/metabase +``` + +## Environment variables on Metabase Cloud + +If you're running Metabase Cloud, you can [contact support](/help/premium) to adjust environment variables for your Metabase. + +--- + +## List of environment variables + + +### `MB_ADMIN_EMAIL` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `admin-email` + +The email address users should be referred to if they encounter a problem. + +### `MB_AGGREGATED_QUERY_ROW_LIMIT` + +- Type: integer +- Default: `10000` +- [Exported as](../installation-and-operation/serialization): `aggregated-query-row-limit`. +- [Configuration file name](./config-file): `aggregated-query-row-limit` + +Maximum number of rows to return for aggregated queries via the API. + +Must be less than 1048575. See also MB_UNAGGREGATED_QUERY_ROW_LIMIT. + +### `MB_ALLOWED_IFRAME_HOSTS` + +- Type: string +- Default: `youtube.com, +youtu.be, +loom.com, +vimeo.com, +docs.google.com, +calendar.google.com, +airtable.com, +typeform.com, +canva.com, +codepen.io, +figma.com, +grafana.com, +miro.com, +excalidraw.com, +notion.com, +atlassian.com, +trello.com, +asana.com, +gist.github.com, +linkedin.com, +twitter.com, +x.com` +- [Exported as](../installation-and-operation/serialization): `allowed-iframe-hosts`. +- [Configuration file name](./config-file): `allowed-iframe-hosts` + +Allowed iframe hosts. + +### `MB_ANON_TRACKING_ENABLED` + +- Type: boolean +- Default: `true` +- [Configuration file name](./config-file): `anon-tracking-enabled` + +Enable the collection of anonymous usage data in order to help Metabase improve. + +### `MB_API_KEY` + +- Type: string +- Default: `null` + +When set, this key is required for calls to /notify/ endpoints. + +Middleware that enforces validation of the client via the request header X-Metabase-Apikey for /notify endpoints. + If the header is available, then it's validated against MB_API_KEY. + When it matches, the request continues; otherwise it's blocked with a 403 Forbidden response. + MB_API_KEY is used only for /notify endpoints and isn't the same as Metabase API keys + used for authenticating other API requests. MP_API_KEY can be an arbitrary string. + +### `MB_APPLICATION_COLORS` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: json +- Default: `{}` +- [Exported as](../installation-and-operation/serialization): `application-colors`. +- [Configuration file name](./config-file): `application-colors` + +Choose the colors used in the user interface throughout Metabase and others specifically for the charts. You need to refresh your browser to see your changes take effect. + +To change the user interface colors: + +``` +{ + "brand":"#ff003b", + "filter":"#FF003B", + "summarize":"#FF003B" +} +``` + +To change the chart colors: + +``` +{ + "accent0":"#FF0005", + "accent1":"#E6C367", + "accent2":"#B9E68A", + "accent3":"#8AE69F", + "accent4":"#8AE6E4", + "accent5":"#8AA2E6", + "accent6":"#B68AE6", + "accent7":"#E68AD0" +} +``` + +### `MB_APPLICATION_FAVICON_URL` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `app/assets/img/favicon.ico` +- [Exported as](../installation-and-operation/serialization): `application-favicon-url`. +- [Configuration file name](./config-file): `application-favicon-url` + +Upload a file to use as the favicon. + +### `MB_APPLICATION_FONT` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `Lato` +- [Exported as](../installation-and-operation/serialization): `application-font`. +- [Configuration file name](./config-file): `application-font` + +Replace “Lato” as the font family. + +### `MB_APPLICATION_FONT_FILES` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: json +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `application-font-files`. +- [Configuration file name](./config-file): `application-font-files` + +Tell us where to find the file for each font weight. You don’t need to include all of them, but it’ll look better if you do. + +Example value: + +``` +[ + { + "src": "https://example.com/resources/font-400", + "fontFormat": "ttf", + "fontWeight": 400 + }, + { + "src": "https://example.com/resources/font-700", + "fontFormat": "woff", + "fontWeight": 700 + } +] +``` + +See [fonts](../configuring-metabase/fonts). + +### `MB_APPLICATION_LOGO_URL` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `app/assets/img/logo.svg` +- [Exported as](../installation-and-operation/serialization): `application-logo-url`. +- [Configuration file name](./config-file): `application-logo-url` + +Upload a file to replace the Metabase logo on the top bar. + +Inline styling and inline scripts are not supported. + +### `MB_APPLICATION_NAME` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `Metabase` +- [Exported as](../installation-and-operation/serialization): `application-name`. +- [Configuration file name](./config-file): `application-name` + +Replace the word “Metabase” wherever it appears. + +### `MB_ATTACHMENT_ROW_LIMIT` + +- Type: positive-integer +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `attachment-row-limit`. + +Row limit in file attachments excluding the header. + +### `MB_ATTACHMENT_TABLE_ROW_LIMIT` + +- Type: positive-integer +- Default: `20` + +Maximum number of rows to render in an alert or subscription image. + +Range: 1-100. To limit the total number of rows included in the file attachment + for an email dashboard subscription, use MB_UNAGGREGATED_QUERY_ROW_LIMIT. + +### `MB_BACKFILL_ENTITY_IDS_REPEAT_MS` + +- Type: integer +- Default: `2000` +- [Exported as](../installation-and-operation/serialization): `backfill-entity-ids-repeat-ms`. + +Frequency for running backfill entity ids job in ms. Minimum value is 1000, and any value at or below 0 will disable the job entirely. + +### `MB_BCC_ENABLED` + +- Type: boolean +- Default: `true` +- [Configuration file name](./config-file): `bcc-enabled` + +Whether or not bcc emails are enabled, default behavior is that it is. + +### `MB_BREAKOUT_BIN_WIDTH` + +- Type: double +- Default: `10.0` +- [Configuration file name](./config-file): `breakout-bin-width` + +When using the default binning strategy for a field of type Coordinate (such as Latitude and Longitude), this number will be used as the default bin width (in degrees). + +### `MB_BREAKOUT_BINS_NUM` + +- Type: integer +- Default: `8` +- [Exported as](../installation-and-operation/serialization): `breakout-bins-num`. +- [Configuration file name](./config-file): `breakout-bins-num` + +When using the default binning strategy and a number of bins is not provided, this number will be used as the default. + +### `MB_CHECK_FOR_UPDATES` + +- Type: boolean +- Default: `true` +- [Configuration file name](./config-file): `check-for-updates` + +Identify when new versions of Metabase are available. + +### `MB_CONFIG_FROM_FILE_SYNC_DATABASES` + +- Type: boolean +- Default: `true` + +Whether to (asynchronously) sync newly created Databases during config-from-file initialization. By default, true, but you can disable + this behavior if you want to sync it manually or use SerDes to populate its data model. + +### `MB_CUSTOM_FORMATTING` + +- Type: json +- Default: `{}` +- [Exported as](../installation-and-operation/serialization): `custom-formatting`. +- [Configuration file name](./config-file): `custom-formatting` + +Object keyed by type, containing formatting settings. + +### `MB_CUSTOM_GEOJSON` + +- Type: json +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `custom-geojson`. +- [Configuration file name](./config-file): `custom-geojson` + +JSON containing information about custom GeoJSON files for use in map visualizations instead of the default US State or World GeoJSON. + +### `MB_CUSTOM_GEOJSON_ENABLED` + +- Type: boolean +- Default: `true` +- [Exported as](../installation-and-operation/serialization): `custom-geojson-enabled`. +- [Configuration file name](./config-file): `custom-geojson-enabled` + +Whether or not the use of custom GeoJSON is enabled. + +### `MB_CUSTOM_HOMEPAGE` + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `custom-homepage` + +Pick one of your dashboards to serve as homepage. Users without dashboard access will be directed to the default homepage. + +### `MB_CUSTOM_HOMEPAGE_DASHBOARD` + +- Type: integer +- Default: `null` +- [Configuration file name](./config-file): `custom-homepage-dashboard` + +ID of dashboard to use as a homepage. + +### `MB_DB_CONNECTION_TIMEOUT_MS` + +- Type: integer +- Default: `10000` + +Consider metabase.driver/can-connect? / can-connect-with-details? to have failed if they were not able to + successfully connect after this many milliseconds. By default, this is 10 seconds. + +Timeout in milliseconds for connecting to databases, both Metabase application database and data connections. + In case you're connecting via an SSH tunnel and run into a timeout, you might consider increasing this value + as the connections via tunnels have more overhead than connections without. + +### `MB_DB_QUERY_TIMEOUT_MINUTES` + +- Type: integer +- Default: `20` + +By default, this is 20 minutes. + +Timeout in minutes for databases query execution, both Metabase application database and data connections. + If you have long-running queries, you might consider increasing this value. + Adjusting the timeout does not impact Metabase’s frontend. + Please be aware that other services (like Nginx) may still drop long-running queries. + +### `MB_DEFAULT_MAPS_ENABLED` + +- Type: boolean +- Default: `true` +- [Exported as](../installation-and-operation/serialization): `default-maps-enabled`. +- [Configuration file name](./config-file): `default-maps-enabled` + +Whether or not the default GeoJSON maps are enabled. + +### `MB_DOWNLOAD_ROW_LIMIT` + +- Type: positive-integer +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `download-row-limit`. + +Row limit in file exports excluding the header. Enforces 1048575 excluding header as minimum. xlsx downloads are inherently limited to 1048575 rows even if this limit is higher. + +### `MB_EE_AI_FEATURES_ENABLED` + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `ee-ai-features-enabled` + +Enable AI features. + +This feature is experimental. + +### `MB_EE_OPENAI_API_KEY` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `ee-openai-api-key` + +The OpenAI API Key used in Metabase Enterprise. + +This feature is experimental. + +### `MB_EE_OPENAI_MODEL` + +- Type: string +- Default: `gpt-4-turbo-preview` +- [Configuration file name](./config-file): `ee-openai-model` + +The OpenAI Model (e.g. 'gpt-4', 'gpt-3.5-turbo'). + +This feature is experimental. + +### `MB_EMAIL_FROM_ADDRESS` + +- Type: string +- Default: `notifications@metabase.com` +- [Configuration file name](./config-file): `email-from-address` + +The email address you want to use for the sender of emails. + +### `MB_EMAIL_FROM_NAME` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `email-from-name` + +The name you want to use for the sender of emails. + +### `MB_EMAIL_MAX_RECIPIENTS_PER_SECOND` + +- Type: integer +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `email-max-recipients-per-second`. +- [Configuration file name](./config-file): `email-max-recipients-per-second` + +The maximum number of recipients, summed across emails, that can be sent per second. + Note that the final email sent before reaching the limit is able to exceed it, if it has multiple recipients. + +### `MB_EMAIL_REPLY_TO` + +- Type: json +- Default: `null` +- [Configuration file name](./config-file): `email-reply-to` + +The email address you want the replies to go to, if different from the from address. + +### `MB_EMAIL_SMTP_HOST` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `email-smtp-host` + +The address of the SMTP server that handles your emails. + +### `MB_EMAIL_SMTP_PASSWORD` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `email-smtp-password` + +SMTP password. + +### `MB_EMAIL_SMTP_PORT` + +- Type: integer +- Default: `null` +- [Configuration file name](./config-file): `email-smtp-port` + +The port your SMTP server uses for outgoing emails. + +### `MB_EMAIL_SMTP_SECURITY` + +- Type: keyword +- Default: `:none` +- [Configuration file name](./config-file): `email-smtp-security` + +SMTP secure connection protocol. (tls, ssl, starttls, or none). + +### `MB_EMAIL_SMTP_USERNAME` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `email-smtp-username` + +SMTP username. + +### `MB_EMBEDDING_APP_ORIGIN [DEPRECATED]` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +> DEPRECATED: 0.51.0 + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `embedding-app-origin` + +Allow this origin to embed the full Metabase application. + +### `MB_EMBEDDING_APP_ORIGINS_INTERACTIVE` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `embedding-app-origins-interactive` + +Allow these space delimited origins to embed Metabase interactive. + +### `MB_EMBEDDING_APP_ORIGINS_SDK` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `localhost:*` +- [Configuration file name](./config-file): `embedding-app-origins-sdk` + +Allow Metabase SDK access to these space delimited origins. + +### `MB_EMBEDDING_HOMEPAGE` + +- Type: keyword +- Default: `:hidden` +- [Exported as](../installation-and-operation/serialization): `embedding-homepage`. +- [Configuration file name](./config-file): `embedding-homepage` + +Embedding homepage status, indicating if it's visible, hidden or has been dismissed. + +### `MB_EMBEDDING_SECRET_KEY` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `embedding-secret-key` + +Secret key used to sign JSON Web Tokens for requests to `/api/embed` endpoints. + +### `MB_ENABLE_EMBEDDING [DEPRECATED]` + +> DEPRECATED: 0.51.0 + +- Type: boolean +- Default: `false` +- [Exported as](../installation-and-operation/serialization): `enable-embedding`. +- [Configuration file name](./config-file): `enable-embedding` + +Allow admins to securely embed questions and dashboards within other applications? + +### `MB_ENABLE_EMBEDDING_INTERACTIVE` + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `enable-embedding-interactive` + +Allow admins to embed Metabase via interactive embedding? + +### `MB_ENABLE_EMBEDDING_SDK` + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `enable-embedding-sdk` + +Allow admins to embed Metabase via the SDK? + +### `MB_ENABLE_EMBEDDING_STATIC` + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `enable-embedding-static` + +Allow admins to embed Metabase via static embedding? + +### `MB_ENABLE_FIELD_USAGE_ANALYSIS` + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `enable-field-usage-analysis` + +Enable field usage analysis for queries. This will analyze the fields used in queries and store them in the + application database. + + Turn off by default since we haven't had an user-facing feature that uses this data yet. + +### `MB_ENABLE_PASSWORD_LOGIN` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: boolean +- Default: `true` +- [Configuration file name](./config-file): `enable-password-login` + +Allow logging in by email and password. + +### `MB_ENABLE_PIVOTED_EXPORTS` + +- Type: boolean +- Default: `true` +- [Exported as](../installation-and-operation/serialization): `enable-pivoted-exports`. +- [Configuration file name](./config-file): `enable-pivoted-exports` + +Enable pivoted exports and pivoted subscriptions. + +### `MB_ENABLE_PUBLIC_SHARING` + +- Type: boolean +- Default: `true` +- [Configuration file name](./config-file): `enable-public-sharing` + +Enable admins to create publicly viewable links (and embeddable iframes) for Questions and Dashboards? + +### `MB_ENABLE_QUERY_CACHING` + +- Type: boolean +- Default: `true` +- [Configuration file name](./config-file): `enable-query-caching` + +Allow caching results of queries that take a long time to run. + +### `MB_ENABLE_XRAYS` + +- Type: boolean +- Default: `true` +- [Exported as](../installation-and-operation/serialization): `enable-xrays`. +- [Configuration file name](./config-file): `enable-xrays` + +Allow users to explore data using X-rays. + +### `MB_FOLLOW_UP_EMAIL_SENT` + +- Type: boolean +- Default: `false` + +Have we sent a follow up email to the instance admin? + +### `MB_GOOGLE_AUTH_AUTO_CREATE_ACCOUNTS_DOMAIN` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `google-auth-auto-create-accounts-domain` + +When set, allow users to sign up on their own if their Google account email address is from this domain. + +### `MB_GOOGLE_AUTH_CLIENT_ID` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `google-auth-client-id` + +Client ID for Google Sign-In. + +### `MB_GOOGLE_AUTH_ENABLED` + +- Type: boolean +- Default: `null` +- [Configuration file name](./config-file): `google-auth-enabled` + +Is Google Sign-in currently enabled? + +### `MB_GSHEETS` + +- Type: json +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `gsheets`. +- [Configuration file name](./config-file): `gsheets` + +Information about Google Sheets Integration. + +### `MB_HEALTH_CHECK_LOGGING_ENABLED` + +- Type: boolean +- Default: `true` + +Whether to log health check requests from session middleware. + +### `MB_HELP_LINK` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: keyword +- Default: `:metabase` +- [Configuration file name](./config-file): `help-link` + +Keyword setting to control whitelabeling of the help link. Valid values are `:metabase`, `:hidden`, and `:custom`. If `:custom` is set, the help link will use the URL specified in the `help-link-custom-destination`, or be hidden if it is not set. + +### `MB_HELP_LINK_CUSTOM_DESTINATION` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `https://www.metabase.com/help/premium` +- [Configuration file name](./config-file): `help-link-custom-destination` + +Custom URL for the help link. + +### `MB_HUMANIZATION_STRATEGY` + +- Type: keyword +- Default: `:simple` +- [Exported as](../installation-and-operation/serialization): `humanization-strategy`. +- [Configuration file name](./config-file): `humanization-strategy` + +To make table and field names more human-friendly, Metabase will replace dashes and underscores in them with spaces. We’ll capitalize each word while at it, so ‘last_visited_at’ will become ‘Last Visited At’. + +### `MB_JDBC_DATA_WAREHOUSE_MAX_CONNECTION_POOL_SIZE` + +- Type: integer +- Default: `15` + +Maximum size of the c3p0 connection pool. + +Change this to a higher value if you notice that regular usage consumes all or close to all connections. + +When all connections are in use then Metabase will be slower to return results for queries, since it would have to wait for an available connection before processing the next query in the queue. + +For setting the maximum, see [MB_APPLICATION_DB_MAX_CONNECTION_POOL_SIZE](#mb_application_db_max_connection_pool_size). + +### `MB_JWT_ATTRIBUTE_EMAIL` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `email` +- [Configuration file name](./config-file): `jwt-attribute-email` + +Key to retrieve the JWT user's email address. + +### `MB_JWT_ATTRIBUTE_FIRSTNAME` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `first_name` +- [Configuration file name](./config-file): `jwt-attribute-firstname` + +Key to retrieve the JWT user's first name. + +### `MB_JWT_ATTRIBUTE_GROUPS` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `groups` +- [Configuration file name](./config-file): `jwt-attribute-groups` + +Key to retrieve the JWT user's groups. + +### `MB_JWT_ATTRIBUTE_LASTNAME` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `last_name` +- [Configuration file name](./config-file): `jwt-attribute-lastname` + +Key to retrieve the JWT user's last name. + +### `MB_JWT_ENABLED` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `jwt-enabled` + +Is JWT authentication configured and enabled? + +When set to true, will enable JWT authentication with the options configured in the MB_JWT_* variables. + This is for JWT SSO authentication, and has nothing to do with Static embedding, which is MB_EMBEDDING_SECRET_KEY. + +### `MB_JWT_GROUP_MAPPINGS` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: json +- Default: `{}` +- [Configuration file name](./config-file): `jwt-group-mappings` + +JSON containing JWT to Metabase group mappings. + +JSON object containing JWT to Metabase group mappings, where keys are JWT groups and values are lists of Metabase groups IDs. + +### `MB_JWT_GROUP_SYNC` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `jwt-group-sync` + +Enable group membership synchronization with JWT. + +### `MB_JWT_IDENTITY_PROVIDER_URI` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `jwt-identity-provider-uri` + +URL for JWT-based login page. Optional if using JWT SSO only with the embedded analytics SDK. + +### `MB_JWT_SHARED_SECRET` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `jwt-shared-secret` + +String used to seed the private key used to validate JWT messages. A hexadecimal-encoded 256-bit key (i.e., a 64-character string) is strongly recommended. + +### `MB_JWT_USER_PROVISIONING_ENABLED` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: boolean +- Default: `true` +- [Configuration file name](./config-file): `jwt-user-provisioning-enabled` + +When we enable JWT user provisioning, we automatically create a Metabase account on JWT signin for users who +don't have one. + +### `MB_LANDING_PAGE` + +- Type: string +- Default: `` +- [Exported as](../installation-and-operation/serialization): `landing-page`. +- [Configuration file name](./config-file): `landing-page` + +Enter a URL of the landing page to show the user. This overrides the custom homepage setting above. + +### `MB_LANDING_PAGE_ILLUSTRATION` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `default` +- [Exported as](../installation-and-operation/serialization): `landing-page-illustration`. +- [Configuration file name](./config-file): `landing-page-illustration` + +Options for displaying the illustration on the landing page. + +### `MB_LANDING_PAGE_ILLUSTRATION_CUSTOM` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `landing-page-illustration-custom`. +- [Configuration file name](./config-file): `landing-page-illustration-custom` + +The custom illustration for the landing page. + +### `MB_LDAP_ATTRIBUTE_EMAIL` + +- Type: string +- Default: `mail` +- [Configuration file name](./config-file): `ldap-attribute-email` + +Attribute to use for the user's email. (usually 'mail', 'email' or 'userPrincipalName'). + +### `MB_LDAP_ATTRIBUTE_FIRSTNAME` + +- Type: string +- Default: `givenName` +- [Configuration file name](./config-file): `ldap-attribute-firstname` + +Attribute to use for the user's first name. (usually 'givenName'). + +### `MB_LDAP_ATTRIBUTE_LASTNAME` + +- Type: string +- Default: `sn` +- [Configuration file name](./config-file): `ldap-attribute-lastname` + +Attribute to use for the user's last name. (usually 'sn'). + +### `MB_LDAP_BIND_DN` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `ldap-bind-dn` + +The Distinguished Name to bind as (if any), this user will be used to lookup information about other users. + +### `MB_LDAP_ENABLED` + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `ldap-enabled` + +Is LDAP currently enabled? + +### `MB_LDAP_GROUP_BASE` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `ldap-group-base` + +Search base for groups. Not required for LDAP directories that provide a 'memberOf' overlay, such as Active Directory. (Will be searched recursively). + +### `MB_LDAP_GROUP_MAPPINGS` + +- Type: json +- Default: `{}` +- [Configuration file name](./config-file): `ldap-group-mappings` + +JSON containing LDAP to Metabase group mappings. + +### `MB_LDAP_GROUP_MEMBERSHIP_FILTER` + +- Type: string +- Default: `(member={dn})` +- [Configuration file name](./config-file): `ldap-group-membership-filter` + +Group membership lookup filter. The placeholders {dn} and {uid} will be replaced by the user's Distinguished Name and UID, respectively. + +### `MB_LDAP_GROUP_SYNC` + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `ldap-group-sync` + +Enable group membership synchronization with LDAP. + +### `MB_LDAP_HOST` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `ldap-host` + +Server hostname. + +### `MB_LDAP_PASSWORD` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `ldap-password` + +The password to bind with for the lookup user. + +### `MB_LDAP_PORT` + +- Type: integer +- Default: `389` +- [Configuration file name](./config-file): `ldap-port` + +Server port, usually 389 or 636 if SSL is used. + +### `MB_LDAP_SECURITY` + +- Type: keyword +- Default: `:none` +- [Configuration file name](./config-file): `ldap-security` + +Use SSL, TLS or plain text. + +### `MB_LDAP_SYNC_USER_ATTRIBUTES` + +- Type: boolean +- Default: `true` +- [Configuration file name](./config-file): `ldap-sync-user-attributes` + +Should we sync user attributes when someone logs in via LDAP? + +### `MB_LDAP_SYNC_USER_ATTRIBUTES_BLACKLIST` + +- Type: csv +- Default: `userPassword,dn,distinguishedName` +- [Configuration file name](./config-file): `ldap-sync-user-attributes-blacklist` + +Comma-separated list of user attributes to skip syncing for LDAP users. + +### `MB_LDAP_USER_BASE` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `ldap-user-base` + +Search base for users. (Will be searched recursively). + +### `MB_LDAP_USER_FILTER` + +- Type: string +- Default: `(&(objectClass=inetOrgPerson)(|(uid={login})(mail={login})))` +- [Configuration file name](./config-file): `ldap-user-filter` + +User lookup filter. The placeholder '{login}' will be replaced by the user supplied login. + +### `MB_LDAP_USER_PROVISIONING_ENABLED` + +- Type: boolean +- Default: `true` +- [Configuration file name](./config-file): `ldap-user-provisioning-enabled` + +When we enable LDAP user provisioning, we automatically create a Metabase account on LDAP signin for users who +don't have one. + +### `MB_LOADING_MESSAGE` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: keyword +- Default: `:doing-science` +- [Exported as](../installation-and-operation/serialization): `loading-message`. +- [Configuration file name](./config-file): `loading-message` + +Choose the message to show while a query is running. Possible values are "doing-science", "running-query", or "loading-results". + +### `MB_LOGIN_PAGE_ILLUSTRATION` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `default` +- [Exported as](../installation-and-operation/serialization): `login-page-illustration`. +- [Configuration file name](./config-file): `login-page-illustration` + +Options for displaying the illustration on the login page. + +### `MB_LOGIN_PAGE_ILLUSTRATION_CUSTOM` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `login-page-illustration-custom`. +- [Configuration file name](./config-file): `login-page-illustration-custom` + +The custom illustration for the login page. + +### `MB_MAP_TILE_SERVER_URL` + +- Type: string +- Default: `https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png` +- [Configuration file name](./config-file): `map-tile-server-url` + +The map tile server URL template used in map visualizations, for example from OpenStreetMaps or MapBox. + +### `MB_NATIVE_QUERY_AUTOCOMPLETE_MATCH_STYLE` + +- Type: keyword +- Default: `:substring` +- [Exported as](../installation-and-operation/serialization): `native-query-autocomplete-match-style`. +- [Configuration file name](./config-file): `native-query-autocomplete-match-style` + +Matching style for native query editor's autocomplete. Can be "substring", "prefix", or "off". Larger instances can have performance issues matching using substring, so can use prefix matching, or turn autocompletions off. + +### `MB_NESTED_FIELD_COLUMNS_VALUE_LENGTH_LIMIT` + +- Type: integer +- Default: `50000` +- [Exported as](../installation-and-operation/serialization): `nested-field-columns-value-length-limit`. + +Maximum length of a JSON string before skipping it during sync for JSON unfolding. If this is set too high it could lead to slow syncs or out of memory errors. + +### `MB_NO_DATA_ILLUSTRATION` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `default` +- [Exported as](../installation-and-operation/serialization): `no-data-illustration`. +- [Configuration file name](./config-file): `no-data-illustration` + +Options for displaying the illustration when there are no results after running a question. + +### `MB_NO_DATA_ILLUSTRATION_CUSTOM` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `no-data-illustration-custom`. +- [Configuration file name](./config-file): `no-data-illustration-custom` + +The custom illustration for when there are no results after running a question. + +### `MB_NO_OBJECT_ILLUSTRATION` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `default` +- [Exported as](../installation-and-operation/serialization): `no-object-illustration`. +- [Configuration file name](./config-file): `no-object-illustration` + +Options for displaying the illustration when there are no results after searching. + +### `MB_NO_OBJECT_ILLUSTRATION_CUSTOM` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `no-object-illustration-custom`. +- [Configuration file name](./config-file): `no-object-illustration-custom` + +The custom illustration for when there are no results after searching. + +### `MB_NOT_BEHIND_PROXY` + +- Type: boolean +- Default: `false` + +Indicates whether Metabase is running behind a proxy that sets the source-address-header for incoming requests. + +### `MB_NOTIFICATION_LINK_BASE_URL` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` + +By default "Site Url" is used in notification links, but can be overridden. + +The base URL where dashboard notitification links will point to instead of the Metabase base URL. + Only applicable for users who utilize interactive embedding and subscriptions. + +### `MB_NOTIFICATION_THREAD_POOL_SIZE` + +- Type: integer +- Default: `3` + +The size of the thread pool used to send notifications. + +### `MB_PERSISTED_MODEL_REFRESH_CRON_SCHEDULE` + +- Type: string +- Default: `0 0 0/6 * * ? *` +- [Configuration file name](./config-file): `persisted-model-refresh-cron-schedule` + +cron syntax string to schedule refreshing persisted models. + +### `MB_PERSISTED_MODELS_ENABLED` + +- Type: boolean +- Default: `false` +- [Exported as](../installation-and-operation/serialization): `persisted-models-enabled`. +- [Configuration file name](./config-file): `persisted-models-enabled` + +Allow persisting models into the source database. + +### `MB_PREMIUM_EMBEDDING_TOKEN` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `premium-embedding-token` + +Token for premium features. Go to the MetaStore to get yours! + +### `MB_QUERY_ANALYSIS_ENABLED` + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `query-analysis-enabled` + +Whether or not we analyze any queries at all. + +### `MB_QUERY_CACHING_MAX_KB` + +- Type: integer +- Default: `2000` +- [Configuration file name](./config-file): `query-caching-max-kb` + +The maximum size of the cache, per saved question, in kilobytes. + +### `MB_QUERY_CACHING_MAX_TTL` + +- Type: double +- Default: `3024000.0` +- [Configuration file name](./config-file): `query-caching-max-ttl` + +The absolute maximum time to keep any cached query results, in seconds. + +### `MB_REDIRECT_ALL_REQUESTS_TO_HTTPS` + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `redirect-all-requests-to-https` + +Force all traffic to use HTTPS via a redirect, if the site URL is HTTPS. + +### `MB_REPORT_TIMEZONE` + +- Type: string +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `report-timezone`. +- [Configuration file name](./config-file): `report-timezone` + +Connection timezone to use when executing queries. Defaults to system timezone. + +### `MB_RESET_TOKEN_TTL_HOURS` + +- Type: integer +- Default: `48` + +Number of hours a password reset is considered valid. + +### `MB_RETRY_INITIAL_INTERVAL` + +- Type: integer +- Default: `500` +- [Configuration file name](./config-file): `retry-initial-interval` + +The initial retry delay in milliseconds. + +### `MB_RETRY_MAX_ATTEMPTS` + +- Type: integer +- Default: `7` +- [Configuration file name](./config-file): `retry-max-attempts` + +The maximum number of attempts for an event. + +### `MB_RETRY_MAX_INTERVAL_MILLIS` + +- Type: integer +- Default: `30000` +- [Configuration file name](./config-file): `retry-max-interval-millis` + +The maximum delay between attempts. + +### `MB_RETRY_MULTIPLIER` + +- Type: double +- Default: `2.0` +- [Configuration file name](./config-file): `retry-multiplier` + +The delay multiplier between attempts. + +### `MB_RETRY_RANDOMIZATION_FACTOR` + +- Type: double +- Default: `0.1` +- [Configuration file name](./config-file): `retry-randomization-factor` + +The randomization factor of the retry delay. + +### `MB_SAML_APPLICATION_NAME` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `Metabase` +- [Configuration file name](./config-file): `saml-application-name` + +This application name will be used for requests to the Identity Provider. + +### `MB_SAML_ATTRIBUTE_EMAIL` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` +- [Configuration file name](./config-file): `saml-attribute-email` + +SAML attribute for the user's email address. + +### `MB_SAML_ATTRIBUTE_FIRSTNAME` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname` +- [Configuration file name](./config-file): `saml-attribute-firstname` + +SAML attribute for the user's first name. + +### `MB_SAML_ATTRIBUTE_GROUP` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `member_of` +- [Configuration file name](./config-file): `saml-attribute-group` + +SAML attribute for group syncing. + +### `MB_SAML_ATTRIBUTE_LASTNAME` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname` +- [Configuration file name](./config-file): `saml-attribute-lastname` + +SAML attribute for the user's last name. + +### `MB_SAML_ENABLED` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `saml-enabled` + +Is SAML authentication configured and enabled? + +### `MB_SAML_GROUP_MAPPINGS` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: json +- Default: `{}` +- [Configuration file name](./config-file): `saml-group-mappings` + +JSON containing SAML to Metabase group mappings. + +### `MB_SAML_GROUP_SYNC` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `saml-group-sync` + +Enable group membership synchronization with SAML. + +### `MB_SAML_IDENTITY_PROVIDER_CERTIFICATE` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `saml-identity-provider-certificate` + +Encoded certificate for the identity provider. Depending on your IdP, you might need to download this, +open it in a text editor, then copy and paste the certificate's contents here. + +### `MB_SAML_IDENTITY_PROVIDER_ISSUER` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `saml-identity-provider-issuer` + +This is a unique identifier for the IdP. Often referred to as Entity ID or simply 'Issuer'. Depending +on your IdP, this usually looks something like `http://www.example.com/141xkex604w0Q5PN724v`. + +### `MB_SAML_IDENTITY_PROVIDER_SLO_URI` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `saml-identity-provider-slo-uri` + +This is the URL where your users go to logout of your identity provider. Depending on which IdP you're +using, this usually looks like `https://your-org-name.example.com` or `https://example.com/app/my_saml_app/abc123/sso/slo`. + +### `MB_SAML_IDENTITY_PROVIDER_URI` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `saml-identity-provider-uri` + +This is the URL where your users go to log in to your identity provider. Depending on which IdP you're +using, this usually looks like `https://your-org-name.example.com` or `https://example.com/app/my_saml_app/abc123/sso/saml`. + +### `MB_SAML_KEYSTORE_ALIAS` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `metabase` +- [Configuration file name](./config-file): `saml-keystore-alias` + +Alias for the key that Metabase should use for signing SAML requests. + +### `MB_SAML_KEYSTORE_PASSWORD` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `changeit` +- [Configuration file name](./config-file): `saml-keystore-password` + +Password for opening the keystore. + +### `MB_SAML_KEYSTORE_PATH` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `saml-keystore-path` + +Absolute path to the Keystore file to use for signing SAML requests. + +### `MB_SAML_SLO_ENABLED` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: boolean +- Default: `false` +- [Configuration file name](./config-file): `saml-slo-enabled` + +Is SAML Single Log Out enabled? + +### `MB_SAML_USER_PROVISIONING_ENABLED` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: boolean +- Default: `true` +- [Configuration file name](./config-file): `saml-user-provisioning-enabled` + +When we enable SAML user provisioning, we automatically create a Metabase account on SAML signin for users who +don't have one. + +### `MB_SCIM_ENABLED` + +- Type: boolean +- Default: `null` +- [Configuration file name](./config-file): `scim-enabled` + +Is SCIM currently enabled? + +### `MB_SEARCH_ENGINE` + +- Type: keyword +- Default: `:appdb` + +Which engine to use when performing search. Supported values are :in-place and :appdb. + +### `MB_SEARCH_TYPEAHEAD_ENABLED` + +- Type: boolean +- Default: `true` +- [Exported as](../installation-and-operation/serialization): `search-typeahead-enabled`. +- [Configuration file name](./config-file): `search-typeahead-enabled` + +Enable typeahead search in the Metabase navbar? + +### `MB_SEND_NEW_SSO_USER_ADMIN_EMAIL` + +- Type: boolean +- Default: `null` +- [Configuration file name](./config-file): `send-new-sso-user-admin-email` + +Should new email notifications be sent to admins, for all new SSO users? + +### `MB_SESSION_COOKIE_SAMESITE` + +- Type: keyword +- Default: `:lax` +- [Configuration file name](./config-file): `session-cookie-samesite` + +Value for the session cookie's `SameSite` directive. + +See [Embedding Metabase in a different domain](../embedding/interactive-embedding#embedding-metabase-in-a-different-domain). + Read more about [interactive Embedding](../embedding/interactive-embedding). + Learn more about [SameSite cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite). + +### `MB_SESSION_COOKIES` + +- Type: boolean +- Default: `null` +- [Configuration file name](./config-file): `session-cookies` + +When set, enforces the use of session cookies for all users which expire when the browser is closed. + +The user login session will always expire after the amount of time defined in MAX_SESSION_AGE (by default 2 weeks). + This overrides the “Remember me” checkbox when logging in. + Also see the Changing session expiration documentation page. + +### `MB_SESSION_TIMEOUT` + +- Type: json +- Default: `null` +- [Configuration file name](./config-file): `session-timeout` + +Time before inactive users are logged out. By default, sessions last indefinitely. + +Has to be in the JSON format `"{"amount":120,"unit":"minutes"}"` where the unit is one of "seconds", "minutes" or "hours". + +### `MB_SETUP_EMBEDDING_AUTOENABLED` + +- Type: boolean +- Default: `false` +- [Exported as](../installation-and-operation/serialization): `setup-embedding-autoenabled`. +- [Configuration file name](./config-file): `setup-embedding-autoenabled` + +Indicates if embedding has enabled automatically during the setup because the user was interested in embedding. + +### `MB_SETUP_LICENSE_ACTIVE_AT_SETUP` + +- Type: boolean +- Default: `false` +- [Exported as](../installation-and-operation/serialization): `setup-license-active-at-setup`. +- [Configuration file name](./config-file): `setup-license-active-at-setup` + +Indicates if at the end of the setup a valid license was active. + +### `MB_SHOW_DATABASE_SYNCING_MODAL` + +- Type: boolean +- Default: `null` +- [Configuration file name](./config-file): `show-database-syncing-modal` + +Whether an introductory modal should be shown after the next database connection is added. Defaults to false if any non-default database has already finished syncing for this instance. + +### `MB_SHOW_HOMEPAGE_DATA` + +- Type: boolean +- Default: `true` +- [Exported as](../installation-and-operation/serialization): `show-homepage-data`. +- [Configuration file name](./config-file): `show-homepage-data` + +Whether or not to display data on the homepage. Admins might turn this off in order to direct users to better content than raw data. + +### `MB_SHOW_HOMEPAGE_XRAYS` + +- Type: boolean +- Default: `true` +- [Exported as](../installation-and-operation/serialization): `show-homepage-xrays`. +- [Configuration file name](./config-file): `show-homepage-xrays` + +Whether or not to display x-ray suggestions on the homepage. They will also be hidden if any dashboards are pinned. Admins might hide this to direct users to better content than raw data. + +### `MB_SHOW_METABASE_LINKS` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: boolean +- Default: `true` +- [Configuration file name](./config-file): `show-metabase-links` + +Whether or not to display Metabase links outside admin settings. + +### `MB_SHOW_METABOT` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: boolean +- Default: `true` +- [Exported as](../installation-and-operation/serialization): `show-metabot`. +- [Configuration file name](./config-file): `show-metabot` + +Enables Metabot character on the home page. + +### `MB_SHOW_STATIC_EMBED_TERMS` + +- Type: boolean +- Default: `true` +- [Exported as](../installation-and-operation/serialization): `show-static-embed-terms`. +- [Configuration file name](./config-file): `show-static-embed-terms` + +Check if the static embedding licensing should be hidden in the static embedding flow. + +### `MB_SITE_LOCALE` + +- Type: string +- Default: `en` +- [Exported as](../installation-and-operation/serialization): `site-locale`. +- [Configuration file name](./config-file): `site-locale` + +The default language for all users across the Metabase UI, system emails, pulses, and alerts. Users can individually override this default language from their own account settings. + +### `MB_SITE_NAME` + +- Type: string +- Default: `Metabase` +- [Exported as](../installation-and-operation/serialization): `site-name`. +- [Configuration file name](./config-file): `site-name` + +The name used for this instance of Metabase. + +### `MB_SITE_URL` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `site-url` + +This URL is used for things like creating links in emails, auth redirects, and in some embedding scenarios, so changing it could break functionality or get you locked out of this instance. + +This URL is critical for things like SSO authentication, email links, embedding and more. + Even difference with `http://` vs `https://` can cause problems. + Make sure that the address defined is how Metabase is being accessed. + +### `MB_SLACK_APP_TOKEN` + +- Type: string +- Default: `null` +- [Configuration file name](./config-file): `slack-app-token` + +Bot user OAuth token for connecting the Metabase Slack app. This should be used for all new Slack integrations starting in Metabase v0.42.0. + +### `MB_SLACK_BUG_REPORT_CHANNEL` + +- Type: string +- Default: `metabase-bugs` +- [Configuration file name](./config-file): `slack-bug-report-channel` + +The name of the channel where bug reports should be posted. + +### `MB_SLACK_FILES_CHANNEL [DEPRECATED]` + +> DEPRECATED: 0.54.0 + +- Type: string +- Default: `metabase_files` +- [Configuration file name](./config-file): `slack-files-channel` + +The name of the channel to which Metabase files should be initially uploaded. + +### `MB_SOURCE_ADDRESS_HEADER` + +- Type: string +- Default: `X-Forwarded-For` +- [Exported as](../installation-and-operation/serialization): `source-address-header`. +- [Configuration file name](./config-file): `source-address-header` + +Identify the source of HTTP requests by this header's value, instead of its remote address. + +### `MB_SQL_JDBC_FETCH_SIZE` + +- Type: integer +- Default: `500` + +Fetch size for result sets. We want to ensure that the jdbc ResultSet objects are not realizing the entire results + in memory. + +### `MB_SQL_PARSING_ENABLED` + +- Type: boolean +- Default: `true` + +SQL Parsing is disabled. + +### `MB_SSH_HEARTBEAT_INTERVAL_SEC` + +- Type: integer +- Default: `180` +- [Configuration file name](./config-file): `ssh-heartbeat-interval-sec` + +Controls how often the heartbeats are sent when an SSH tunnel is established (in seconds). + +### `MB_START_OF_WEEK` + +- Type: keyword +- Default: `:sunday` +- [Exported as](../installation-and-operation/serialization): `start-of-week`. +- [Configuration file name](./config-file): `start-of-week` + +This will affect things like grouping by week or filtering in GUI queries. It won't affect most SQL queries, although it is used to set the WEEK_START session variable in Snowflake. + +### `MB_SUBSCRIPTION_ALLOWED_DOMAINS` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: string +- Default: `null` +- [Exported as](../installation-and-operation/serialization): `subscription-allowed-domains`. +- [Configuration file name](./config-file): `subscription-allowed-domains` + +Allowed email address domain(s) for new Dashboard Subscriptions and Alerts. To specify multiple domains, separate each domain with a comma, with no space in between. To allow all domains, leave the field empty. This setting doesn’t affect existing subscriptions. + +### `MB_SURVEYS_ENABLED` + +- Type: boolean +- Default: `true` + +Enable or disable surveys. + +### `MB_SYNCHRONOUS_BATCH_UPDATES` + +- Type: boolean +- Default: `false` +- [Exported as](../installation-and-operation/serialization): `synchronous-batch-updates`. +- [Configuration file name](./config-file): `synchronous-batch-updates` + +Process batches updates synchronously. If true, all `submit!` calls will be processed immediately. Default is false. + +### `MB_UNAGGREGATED_QUERY_ROW_LIMIT` + +- Type: integer +- Default: `2000` +- [Exported as](../installation-and-operation/serialization): `unaggregated-query-row-limit`. +- [Configuration file name](./config-file): `unaggregated-query-row-limit` + +Maximum number of rows to return specifically on :rows type queries via the API. + +Must be less than 1048575, and less than the number configured in MB_AGGREGATED_QUERY_ROW_LIMIT. See also MB_AGGREGATED_QUERY_ROW_LIMIT. + +### `MB_UPDATE_CHANNEL` + +- Type: string +- Default: `latest` +- [Exported as](../installation-and-operation/serialization): `update-channel`. +- [Configuration file name](./config-file): `update-channel` + +We'll notify you here when there's a new version of this type of release. + +### `MB_UPLOADS_DATABASE_ID [DEPRECATED]` + +> DEPRECATED: 0.50.0 + +- Type: integer +- Default: `null` + +Database ID for uploads. + +### `MB_UPLOADS_ENABLED [DEPRECATED]` + +> DEPRECATED: 0.50.0 + +- Type: boolean +- Default: `false` + +Whether or not uploads are enabled. + +### `MB_UPLOADS_SCHEMA_NAME [DEPRECATED]` + +> DEPRECATED: 0.50.0 + +- Type: string +- Default: `null` + +Schema name for uploads. + +### `MB_UPLOADS_SETTINGS` + +- Type: json +- Default: `null` +- [Configuration file name](./config-file): `uploads-settings` + +Upload settings. + +### `MB_UPLOADS_TABLE_PREFIX [DEPRECATED]` + +> DEPRECATED: 0.50.0 + +- Type: string +- Default: `null` + +Prefix for upload table names. + +### `MB_USER_VISIBILITY` + +> Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +- Type: keyword +- Default: `:all` +- [Configuration file name](./config-file): `user-visibility` + +Note: Sandboxed users will never see suggestions. + +## Other environment variables + +The following environment variables can only be set via the environment. They cannot be set by the configuration file. + +### `MAX_SESSION_AGE` + +Type: integer
+Default: `20160` + +Session expiration, defined in minutes (default is 2 weeks), which will log out users after the defined period and require re-authentication. + +Note: This setting is not an idle/inactivity timeout. If you set this to 15 minutes, your users have to login (or re-authenticate) again every 15 minutes. Use [MB_SESSION_TIMEOUT](#mb_session_timeout) to control timeout based on inactivity. + +Use [MB_SESSION_COOKIES](#mb_session_cookies) to also expire sessions, when browser is closed. + +Also see the [Changing session expiration](../people-and-groups/changing-session-expiration) documentation page. + +### `MB_APPLICATION_DB_MAX_CONNECTION_POOL_SIZE` + +Type: integer
+Default: `15`
+Since: v35.0 + +Maximum number of connections to the Metabase application database. + +Change this to a higher value if you notice that regular usage consumes all or close to all connections. When all connections are in use, Metabase might feel slow or unresponsive when clicking around the interface. + +To see how many connections are being used, check the Metabase logs and look for lines that contains the following: `… App DB connections: 12/15 …`. In this example, 12 out of 15 available connections are being used. + +See [MB_JDBC_DATA_WAREHOUSE_MAX_CONNECTION_POOL_SIZE](#mb_jdbc_data_warehouse_max_connection_pool_size) for setting maximum connections to the databases connected to Metabase. + +### `MB_ASYNC_QUERY_THREAD_POOL_SIZE` + +Type: integer
+Default: `50`
+Since: v35.0 + +Maximum number of async Jetty threads. If not set, then [MB_JETTY_MAXTHREADS](#mb_jetty_maxthreads) will be used, otherwise it will use the default. + +### `MB_ATTACHMENT_TABLE_ROW_LIMIT` + +Type: integer
+Default: `20`
+ +Limits the number of rows Metabase will display in tables sent with dashboard subscriptions and alerts. Range: 1-100. To limit the total number of rows included in the file attachment for an email dashboard subscription, use [MB_UNAGGREGATED_QUERY_ROW_LIMIT](#mb_unaggregated_query_row_limit). + +### `MB_AUDIT_MAX_RETENTION_DAYS` + +Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans.
+Type: integer
+Default: 720 (Metabase keeps all rows)
+ +Sets the maximum number of days Metabase preserves rows for the following application database tables: + +- `query_execution` +- `audit_log` +- `view_log` + +Twice a day, Metabase will delete rows older than this threshold. + +The minimum value is `30` days (Metabase will treat entered values of `1` to `29` the same as `30`). If set to `0`, Metabase will keep all rows. + +### `MB_COLORIZE_LOGS` + +Type: boolean
+Default: `true` + +Color log lines. When set to `false` it will disable log line colors. This is disabled on Windows. Related to [MB_EMOJI_IN_LOGS](#mb_emoji_in_logs). + +### `MB_CONFIG_FILE_PATH` + +Type: string
+Default: `config.yml` + +This feature requires the `config-text-file` feature flag on your token. + +### `MB_DB_AUTOMIGRATE` + +Type: boolean
+Default: `true` + +When set to `false`, Metabase will print migrations needed to be done in the application database and exit. Those migrations need to be applied manually. When `true`, Metabase will automatically make changes to the application database. This is not related to migrating away from H2. + +### `MB_DB_CONNECTION_URI` + +Type: string
+Default: `null` + +A JDBC-style connection URI that can be used instead of most of `MB_DB_*` like [MB_DB_HOST](#mb_db_host). Also used when certain Connection String parameters are required for the connection. The connection type requirement is the same as [MB_DB_TYPE](#mb_db_type). + +Examples: + +``` +jdbc:postgresql://db.example.com:5432/mydb?user=dbuser&password=dbpassword + +jdbc:postgresql://db.example.com:5432/mydb?user=dbuser&password=dbpassword&ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory + +jdbc:mysql://db.example.com:3306/mydb?user=dbuser&password=dbpassword +``` + +### `MB_DB_DBNAME` + +Type: string
+Default: `null` + +The database name of the application database used with [MB_DB_HOST](#mb_db_host). + +### `MB_DB_FILE` + +Type: string
+Default: `"metabase.db"` + +Location of H2 database file. Should not include the `.mv.db` (or `.h2.db`) file extension. Used when [MB_DB_TYPE](#mb_db_type) is set to`"h2"`. + +Can also be used when migrating away from H2 to specify where the existing data should be read from. + +### `MB_DB_HOST` + +Type: string
+Default: `null` + +The host name or IP address of the application database. Used when [MB_DB_TYPE](#mb_db_type) is different than `"h2"`. + +### `MB_DB_IN_MEMORY` + +Type: boolean
+Default: `null` + +Used for testing with [MB_DB_FILE](#mb_db_file). + +### `MB_DB_PASS` + +Type: string
+Default: `null` + +The password for [MB_DB_HOST](#mb_db_host). + +### `MB_DB_PORT` + +Type: integer
+Default: `null` + +The port for [MB_DB_HOST](#mb_db_host). + +### `MB_DB_TYPE` + +Type: string (`"h2"`, `"postgres"`, `"mysql"`)
+Default: `"h2"` + +When `"h2"`, the application database is loaded from [MB_DB_FILE](#mb_db_file), otherwise [MB_DB_HOST](#mb_db_host) will be used to define application database. + +### `MB_DB_USER` + +Type: string
+Default: `null` + +The username for [MB_DB_HOST](#mb_db_host). + +### `MB_DEV_ADDITIONAL_DRIVER_MANIFEST_PATHS` + +Type: string
+Default: `null` + +Used during development of third-party drivers. Set the value to have that plugin manifest get loaded during startup. Specify multiple plugin manifests by comma-separating them. + +### `MB_DISABLE_SCHEDULER` + +Type: boolean
+Default: `false` + +When `true`, Metabase will turn off Metabase’s scheduled jobs, which include syncs, fingerprinting, and scanning, as well as dashboard subscriptions, alerts, and model caching. + +Can be useful for testing, or when setting up a [git-based workflow](/learn/metabase-basics/administration/administration-and-operation/git-based-workflow). + +### `MB_DISABLE_SESSION_THROTTLE` + +Type: boolean
+Default: `false` + +When `true`, this will disable session throttling. **Warning:** It is not recommended to disable throttling, since it is a protective measure against brute-force attacks. + +Use [MB_SOURCE_ADDRESS_HEADER](#mb_source_address_header) to set the IP address of the remote client from e.g. a reverse-proxy. + +### `MB_EMOJI_IN_LOGS` + +Type: boolean
+Default: `true` + +Emojis on log lines. When set to `false` it will disable log line emojis. This is disabled on Windows. Related to [MB_COLORIZE_LOGS](#mb_colorize_logs). + +### `MB_ENABLE_TEST_ENDPOINTS` + +Type: boolean
+Default: `null` + +When `true`, this will enable `/api/testing` endpoint. **Warning:** This should never be enabled in production system. + +### `MB_ENCRYPTION_SECRET_KEY` + +Type: string
+Default: `null` + +When set, this will encrypt database credentials stored in the application database. Requirement: minimum 16 characters base64-encoded string. + +Also see documentation page [Encrypting database details at rest](../databases/encrypting-details-at-rest). + +### `MB_JDBC_DATA_WAREHOUSE_UNRETURNED_CONNECTION_TIMEOUT_SECONDS` + +Type: integer
+Default: `1200`
+Since: v47.4 + +Metabase's query processor will normally kill connections when their queries time out, but in practice some connections can be severed and go undetected by Metabase, staying alive even after a query returns or times out. This environment variable tells Metabase how long to wait before killing connections if no response is received from the connection. + +This variable affects connections that are severed and undetected by Metabase (that is, in situations where Metabase never receives a connection closed signal and is treating an inactive connection as active). You may want to adjust this variable's value if your connection is unreliable or is a dynamic connections behind a SSH tunnel where the connection to the SSH tunnel host may stay active even after the connection from the SSH tunnel host to your database is severed. + +Unless set otherwise, the default production value for `metabase.query-processor.query-timeout-ms` is used which is 1,200,000 ms (i.e. 1,200 seconds or 20 minutes). + +### `MB_JDBC_DATA_WAREHOUSE_DEBUG_UNRETURNED_CONNECTION_STACK_TRACES` + +Type: boolean
+Default: `false`
+Since: v51.3 + +If `true`, log a stack trace for any connections killed due to exceeding the timeout specified in [MB_JDBC_DATA_WAREHOUSE_UNRETURNED_CONNECTION_TIMEOUT_SECONDS](#mb_jdbc_data_warehouse_unreturned_connection_timeout_seconds). + +In order to see the stack traces in the logs, you'll also need to update the com.mchange log level to "INFO" or higher via a custom log4j configuration. For configuring log levels, see [Metabase log configuration](./log-configuration). + +To set a timeout for how long Metabase should wait before it kills unreturned connections, see [MB_JDBC_DATA_WAREHOUSE_UNRETURNED_CONNECTION_TIMEOUT_SECONDS](#mb_jdbc_data_warehouse_unreturned_connection_timeout_seconds). + +### `MB_JETTY_ASYNC_RESPONSE_TIMEOUT` + +Type: integer
+Default: `600000`
+Since: v35.0 + +Timeout of Jetty async threads, defined in milliseconds. The default is 10 minutes. Very few things might reach that timeout, since they return some type of data before, but things like CSV downloads might. + +### `MB_JETTY_DAEMON` + +Type: boolean
+Default: `false` + +Use daemon threads. + +### `MB_JETTY_HOST` + +Type: string
+Default: `localhost` for JAR, `0.0.0.0` for Docker + +Configure a host either as a host name or IP address to identify a specific network interface on which to listen. If set to `"0.0.0.0"`, Metabase listens on all network interfaces. It will listen on the port specified in [MB_JETTY_PORT](#mb_jetty_port). + +### `MB_JETTY_JOIN` + +Type: boolean
+Default: `true` + +Blocks the thread until server ends. + +### `MB_JETTY_MAXIDLETIME` + +Type: integer
+Default: `200000` + +Maximum idle time for a connection, in milliseconds. + +### `MB_JETTY_MAXTHREADS` + +Type: integer
+Default: `50` + +Maximum number of threads. + +Change this to a higher value if you notice that regular usage consumes all or close to all threads. When all threads are in use Metabase might feel slow or unresponsive when clicking around the interface. + +To see how many threads are being used, check the Metabase logs and look for lines that contain the following: `… Jetty threads: 45/50 …`, which in this case would indicate 45 out of 50 available threads are being used. + +Related [MB_ASYNC_QUERY_THREAD_POOL_SIZE](#mb_async_query_thread_pool_size). + +### `MB_JETTY_MINTHREADS` + +Type: integer
+Default: `8` + +Minimum number of threads. + +### `MB_JETTY_PORT` + +Type: integer
+Default: `3000` + +Configure which port to use for HTTP. It will listen on the interface specified in [MB_JETTY_HOST](#mb_jetty_host). + +### `MB_JETTY_REQUEST_HEADER_SIZE` + +Type: integer
+Default: `8192`
+Since: v36.0 + +Maximum size of a request header, in bytes. Increase this value if you are experiencing errors like "Request Header Fields Too Large". + +### `MB_JETTY_SSL` + +Type: boolean
+Default: `null` + +When set to `true`, will enable HTTPS with the options configured in the `MB_JETTY_SSL_*` variables. + +Also see the [Customizing Jetty web server](customizing-jetty-webserver) documentation page. + +### `MB_JETTY_SSL_CLIENT_AUTH` + +Type: boolean
+Default: `null` + +Configure Java SSL client authentication. When set to `true`, client certificates are required and verified by the certificate authority in the TrustStore. + +### `MB_JETTY_SSL_KEYSTORE` + +Type: string
+Default: `null` + +Path to Java KeyStore file. + +### `MB_JETTY_SSL_KEYSTORE_PASSWORD` + +Type: string
+Default: `null` + +Password for Java KeyStore file. + +### `MB_JETTY_SSL_PORT` + +Type: integer
+Default: `null` + +Configure which port to use for HTTPS. It will listen on the interface specified in [MB_JETTY_HOST](#mb_jetty_host). + +### `MB_JETTY_SSL_TRUSTSTORE` + +Type: string
+Default: `null` + +Path to Java TrustStore file. + +### `MB_JETTY_SSL_TRUSTSTORE_PASSWORD` + +Type: string
+Default: `null` + +Password for Java TrustStore file. + +### `MB_LANDING_PAGE` + +Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans.
+Type: string
+Default: `""` + +Default page to show people when they log in. + +### `MB_LOAD_ANALYTICS_CONTENT` + +Type: Boolean
+Default: True + +If you want to exclude the [Metabase analytics](../usage-and-performance-tools/usage-analytics) collection, you can set `MB_LOAD_ANALYTICS_CONTENT=false`. Setting this environment variable to false can also come in handy when migrating environments, as it can simplify the migration process. + +### `MB_LOAD_SAMPLE_CONTENT` + +Type: Boolean
+Default: True + +Whether to include the Sample Database in your Metabase. To exclude the Sample Database, set `MB_LOAD_SAMPLE_CONTENT=false`. + +### `MB_NO_SURVEYS` + +Type: boolean
+Default: `false`
+ +Metabase will send a sentiment survey to people who create a number of questions and dashboards to gauge how well the product is doing with respect to making things easy for creators. + +Metabase will only send these emails to people who have in the past 2 months: + +- Created at least 10 questions total +- Created at least 2 SQL questions +- Created at least 1 dashboard + +If you're whitelabeling Metabase, these survey emails will only be sent to admins for that instance who meet that criteria. + +If you don't want Metabase to send these emails, set `MB_NO_SURVEYS=true`. + +### `MB_NS_TRACE` + +Type: string
+Default: `""` + +Comma-separated namespaces to trace. **WARNING:** Could log sensitive information like database passwords. + +### `MB_PASSWORD_COMPLEXITY` + +Type: string (`"weak"`, `"normal"`, `"strong"`)
+Default: `"normal"` + +Enforce a password complexity rule to increase security for regular logins. This only applies to new users or users that are changing their password. Related [MB_PASSWORD_LENGTH](#mb_password_length) + +- `weak` no character constraints +- `normal` at least 1 digit +- `strong` minimum 8 characters w/ 2 lowercase, 2 uppercase, 1 digit, and 1 special character + +### `MB_PASSWORD_LENGTH` + +Type: integer
+Default: `6` + +Set a minimum password length to increase security for regular logins. This only applies to new users or users that are changing their password. Uses the length of [MB_PASSWORD_COMPLEXITY](#mb_password_complexity) if not set. + +### `MB_PLUGINS_DIR` + +Type: string
+Default: `"plugins"` + +Path of the "plugins" directory, which is used to store the Metabase database drivers. The user who is running Metabase should have permission to write to the directory. When running the JAR, the default directory is `plugins`, created in the same location as the JAR file. When running Docker, the default directory is `/plugins`. + +The location is where custom third-party drivers should be added. Then Metabase will load the driver on startup, which can be verified in the log. + +### `MB_PREMIUM_EMBEDDING_TOKEN` + +Type: string
+Default: `null` + +The license token used for Pro and Enterprise to enable premium features on the Enterprise edition. It is also used for the deprecated "Premium Embedding" functionality on the OSS edition. + +### `MB_QP_CACHE_BACKEND` + +Type: string
+Default: `"db"` + +Current cache backend. Dynamically rebindable primarily for test purposes. + +### `MB_SEARCH_TYPEAHEAD_ENABLED` + +Type: boolean
+Default: `true`
+Since: v39.0 + +Show auto-suggestions when using the global search in the top navigation bar. + +### `MB_SEND_EMAIL_ON_FIRST_LOGIN_FROM_NEW_DEVICE` + +Type: boolean
+Default: `true`
+Since: v39.0 + +Send email notification to user, when they login from a new device. Set to `false` to stop sending "We've noticed a new login on your Metabase account" emails for all users. + +Also, this variable controls the geocoding service that Metabase uses to know the location from where your users logged in. Setting this variable to false also disables this reverse geocoding functionality. + +### `MB_SEND_NEW_SSO_USER_ADMIN_EMAIL` + +Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans.
+Type: boolean
+Default: `true` + +Send email notifications to users in Admin group, when a new SSO users is created on Metabase. + +### `MB_SETUP_TOKEN` + +Type: string
+Default: `null` + +An UUID token used to signify that an instance has permissions to create the initial User. This is created upon the first launch of Metabase, by the first instance; once used, it is cleared out, never to be used again. + +### `MB_SHOW_LIGHTHOUSE_ILLUSTRATION` + +Only available on Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise) plans.
+Type: boolean
+Default: `true`
+Since: v44.0 + +Display the lighthouse illustration on the home and login pages. + +### `MB_JETTY_SKIP_SNI` + +Type: string
+Default: `"true"`
+Since: v48.4 + +Setting `MB_JETTY_SKIP_SNI=true` (the default setting) turns off the Server Name Indication (SNI) checks in the Jetty web server. Normally you would leave this enabled. If, however, you're terminating the Transport Layer Security (TLS) connection on Metabase itself, and you're getting an error like `HTTP ERROR 400 Invalid SNI`, consider either setting `MB_JETTY_SKIP_SNI=false`, or use another SSL certificate that exactly matches the domain name of the server. + +### `MB_SOURCE_ADDRESS_HEADER` + +Type: string
+Default: `X-Forwarded-For` + +Identify the source of HTTP requests by this header's value, instead of its remote address. Related to [MB_DISABLE_SESSION_THROTTLE](#mb_disable_session_throttle). + +### `MB_SSL_CERTIFICATE_PUBLIC_KEY` + +Type: string
+Default: `null` + +Base-64 encoded public key for this sites SSL certificate. Specify this to enable HTTP Public Key Pinning. Using HPKP is no longer recommended. See http://mzl.la/1EnfqBf for more information. diff --git a/_docs/doc-update-detection/configuring-metabase/fonts.md b/_docs/doc-update-detection/configuring-metabase/fonts.md new file mode 100644 index 000000000..bcbe86cd6 --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/fonts.md @@ -0,0 +1,136 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: Fonts +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/fonts.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/fonts + - /docs/doc-update-detection/embedding/fonts +--- + +# Fonts + +{% include plans-blockquote.html feature="Customizable font" %} + +On Pro and Enterprise plans, you can customize the font Metabase uses (the default is [Lato](https://fonts.google.com/specimen/Lato)). You can choose from a curated set of Google Fonts that accommodate the regular, bold, and heavy font weights that Metabase relies on for its various UI elements. + +## Included fonts + +To change your Metabase font, click on the **gear** icon in the upper right of the screen and select **Admin settings** > **Settings** > **Appearance**. Under **Font**, select from a list of included fonts. + +- [Custom font](#custom-fonts) +- [Lato](https://fonts.google.com/specimen/Lato) +- [Lora](https://fonts.google.com/specimen/Lora) +- [Merriweather](https://fonts.google.com/specimen/Merriweather) +- [Montserrat](https://fonts.google.com/specimen/Montserrat) +- [Noto Sans](https://fonts.google.com/specimen/Noto+Sans) +- [Open Sans](https://fonts.google.com/specimen/Open+Sans) +- [Oswald](https://fonts.google.com/specimen/Oswald) +- [Playfair Display](https://fonts.google.com/specimen/Playfair+Display) +- [Poppins](https://fonts.google.com/specimen/Poppins) +- [PT Sans](https://fonts.google.com/specimen/PT+Sans) +- [PT Serif](https://fonts.google.com/specimen/PT+Serif) +- [Raleway](https://fonts.google.com/specimen/Raleway) +- [Roboto](https://fonts.google.com/specimen/Roboto) +- [Roboto Condensed](https://fonts.google.com/specimen/Roboto+Condensed) +- [Roboto Mono](https://fonts.google.com/specimen/Roboto+Mono) +- [Roboto Slab](https://fonts.google.com/specimen/Roboto+Slab) +- [Slabo 27px](https://fonts.google.com/specimen/Slabo+27px) +- Source Sans Pro +- [Ubuntu](https://fonts.google.com/specimen/Ubuntu) + +Comic Sans is currently not included. + +## Custom fonts + +To set a custom font, click on the **gear** icon in the upper right of the screen and select **Admin settings** > **Settings** > **Appearance**. + +For **Font**, select **Custom...** and enter URLs to your font files. + +## Font style options + +You can set three different font styles with three different URLs, one for each font style (size and weight) that Metabase will use in order to display its user interface properly. The font weights are: + +- Regular 400 +- Bold 700 +- Heavy 900 (sometimes called Black 900) + +You only need to set the first style (Regular 400); the browser will fill in the other styles. + +For best results, set at least the 400 and 700 styles. If you have a single font file that contains multiple font styles within the same family, enter the URL in multiple fields to tell Metabase to prefer the weights in that font file. Metabase will use those styles to override the font styles set by the browser. + +### Supported font file formats + +For custom fonts, Metabase supports woff, woff2, ttf files. If the URL you provide lacks a specific file extension, Metabase will assume it's a woff2 file. + +## Google Font URLs + +To get a URL for a [Google Font](https://fonts.google.com/), visit the Google Font page and select the style you want to use. Then make an HTTP request to get the URL of the tff file. For example, say we want to use Roboto Mono: here's how we could get the font file URLs for both the 400 and 700 styles: + +We'd paste the URL [https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&display=swap](https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&display=swap) into our browser's address bar. This URL will return a response like: + +```css +* cyrillic-ext */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v21/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSV0me8iUI0lkQ.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto Mono'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/robotomono/v21/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSx0me8iUI0lkQ.woff2) format('woff2'); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +... +``` + +For latin text, we'd copy the relevant src URLs for each style, in this case: + +- For 400: [https://fonts.gstatic.com/s/robotomono/v21/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSh0me8iUI0.woff2](https://fonts.gstatic.com/s/robotomono/v21/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSh0me8iUI0.woff2) +- For 700: [https://fonts.gstatic.com/s/robotomono/v21/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSh0me8iUI0.woff2](https://fonts.gstatic.com/s/robotomono/v21/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSh0me8iUI0.woff2) + +And paste those URLS in the relevant input fields in **Admin settings** > **Settings** > **Appearance** > **Font** section where it says "Tell us where to find the file for each font weight. You don’t need to include all of them, but it’ll look better if you do." + +## Hosting fonts on GitHub + +If you host a font on GitHub, the font should be in a public repository, and you'll need to link to the raw font file(s) served from the raw.githubusercontent.com domain. + +For example, let's say you want to use the Inter typeface. The font is hosted at: + +[https://github.com/rsms/inter/blob/master/docs/font-files/Inter-Regular.woff2](https://github.com/rsms/inter/blob/master/docs/font-files/Inter-Regular.woff2) + +Then the link you'll need is: + +[https://raw.githubusercontent.com/rsms/inter/master/docs/font-files/Inter-Regular.woff2](https://raw.githubusercontent.com/rsms/inter/master/docs/font-files/Inter-Regular.woff2) + +Which follows the pattern: + +```txt +raw.githubusercontent.com/${user}/${repo}/${branch}/${path} +``` + +Note that in the raw link, there is no `/blob/` directory in the URL. + +## Supporting multiple languages + +To support multiple character sets, for example both Latin and Cyrillic, you'll need to merge font files. + +## Customizing the font for individual embedded items + +In addition to the [included fonts](#included-fonts), if you set a custom font for your Metabase, that font will be selectable from "Use instance font" in [static embeds](../embedding/static-embedding). + +## Further reading + +- [Customizing Metabase's appearance](./appearance) +- [Customer-facing analytics](/learn/metabase-basics/embedding) +- [Embedding documentation](../embedding/start) diff --git a/_docs/doc-update-detection/configuring-metabase/images/AccountSetup.png b/_docs/doc-update-detection/configuring-metabase/images/AccountSetup.png new file mode 100644 index 000000000..1c693d756 Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/AccountSetup.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/AddDatabaseInfo.png b/_docs/doc-update-detection/configuring-metabase/images/AddDatabaseInfo.png new file mode 100644 index 000000000..e0df8533b Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/AddDatabaseInfo.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/EmailCredentials.png b/_docs/doc-update-detection/configuring-metabase/images/EmailCredentials.png new file mode 100644 index 000000000..78f461c2d Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/EmailCredentials.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/MapSettings.png b/_docs/doc-update-detection/configuring-metabase/images/MapSettings.png new file mode 100644 index 000000000..f97424ecd Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/MapSettings.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/NewsletterSignup.png b/_docs/doc-update-detection/configuring-metabase/images/NewsletterSignup.png new file mode 100644 index 000000000..f5e74b7f2 Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/NewsletterSignup.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/UsageData.png b/_docs/doc-update-detection/configuring-metabase/images/UsageData.png new file mode 100644 index 000000000..194506cf2 Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/UsageData.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/WelcomeScreen.png b/_docs/doc-update-detection/configuring-metabase/images/WelcomeScreen.png new file mode 100644 index 000000000..a269a92f9 Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/WelcomeScreen.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/chart-colors.png b/_docs/doc-update-detection/configuring-metabase/images/chart-colors.png new file mode 100644 index 000000000..bf7b6f6c0 Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/chart-colors.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/custom-geojson.png b/_docs/doc-update-detection/configuring-metabase/images/custom-geojson.png new file mode 100644 index 000000000..1472f75d6 Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/custom-geojson.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/data-caching-settings.png b/_docs/doc-update-detection/configuring-metabase/images/data-caching-settings.png new file mode 100644 index 000000000..a4ae2aecc Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/data-caching-settings.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/lighthouse-illustration.png b/_docs/doc-update-detection/configuring-metabase/images/lighthouse-illustration.png new file mode 100644 index 000000000..16e2e8ecb Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/lighthouse-illustration.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/login-page.png b/_docs/doc-update-detection/configuring-metabase/images/login-page.png new file mode 100644 index 000000000..116fe590b Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/login-page.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/metabot-greeting.png b/_docs/doc-update-detection/configuring-metabase/images/metabot-greeting.png new file mode 100644 index 000000000..d8834ac09 Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/metabot-greeting.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/payload-chart.png b/_docs/doc-update-detection/configuring-metabase/images/payload-chart.png new file mode 100644 index 000000000..3973a2ddb Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/payload-chart.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/sailboat.png b/_docs/doc-update-detection/configuring-metabase/images/sailboat.png new file mode 100644 index 000000000..55cb45969 Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/sailboat.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/table-view.png b/_docs/doc-update-detection/configuring-metabase/images/table-view.png new file mode 100644 index 000000000..29d8631b4 Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/table-view.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/user-interface-colors.png b/_docs/doc-update-detection/configuring-metabase/images/user-interface-colors.png new file mode 100644 index 000000000..f6dddca80 Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/user-interface-colors.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/images/what-will-you-use-metabase-for.png b/_docs/doc-update-detection/configuring-metabase/images/what-will-you-use-metabase-for.png new file mode 100644 index 000000000..a37d5ab86 Binary files /dev/null and b/_docs/doc-update-detection/configuring-metabase/images/what-will-you-use-metabase-for.png differ diff --git a/_docs/doc-update-detection/configuring-metabase/localization.md b/_docs/doc-update-detection/configuring-metabase/localization.md new file mode 100644 index 000000000..aa3b56a8f --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/localization.md @@ -0,0 +1,127 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'Languages and localization' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/localization.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/localization +--- + +# Languages and localization + +The **Localization** settings allow you to set global defaults for your Metabase instance. You can find **Localization** under **Admin settings** > **Settings**. + +## Default language + +Here you can set the default language (also called the "instance language") across your Metabase UI, system [emails](./email), [dashboard subscriptions](../dashboards/subscriptions), and [alerts](../questions/alerts). People can pick a different language from their own [account settings](../people-and-groups/account-settings). + +## Supported languages + +Thanks to our amazing user community, Metabase has been translated into many different languages. Due to [the way we collect translations](#translations), languages may be added or removed during major releases depending on translation coverage. + +Supported languages include: + +| Language | Code | +| ---------------------- | ------- | +| English | `en` | +| Albanian | `sq` | +| Arabic | `ar` | +| Arabic (Saudi Arabia) | `ar-SA` | +| Bulgarian | `bg` | +| Catalan | `ca` | +| Chinese (Traditional) | `zh` | +| Chinese (Taiwanese) | `zh-TW` | +| Chinese (Hong Kong) | `zh-HK` | +| Chinese (Simplified) | `zh-CN` | +| Czech | `cs` | +| Dutch | `nl` | +| Farsi/Persian | `fa` | +| Finnish | `fi` | +| French | `fr` | +| German | `de` | +| Hebrew | `he` | +| Hungarian | `hu` | +| Indonesian | `id` | +| Malay | `ms` | +| Italian | `it` | +| Japanese | `ja` | +| Korean | `ko` | +| Latvian | `lv` | +| Norwegian Bokmål | `nb` | +| Polish | `pl` | +| Portuguese (Brazilian) | `pt-BR` | +| Russian | `ru` | +| Serbian | `sr` | +| Slovak | `sk` | +| Spanish | `es` | +| Swedish | `sv` | +| Turkish | `tr` | +| Ukrainian | `uk` | +| Vietnamese | `vi` | + +The locale codes are relevant for setting the language in [static embeds](../embedding/static-embedding-parameters#setting-the-language-for-a-static-embed). + +> While Metabase can support languages that read right to left, the Metabase UI is designed around languages that read left to right. + +## Translations + +Our community contributes to Metabase translations on our [Crowdin project](https://crowdin.com/project/metabase-i18n). If you'd like to help make Metabase available in a language you're fluent in, we'd love your help! + +For a new language to be added to Metabase, it must reach 100%. Once it does, we add it in the next major or minor release of Metabase. All _existing_ languages in Metabase _must stay at 100%_ to continue being included in the next _major_ version of Metabase. This rule ensures that no one encounters a confusing mishmash of English and another language when using Metabase. + +We understand that this is a high bar, so we commit to making sure that before each major release, any additions or changes to text in the product are completed at least 10 calendar days before the release ships, at which point we notify all translators that a new release will be happening soon. + +Note that while we only remove languages in major releases, we are happy to add them back for minor releases, so it's always a good time to jump in and start translating. + +## Report timezone + +Use **report timezone** to set a default display time zone for dates and times in Metabase. The report timezone setting is a display setting only, so changing the report timezone won't affect the time zone of any data in your database. + +Report timezone doesn't apply to `timestamp without time zone` data types, including the output of [`convertTimezone`](../questions/query-builder/expressions/converttimezone) expressions. For example: + +| Raw timestamp in your database | Data type | Report time zone | Displayed as | +| ---------------------------------------- | ----------------------------- | ---------------- | ---------------------- | +| `2022-12-28T12:00:00 AT TIME ZONE 'CST'` | `timestamp with time zone` | 'Canada/Eastern' | Dec 28, 2022, 7:00 AM | +| `2022-12-28T12:00:00-06:00` | `timestamp with offset` | 'Canada/Eastern' | Dec 28, 2022, 7:00 AM | +| `2022-12-28T12:00:00` | `timestamp without time zone` | 'Canada/Eastern' | Dec 28, 2022, 12:00 AM | + +Report timezone is only supported for the following databases: + +- BigQuery +- Druid +- MySQL +- Oracle +- PostgreSQL +- Presto +- Redshift +- Vertica + +## First day of the week + +If you need to, you can change the first day of the week for your instance (the default is Sunday). Setting the first day of the week affects things like grouping by week and filtering in questions built using the [query builder](../questions/query-builder/editor). This setting doesn't affect [SQL queries](../questions/native-editor/writing-sql). + +## Localization options + +**Localization options** allow you to set global default display formats for dates, times, numbers, and currencies. + +You can also override these localization options for specific fields or questions. For more info, see [Formatting](../data-modeling/formatting). + +### Dates and times + +- **Date style:** the way dates should be displayed in tables, axis labels, and tooltips. +- **Date separators:** you can choose between slashes (`2022/12/14`), dashes (`2022-12-14`), and dots (`2022.12.14.`). +- **Abbreviate names of days and months:** whenever a date is displayed with the day of the week and/or the month written out, turning this setting on will display e.g. "January" as "Jan" or "Monday" as "Mon". +- **Time style:** choose to display the time using either a 12 or 24-hour clock (e.g., 3:00 PM or 15:00). + +### Numbers + +- **Separator style:** some people use commas to separate thousands places, and others use periods. Here's where you can indicate which camp you belong to. + +### Currency + +- **Unit of currency:** if you do most of your business in a particular currency, you can specify that here. +- **Currency label style:** whether you want to have your currencies labeled with a symbol, a code (like "USD"), or its full name. +- **Where to display the unit of currency:** this pertains specifically to tables, and lets you choose if you want the currency labels to appear only in the column heading, or next to each value in the column. diff --git a/_docs/doc-update-detection/configuring-metabase/log-configuration.md b/_docs/doc-update-detection/configuring-metabase/log-configuration.md new file mode 100644 index 000000000..dcb46a644 --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/log-configuration.md @@ -0,0 +1,80 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'Metabase logs' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/log-configuration.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/log-configuration +--- + +# Metabase logs + +Metabase logs quite a bit of information by default. It uses [Log4j 2][log4j] under the hood, so you can configure how much information Metabase logs. + +## Configuring Logging Level + +Here is Metabase's [default logging configuration][default-log-config]. You can override this XML file and tell Metabase to use your own logging configuration file by passing a `-Dlog4j.configurationFile` argument when running Metabase. For example, if your custom XML file is found in `/path/to/custom/log4j2.xml`, you can use it like so: + +``` +java -Dlog4j.configurationFile=file:/path/to/custom/log4j2.xml -jar metabase.jar +``` + +To get started customizing the logs, make a [copy of the default `log4j2.xml` file][default-log-config] and adjust it to meet your needs. You'll need to restart Metabase for changes to the file to take effect. See Log4j's docs for info on [log levels][levels]. + +You can set different log levels for different areas of the application, e.g.,: + +``` + + + + + + + + + + + + + + +``` + +Check out [How to read the logs][read-logs]. + +## Jetty logs + +You can configure Metabase's web server to provide more detail in the logs by setting the log level to `DEBUG`. Just keep in mind that Jetty's debug logs can be really chatty, which can make it difficult to find the data you're looking for. + +To get Jetty logs, add the following lines to the Log4J2 XML file in the node: + +``` + +``` + +## Using Log4j 2 with Docker + +Before running the Metabase Docker image, you'll need to pass the custom `log4j.configurationFile` argument. Add a `JAVA_OPTS=-Dlog4j.configurationFile=file:/path/to/custom/log4j2.xml` to the environment variables of the container, like this: + +``` +docker run -p 3000:3000 -v $PWD/my_log4j2.xml:/tmp/my_log4j2.xml -e JAVA_OPTS=-Dlog4j.configurationFile=file:/tmp/my_log4j2.xml metabase/metabase` +``` + +## Disable emoji or colorized logging + +By default Metabase will include emoji characters in logs. You can disable emoji by using the `MB_EMOJI_IN_LOGS` environment variable: + +### Configuring Emoji Logging + +``` +export MB_EMOJI_IN_LOGS="false" +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +[default-log-config]: https://github.com/metabase/metabase/blob/master/resources/log4j2.xml +[levels]: https://logging.apache.org/log4j/2.x/manual/customloglevels.html +[log4j]: https://logging.apache.org/log4j/2.x/ +[read-logs]: ../troubleshooting-guide/server-logs diff --git a/_docs/doc-update-detection/configuring-metabase/setting-up-metabase.md b/_docs/doc-update-detection/configuring-metabase/setting-up-metabase.md new file mode 100644 index 000000000..656d68f16 --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/setting-up-metabase.md @@ -0,0 +1,97 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'Setting up Metabase' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/setting-up-metabase.md' +redirect_from: + - /docs/doc-update-detection/setting-up-metabase +--- + +# Setting up Metabase + +This guide will help you set up Metabase once you’ve gotten it installed. If you haven’t installed Metabase yet, you can [get Metabase here](/pricing/). + +Start Metabase up for the first time and you’ll see this screen: +![Welcome Screen](images/WelcomeScreen.png) + +Go ahead and click **Let’s get started**. + +## Setting up an admin account + +The first thing you’ll need to do is set up an admin account. The account you create when you first install Metabase is an admin account by default — handy! If you’ve installed Metabase on a production server, you should be really careful to remember the password for this account since it will be used to add other users, connect to databases, set up email, and more. You can also create additional admin accounts later. + +For now, let's just create an account for ourselves to explore Metabase. Type in your info, and when you’re ready to continue, click the **Next** button. + +![Account Setup](images/AccountSetup.png) + +## What will you use Metabase for? + +Let us know your plans with Metabase so that we can best guide you. + +![What will you use Metabase for?](./images/what-will-you-use-metabase-for.png) + +- Self-service analytics for my own company +- Embedding analytics into my application +- A bit of both +- Not sure yet + +Don't worry about picking the wrong option. If you say you're interested in embedding, Metabase will display a card with a link to the embedding settings when you (the admin) first log in to your instance. Just a little convenience thing, that's all. + +## Gathering your database info + +At this point you’ll need to gather some information about the database you want to use with Metabase. We won’t be able to connect to your database without it, but you’d like to deal with all of this later, that’s okay: just click **I’ll add my data later**. Metabase comes with a [Sample Database](/glossary/sample_database) that you can play around with to get a feel for how Metabase works. + +If you’re ready to connect, here’s what you’ll need: + +- The **hostname** of the server where your database lives +- The **port** the database server uses +- The **database name** +- The **username** you use for the database +- The **password** you use for the database + +If you don't have this information handy, the person responsible for administering the database should have it. + +## Connect to your database + +Now that you have your database info you can connect to your database. Sweet, sweet data at last. Just go ahead and put your info into this form and click **Next**. + +![adddatabase](images/AddDatabaseInfo.png) + +For more on connecting to databases, see [Adding and managing databases](../databases/connecting). + +## Activate your license + +If you're self-hosting Metabase on the [Pro](/product/pro) or [Enterprise](/product/enterprise) plan, Metabase will prompt you for your license. This step is just a convenience. You don't need to enter your license here; you can [activate your license](../installation-and-operation/activating-the-enterprise-edition) at any time. Just know that all of your Pro and Enterprise features won't work until you've activated your license. + +If you're running Pro on [Metabase Cloud](/cloud/), we'll handle this step for you. Your Pro features should already be available. + +## Usage data preferences + +One last quick thing that you’ll have to decide is if it’s okay for us to collect some anonymous info about how you use the product — it helps us make Metabase better. Like the box says: + +- Metabase never collects anything about your data or question results. +- All collection is completely anonymous. +- Collection can be turned off at any point in your admin settings. + +![Usage data preferences](images/UsageData.png) + +If you’re ready to start using Metabase, go ahead and click **Next**. + +## Staying in touch + +At this point you are all set and ready to use Metabase. Since we like keeping in touch with our friends we made it easy to sign up for our newsletter (infrequent emails) with a single click! + +![Metabase Newsletter](images/NewsletterSignup.png) + +Once you're done here simply follow the link to **Take me to Metabase**. And if you decided to skip the newsletter sign-up, it's cool, we still like you :) + +## Getting started with Metabase + +For a tutorial on getting up and running with questions and dashboards, head over to [Learn Metabase](/learn/metabase-basics/getting-started/). + +--- + +If you’d like more technical resources to set up your data stack with Metabase, connect with a [Metabase Expert](/partners/){:target="\_blank"}. diff --git a/_docs/doc-update-detection/configuring-metabase/settings.md b/_docs/doc-update-detection/configuring-metabase/settings.md new file mode 100644 index 000000000..0db035279 --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/settings.md @@ -0,0 +1,81 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'General settings' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/settings.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/08-configuration-settings +--- + +# General settings + +This section contains settings for your whole instance, like its URL, the reporting timezone, and toggles for disabling or enabling some of Metabase's optional features. + +You can configure these settings from **Settings** > **Admin Settings** > **General**. + +## Site name + +How you’d like to refer to this instance of Metabase. + +## Site URL + +The site URL is the web address that people use to access your Metabase instance. Make sure to include `http://` or `https://` to make sure it’s reachable. This feature is only available for self-hosted Metabases. For customers on Metabase Cloud, check out [Custom domains](/docs/latest/cloud/custom-domain). + +## Custom homepage + +Admins can pick a dashboard to serve as the homepage. If people lack permissions to view the selected dashboard, Metabase will redirect them to the default homepage. + +If you've set a dashboard as your homepage, and want to revert to the default Metabase homepage, simply turn off the **Enabled** toggle to disable the Custom Homepage feature. + +## Redirect to HTTPS + +By default, Metabase is served over HTTP. + +To force all traffic to use HTTPS via redirect, click `http://` (under the **Site URL** section) and select `https://` from the dropdown menu. + +For example, say you enable HTTPS redirect for a Metabase instance at the site URL "example.com". When someone enters an address like `example.com/data` in their browser's address bar, they'll get automatically redirected to a secure connection at `https://example.com/data`. + +> Note: if you haven't set up HTTPS on your server, Metabase will not let you enable HTTPS redirect. Instead, you'll get a warning saying "It looks like HTTPS is not properly configured." + +## Email address for help requests + +This email address will be displayed in various messages throughout Metabase when users encounter a scenario where they need assistance from an admin, such as a password reset request. + +## Anonymous tracking + +This option turns determines whether or not you allow [anonymous data about your usage of Metabase](../installation-and-operation/information-collection) to be sent back to us to help us improve the product. [Your database’s data is never tracked or sent](/security). + +## Friendly table and field names + +By default, Metabase attempts to make field and table names more readable by changing things like `somehorriblename` to `Some Horrible Name`. This does not work well for languages other than English, or for fields that have lots of abbreviations or codes in them. If you'd like to turn this setting off, you can do so from the Admin Panel under **Settings** > **Admin settings** > **General**. + +If you re-enable this setting, Metabase will run a [scan](../databases/sync-scan#how-database-scans-work) against your database to review your table and column names again. + +To manually label field or table names in Metabase, check out the [Table Metadata](../data-modeling/metadata-editing) section in your admin settings. Metadata in the Table Metadata can be further curated in [models](../data-modeling/models). + +## Enable X-rays + +[X-rays](../exploration-and-organization/x-rays) are a great way for people to get quick summary stats on your data. If these X-ray queries get too slow or expensive, you can turn them off here. + +## Allowed domains for iframes in dashboards + +Make sure you trust the sources that you allow people to embed in dashboards. + +You can include multiple domains separated by a comma. Including a subdomain is more restrictive than including the domain. + +- For **Domains**, (e.g., `example.com`), Metabase will allow any iframe from the domain (`example.com`) _and_ its subdomains (e.g., `data.example.com`, `docs.example.com`, etc.). +- For **Subdomains** (e.g., `data.example.com`) Metabase will restrict iframes to those subdomains. In this case, iframes _must_ be from `data.example.com` (or any of the other allowed domains). Metabase will block iframes from all other subdomains, including `example.com`. + +So if you included the following: + +``` +data.example.com, +docs.example.com +``` + +Metabase would only allow iframes from `data.example.com` and `docs.example.com`. Metabase would block iframes from all other domains, including iframes from `example.com` and its other subdomains. + +See [iframes in dashboards](../dashboards/introduction#iframe-cards). diff --git a/_docs/doc-update-detection/configuring-metabase/slack.md b/_docs/doc-update-detection/configuring-metabase/slack.md new file mode 100644 index 000000000..dedbc332f --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/slack.md @@ -0,0 +1,105 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: 'Set up Slack' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/slack.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/09-setting-up-slack +--- + +# Set up Slack + +If you want to have your [dashboard subscriptions](../dashboards/subscriptions) or [alerts](../questions/alerts) sent to Slack channels (or people on Slack), an admin must first integrate your Metabase with Slack. + +## Create your Slack App + +For Metabase to post to your Slack channels, you’ll need to create a Slack App and make it available to Metabase. + +From any Metabase page, go to **Admin settings** > **Settings** > **Notification channels** > **Slack**. + +Click on **Open Slack Apps**. Metabase will open a new browser tab and send you over to the Slack website to create the Slack app. + +On the Slack website, click **Create an App**. + +### Pick a workspace to develop your app + +Select the workspace you want to create your app. + +### The app manifest + +When you click on **Open Slack App**, Metabase will pass along the app manifest, which Slack will use to set up your app. + +You may get a warning that says: + +**This app is created from a 3rd party manifest** Always verify URLs and permissions below. + +This warning is expected (Metabase is the third party here). You can click on **Configure** to see the app manifest Metabase sent along in the URL. Here is the manifest in YAML format: + +```yml +_metadata: + major_version: 1 + minor_version: 1 +display_information: + name: Metabase + description: Bringing the power of Metabase to your Slack #channels! + background_color: "#509EE3" +features: + bot_user: + display_name: Metabase +oauth_config: + scopes: + bot: + - users:read + - channels:read + - channels:join + - files:write + - chat:write + - chat:write.customize + - chat:write.public + - groups:read +``` + +The manifest just take cares of some settings for your app and helps speed things along. + +Click the **Next** button. Then hit **Create** to set up your Slack app. + +## Install your app to your workspace + +On the Slack site for your newly created app, in the **Settings** > **Basic Information** tab, under **Install your app**, click on **Install to workspace**. On the next screen, click **Allow** to give Metabase access to your Slack workspace. + +## The Bot User OAuth Token + +On the Slack site page for your Slack app, on the left in the **Features** section, click on **OAuth and Permissions** in the Slack Apps sidebar and then copy the **Bot User OAuth Token**. Return to the Slack settings page in your Metabase and paste this token in the Metabase field with the same name. + +## Save your changes in Metabase + +In Metabase, click on the **Save changes** button and that’s it! Metabase will automatically run a quick test to check that the API token is working properly. If something goes wrong, it'll give you an error message. + +## Sending alerts and subscriptions to private Slack channels + +In order to send subscriptions and alerts to private Slack channels, you must first add the Metabase app to the private channel. + +In Slack, go to the private channel and mention the Metabase app. For example, if you called your Slack app "Metabase", you'd just type `@Metabase`. Slack will ask you if you want to invite your app to your channel, which you should. + +### Metabase not listing your private channel? + +It can take a little time for metabase to see all the channels the app has been invited to. New channels may not appear in listings for up to 10 minutes after inviting the app to the channel. + +In order for metabase to see private channels, the app must have the `groups:read` oauth scope. Although this scope should be granted when setting up the app through metabase, older installations might not have this scope. +If you think this might be the case [visit the app settings in slack](https://api.slack.com/apps/): +- Click on the metabase app in the app listing. +- Click on **OAuth & Permissions** in the sidebar. +- Under **Scopes** add the `groups:read` scope. +- The app will the need to be reinstalled to the workspace + by clicking the **Reinstall** button under **OAuth Tokens**. + +## Further reading + +- [Alerts](../questions/alerts) +- [Dashboard subscriptions](../dashboards/subscriptions) +- [Notification permissions](../permissions/notifications) +- [Setting up email](./email) +- [Usage analytics](../usage-and-performance-tools/usage-analytics) diff --git a/_docs/doc-update-detection/configuring-metabase/start.md b/_docs/doc-update-detection/configuring-metabase/start.md new file mode 100644 index 000000000..79d206ff6 --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/start.md @@ -0,0 +1,71 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: 'Configuring Metabase' +title: 'Configuration overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/start.md' +--- + +# Configuration overview + +## [Setting up Metabase](./setting-up-metabase) + +A walkthrough of when you first boot up your Metabase. + +## [General settings](./settings) + +Site name, report timezone, and more settings. + +## [Email](./email) + +Set up email for [Alerts](../questions/alerts) and [Dashboard subscriptions](../dashboards/subscriptions). + +## [Slack](./slack) + +Set up Slack for Alerts and Dashboard subscriptions. + +### [Webhooks](./webhooks) + +Set up webhooks as notification channels for alerts. + +## [Environment variables](./environment-variables) + +Configure Metabase on launch via environment variables. + +## [Configuration file](./config-file) + +On self-hosted Pro and Enterprise plans, you can configure Metabase via a configuration file. + +## [Metabase logs configuration](./log-configuration) + +Tell Metabase what to log. + +## [Timezones](./timezones) + +Guidance on timezone settings. + +## [Languages and localization](./localization) + +Set language, datetime, and currency settings. + +## [Uploads](../databases/uploads) + +Allow people to upload data to collections. + +## [Appearance](./appearance) + +Customize colors, fonts, and other visual elements. + +## [Caching query results](./caching) + +Cache query results for faster loading times. + +## [Custom maps](./custom-maps) + +Upload custom maps to your Metabase. + +## [Customizing the Metabase Jetty webserver](./customizing-jetty-webserver) + +Set SSL and port settings for the Jetty webserver. diff --git a/_docs/doc-update-detection/configuring-metabase/timezones.md b/_docs/doc-update-detection/configuring-metabase/timezones.md new file mode 100644 index 000000000..d30d1dbf8 --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/timezones.md @@ -0,0 +1,56 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: Timezones +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/timezones.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/handling-timezones +--- + +# Timezones + +Metabase does its best to ensure proper and accurate reporting in whatever timezone you want. But timezones are mysterious creatures. + +## Time zone settings + +The following places where timezones are set can all impact the data you see: + +- `Database` - includes global database timezone settings, specific column type settings, and even individual data values. +- `OS & JVM` - on whatever system is running Metabase the timezone settings of the Operating System as well as the Java Virtual Machine can impact your reports. +- `Metabase` - inside Metabase the reporting timezone setting (if set) will influence how your data is reported. +- `Metabase Cloud` - the timezone on the server that hosts your Metabase Cloud instance. + +## Recommended settings + +To ensure proper reporting it's important that timezones be set consistently in all places. Metabase recommends the following settings: + +- Make sure all of your database columns are properly setup to include [time zone awareness](#data-types). +- Unless you have a special need it's best to set your database reporting time zone to UTC and store all of your date/time related values in UTC. +- Configure your JVM to use the same timezone you want to use for reporting, which ideally should also match the timezone of your database. +- Set the Metabase `Report Timezone` to match the timezone you want to see your reports in, again, this should match the rest of the timezone settings you've made. +- If you want to change your Metabase Cloud timezone, please [contact support](/help-premium). + +## Data types + +You can make your database columns time zone aware by storing them as specific data types, such as: + +| Data type | Description | Example | +| ----------------------------- | ----------------------------------------- | ---------------------------------------------------- | +| `timestamp with time zone` | Knows about location. | `2022-12-28T12:00:00 AT TIME ZONE 'America/Toronto'` | +| `timestamp with offset` | Knows about the time difference from UTC. | `2022-12-28T12:00:00-04:00` | +| `timestamp without time zone` | No time zone info. | `2022-12-28T12:00:00` | + +The exact data type will depend on your database. Some Metabase features only work with specific data types: + +- [Report timezone setting](../configuring-metabase/localization#report-timezone) +- [`converttimezone` custom expression](../questions/query-builder/expressions/converttimezone) + +## Common pitfalls + +1. Your database is using date/time columns without any timezone information. Typically when this happens your database will assume all the data is from whatever timezone the database is configured in or possible just default to UTC (check your database vendor to be sure). +2. Your JVM timezone is different from your Metabase `Report Timezone` choice. This is a very common issue and can be corrected by launching java with the `-Duser.timezone=` option properly set to match your Metabase report timezone. + +If you are still experiencing timezone problems, then have a look at the [timezone troubleshooting guide](../troubleshooting-guide/timezones). diff --git a/_docs/doc-update-detection/configuring-metabase/webhooks.md b/_docs/doc-update-detection/configuring-metabase/webhooks.md new file mode 100644 index 000000000..63f6e597c --- /dev/null +++ b/_docs/doc-update-detection/configuring-metabase/webhooks.md @@ -0,0 +1,126 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Configuring Metabase' +title: Webhooks +source_url: 'https://github.com/metabase/metabase/blob/master/docs/configuring-metabase/webhooks.md' +--- + +# Webhooks + +Admins can set up webhooks so that people can send [alerts](../questions/alerts) to a particular URL. Which means you can set up an alert to send the results of a question to an endpoint of your choice: to your app, a third-party service, or wherever. + +For now, webhooks are only available for [alerts](../questions/alerts); you can't select a webhook as the recipient of a [dashboard subscription](../dashboards/subscriptions). + +## Creating a webhook + +Before you can send an alert to a webhook, an admin will need to create a webhook to target. + +Admins can create a webhook by clicking on the **gear icon** > **Admin settings** > **Notification channels**. In the **Webhooks for alerts**, click **+ Add another**. Metabase will hand you a short form to fill out: + +- **Webhook URL**. Where you want Metabase to send the results of an alert. Must be a valid URL. +- **Give it a name**. You have to name the webhook so that people can pick the right hook when setting up an alert on a question. +- **Description**. You should probably tell people what the hook is for. +- **Authentication method**. See below. + +## Webhook authentication method + +You can specify an auth method for the webhook. + +- **None**: Anything goes. +- **Basic**: Set a username and password. +- **Bearer**: Include a [secret token](https://datatracker.ietf.org/doc/html/rfc6750). +- **API key**: You can add the API key to the Header or as a Query param. Both approaches require a key and value (the API key itself). + +## Webhook payload + +Metabase will send the results of an alert in JSON. The JSON will include some metadata about the question, like the alert's creator and its ID (`null` in the case of test alerts). + +Metabase will send the "attached" visualization as a base64-encoded PNG in the `data` key, under `visualization`. + +![The encoded PNG chart](./images/payload-chart.png) + +And the data as seen in the table view, which Metabase will send as a `raw_data`. + +![Results as table view](./images/table-view.png) + +Here's an example payload for an alert (we truncated the PNG encoding because it's long and extremely boring): + +```JSON +{ + "type": "alert", + "alert_id": null, + "alert_creator_id": 2666, + "alert_creator_name": "Roberto Bolaño", + "data": { + "type": "question", + "question_id": 108, + "question_name": "Sales", + "question_url": "http://example.com/question/108", + "visualization": "data:image/png;base64,=...LONG_ENCODED_PNG_HERE...", + "raw_data": { + "cols": [ + "CREATED_AT", + "count" + ], + "rows": [ + [ + "2023-09-01T00:00:00Z", + 346 + ], + [ + "2023-10-01T00:00:00Z", + 354 + ], + [ + "2023-11-01T00:00:00Z", + 394 + ], + [ + "2023-12-01T00:00:00Z", + 418 + ], + [ + "2024-01-01T00:00:00Z", + 457 + ], + [ + "2024-02-01T00:00:00Z", + 404 + ], + [ + "2024-03-01T00:00:00Z", + 445 + ], + [ + "2024-04-01T00:00:00Z", + 439 + ], + [ + "2024-05-01T00:00:00Z", + 520 + ], + [ + "2024-06-01T00:00:00Z", + 455 + ], + [ + "2024-07-01T00:00:00Z", + 523 + ], + [ + "2024-08-01T00:00:00Z", + 501 + ] + ] + } + }, + "sent_at": "2024-09-30T20:16:15.76582Z" +} +``` + +## Further reading + +- [Alerts](../questions/alerts) diff --git a/_docs/doc-update-detection/dashboards/actions.md b/_docs/doc-update-detection/dashboards/actions.md new file mode 100644 index 000000000..33616e731 --- /dev/null +++ b/_docs/doc-update-detection/dashboards/actions.md @@ -0,0 +1,67 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Dashboards +title: 'Actions on dashboards' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/dashboards/actions.md' +--- + +# Actions on dashboards + +![Dashboard with filter, action button, and detail card view](./images/dashboard-filter-action.png) + +To put [actions](../actions/start) in action, you can combine them with a [model](../data-modeling/models) and a [filter](./filters) on a dashboard. + +## Adding an action to a dashboard + +Visit a dashboard page and click on the **pencil** icon, then click on the **box with a mouse pointer** to add an action. + +Metabase will add an action button to the dashboard grid, and open a sidebar with the buttons settings. + +### Button text + +A label explaining what the button does, e.g., "Ignition". + +### Button variant + +You can select from a variety of handsome buttons: + +- Primary +- Outline +- Danger +- Success +- Borderless + +![Button types](./images/buttons.png) + +## Connecting an action to a dashboard filter + +For most actions, when people click on a button, they'll be prompted to input values in the fields defined by that action. + +Many types of actions rely on knowing the Entity ID for the model to determine which records to update or delete. To have people select the ID for the action, you'll need to: + +1. Click on the pencil icon to edit the dashboard. +2. Add an action to the dashboard (if you haven't already). +3. [Add a filter](./filters) to a dashboard, wire it up to any cards that you want to, and click **Done** in the bottom of the sidebar. +4. Hover over the action button and click on the **gear** icon, and select **Change action**. +5. Click on the field's dropdown to select where the action should get it's value. Here you can select "Ask the user" or have it automatically populated by a dashboard filter. In this case, we'll select our "ID" filter. + +![Wiring up an action button to a dashboard filter](./images/id-value.png) + +If you also wire that filter up to a card with a model on the dashboard, you can filter for individual records in that model, view them in the model's card, and have the action buttons auto-populate the id. + +![Button form](./images/button-form.png) + +You can add as many buttons as you want, and wire them up to one or more filters. + +## Actions are unavailable for public dashboards and dashboards in static embeds + +While you can add actions to dashboards and use them in your Metabase, actions won't work on dashboards accessed via [public links](./introduction#sharing-dashboards-with-public-links), or dashboards in static embeds. + +If you want people outside of your Metabase to use an action, you can create a [public form for an action](../actions/custom#make-public), or expose actions via [interactive embedding](../embedding/interactive-embedding). + +## Further reading + +- [Actions](../actions/start) diff --git a/_docs/doc-update-detection/dashboards/filters.md b/_docs/doc-update-detection/dashboards/filters.md new file mode 100644 index 000000000..aae75fa13 --- /dev/null +++ b/_docs/doc-update-detection/dashboards/filters.md @@ -0,0 +1,277 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Dashboards +title: 'Dashboard filters' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/dashboards/filters.md' +redirect_from: + - /docs/doc-update-detection/users-guide/08-dashboard-filters +--- + +# Dashboard filters and parameters + +![Dashboard Filters](./images/filters.png) + +Have you ever found yourself in a situation where it seems like you need to create nearly identical copies of the same dashboard, with just one different variable? Maybe you have an Earnings dashboard, but you want to see the data for each city your business is in, or maybe you have a KPI dashboard that you want to see broken out by month. + +Instead of creating duplicate dashboards, you can add filter or parameter widgets to let people change variables for cards on a dashboard. + +## Adding a filter or parameter + +![Add a Filter](./images/add-filter.png) + +- Click the **pencil icon** to enter dashboard editing mode. +- Click the **filter icon** that appears in the top-right to add a filter. +- Select a [filter type](#filter-and-parameter-types) +- [Connect your filter or parameter widget to dashboard cards](#connecting-a-filter-or-parameter-widget-to-dashboard-cards) to one or more dashboard cards on any or all tabs. +- [Configure your filter](#editing-a-filter) +- **Save** your changes. + +Metabase will display the filter only if the filter is connected to a card on the current dashboard tab. + +## Filter and parameter types + +The type of filter or parameter widget you choose will determine how the widget works, as well as which fields you’ll be able to filter your cards by. + +### Filter widgets + +- [Date picker](#date-picker-filters) +- [Location](#location-filters) +- [ID](#id-filter) +- [Number](#number-filter) +- [Text or category](#text-or-category-filter) + +### Parameter widgets + +- [Time grouping](#time-grouping-parameter) + +## Date picker filters + +When picking a Time filter, Metabase will prompt you to pick a specific type of date picker widget: + +- Month and Year +- Quarter and Year +- Single Date +- Date Range +- Relative Date +- All Options + +Single Date and Date Range will provide a calendar widget, while the other options all provide slightly different dropdown interfaces for picking values. To get a widget that's just like the time filter in the query builder, choose All options. + +## Time grouping parameter + +![Time grouping](./images/time-grouping.png) + +You can add a time grouping widget to a dashboard to change how charts are grouped by time. For example, you may want to look at the time series charts grouped by month by default, but give people the option to view the results by other groupings: by week, by quarter, and so on. + +> Time grouping parameter widget can only be connected to questions built with the [graphical query builder](../questions/query-builder/editor). + +This widget doesn't filter data in the charts; the widget just changes the time granularity for any cards that have a datetime field connected to the widget. + +You can group by: + +- Minute (or minute of hour) +- Hour (or hour of day) +- Day (or day of week, month, or year) +- Week (or week of year) +- Month (or month of year) +- Quarter (or quarter of year) +- Year + +## Location filters + +There are four types of Location filters to choose from: + +- City +- State +- ZIP or Postal Code +- Country + +## ID filter + +The ID filter provides a simple input box where you can type the ID of a user, order, etc. + +## Number filter + +You can choose from: + +- Equal to +- Not equal to +- Between +- Greater than or equal to +- Less than or equal to + +## Text or category filter + +A flexible filter type that will let you create either a dropdown menu or an input box to filter on any category field in your cards. Options include: + +- **Is**. Select one or more values from a list or search box. Use **Is** when you just want to plug a value into a variable. For multiple values, the card must be either a question built using the query builder, or a native/SQL question using a [field filter](../questions/native-editor/sql-parameters#the-field-filter-variable-type). +- **Is not**. Exclude one or more specific values. +- **Contains**. Match values that contain the entered text. +- **Does not contain**. Filter out values that contain the entered text. +- **Starts with**. Match values that begin with the entered text. +- **Ends with**. Match values that end with the entered text. + +## Connecting a filter or parameter widget to dashboard cards + +Dashboard widgets apply across all [dashboard tabs](./introduction#dashboard-tabs), though they'll only be displayed when a tab has cards connected to the widget. + +For each widget that you add, you'll need to tell Metabase which column the filter should update for each card. + +Click on a card's dropdown menu to select the field that you want the widget to filter on. + +Here we've wired up a Text filter to the "Event types" card, telling Metabase that the column to filter on should be the `Analytics.Event.Button.Label` field: + +![Wiring up a dashboard filter to a card](./images/wiring-cards.png) + +## Auto-connecting filters to cards + +If there are other cards that also have the field you select, Metabase will offer to automatically connect the filter to those cards too (including to relevant cards on other tabs). If you later add a card with the selected field, Metabase will also try to connect that filter to the new card. + +To undo this auto-connecting of cards, click on the toast that pops up when Metabase auto-connects the cards, or manually disconnect the cards by clicking on the "X" next to the connected field. + +## Filtering dashboards with native/SQL questions + +If you're trying to connect a filter to a card with a native/SQL questions, you'll need to [add a variable or field filter to your query](../questions/native-editor/sql-parameters). For an in-depth article, check out [Adding filters to dashboards with SQL questions](/learn/metabase-basics/querying-and-dashboards/sql-in-metabase/filters). + +You can't connect a time grouping parameter widget to a card with a SQL question. + +## Wiring up dashboard filters to text cards + +You can even wire up filters to text cards, but only if [the text card includes a variable](./introduction#including-variables-in-text-cards). + +## Requiring a filter or parameter + +You can tell Metabase to require a filter so that people _must_ filter the dashboard by a certain column on a card. If you require a filter, you'll also need to supply a default value for that filter. + +You might want to require a filter value if: + +- Your unfiltered dashboard contains questions that pull lots of data, as enforcing filtered data can prevent people from inadvertently querying tons of data and running up your data warehouse costs. +- The questions on your dashboard don't make sense without a filter. For example, if you create a dashboard intended to view data relevant to a specific customer (as opposed to all customers), you can require a customer ID so that the dashboard only loads data for a particular customer. + +## Editing a filter + +To edit a filter's settings: + +1. Click the **pencil** icon to enter dashboard editing mode. +2. Click the **gear** icon on the filter you want to edit. + +From this filter editing view, you can wire up dashboard cards to the filter, or use the filter settings sidebar to: + +- [Rename filter](#rename-filter) +- [Set filter input type](#set-filter-input-type) +- [Set a default filter value](#set-a-default-filter-value) +- [Remove a filter](#remove-a-filter) +- [Reorder filters](#reorder-filters) +- [Make a multi-select filter](#make-a-multi-select-filter) +- [Change a filter's selectable values](#change-a-filters-selectable-values) + +### Rename filter + +1. In dashboard edit mode, click your filter's **gear** icon. +2. Change the label text. + +Renaming the filter only affects the filter's display; the label has no effect on which columns Metabase filters. + +### Set filter input type + +1. In dashboard edit mode, click your filter's **gear** icon. +2. From the filter settings sidebar, set **How should people filter on this column?**: + +- [Dropdown list](#dropdown-list) +- [Search box](#search-box) +- [Input box](#plain-input-box) + +#### Dropdown list + +A list of all of the possible values in a column. People can use checkboxes to select more than one value on [multi-select filters](#make-a-multi-select-filter). You should choose the dropdown widget if you want the list of filter values to load instantly (from cache). + +If you're not seeing the **Dropdown list** option, and your dashboard filter is based on a column from a: + +- Table or GUI model: an admin will need to [enable the dropdown widget](../data-modeling/metadata-editing#changing-a-search-box-filter-to-a-dropdown-filter) for that column from Metabase's **Admin settings**. +- SQL model: go to your [model's metadata settings](../data-modeling/models#add-metadata-to-columns-in-a-model), find your column, and set the **Database column this maps to**. + +#### Search box + +A search box that suggests a list of matching filter values as you type. The suggestion list will display checkboxes for [multi-select filters](#make-a-multi-select-filter). + +The search box is a good choice for most columns containing labels, categories, statuses, and so on. It's is the default filter widget for columns with less than 100 unique values. + +#### Plain input box + +An input box that lets people enter plain text (no suggestion list). + +Useful for looking up partial matches (such as the ["contains" filter](#text-or-category-filter)) in columns that contain free text, such as comments or descriptions. The input box is the default filter widget for columns with more than 100 unique values. + +### Set a default filter value + +1. In dashboard edit mode, click your filter's **gear** icon. +2. From the sidebar, choose a value from the **Default value** input field. + +For example, you might want to set a default filter value like "Active", so that when people load your dashboard, they only see data for "Active" records (not "Inactive", "Cancelled", etc). + +### Remove a filter + +1. In dashboard edit mode, click your filter's **gear** icon. +2. From the sidebar, click **Remove**. + +If you accidentally remove a filter, just click **Cancel** in the top-right to exit dashboard edit mode without saving your changes. + +### Reorder filters + +In dashboard edit mode, click on the grabber handle (six dots) on the left side of a filter widget, then drag the widget to a different position. + +### Make a multi-select filter + +1. In dashboard edit mode, click your filter's **gear** icon. +2. From the sidebar, find **People can pick** and select "Multiple values". + +A multi-select filter with the widget type [Dropdown list](#dropdown-list) or [Search box](#search-box) will display a list of values with checkboxes. + +### Change a filter's selectable values + +1. In dashboard edit mode, click your filter's **gear** icon. +2. From the sidebar, find **How should users filter on this column?**. +3. Select "Dropdown list".\* +4. Click **Edit** (to the right of "Dropdown list") to specify where the values should come from: + - From connected fields + - From another model or question + - Custom list + +![Selectable values](./images/selectable-values.png) + +\* If you don't see "Dropdown list" as an option, go to [Filter widgets: Dropdown list](#dropdown-list) for more info. + +## Linking filters + +See [Linked filters](linked-filters). + +## Auto-apply filters + +By default, each time you change the value in a filter on a dashboard, the dashboard will refresh to get the results of each card with that new filter value applied. + +If a dashboard is particularly large or slow, or you have multiple filters that you want to adjust before the dashboard refreshes its results, you may want to tell Metabase when to apply those filters and refresh the dashboard. + +To turn off the automatic application of filters, click on the info **i** icon, and toggle the **Auto-apply filters** option. With auto-apply turned off, each time you change a value in a filter, you'll need to click the **Apply** button to refresh the dashboard with the new filter value. + +![Click Apply to apply the filters and refresh the dashboard](./images/apply-button.png) + +## Using filter widgets + +Once you’ve added a filter to your dashboard, just click on the filter widget to select a value and activate the filter. To stop filtering, just click the blue X. + +Your active filter will only apply to your view of the dashboard. If someone else is viewing the same dashboard link at the same time, they won't see your filter. + +![Using a filter](./images/use-filter.png) + +You can also set up a dashboard question to [update a filter on click](./interactive#use-a-chart-to-filter-a-dashboard). + +## Further reading + +- [Introduction to dashboards](./introduction) +- [Interactive dashboards](./interactive) +- [Dashboard subscriptions](./subscriptions) +- [Charts with multiple series](./multiple-series) +- [Learn dashboards](/learn/metabase-basics/querying-and-dashboards/dashboards) diff --git a/_docs/doc-update-detection/dashboards/images/add-filter.png b/_docs/doc-update-detection/dashboards/images/add-filter.png new file mode 100644 index 000000000..460ab1466 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/add-filter.png differ diff --git a/_docs/doc-update-detection/dashboards/images/add-section.png b/_docs/doc-update-detection/dashboards/images/add-section.png new file mode 100644 index 000000000..c367bdf42 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/add-section.png differ diff --git a/_docs/doc-update-detection/dashboards/images/add_series.png b/_docs/doc-update-detection/dashboards/images/add_series.png new file mode 100644 index 000000000..625512ea9 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/add_series.png differ diff --git a/_docs/doc-update-detection/dashboards/images/add_values.png b/_docs/doc-update-detection/dashboards/images/add_values.png new file mode 100644 index 000000000..2ce7ba3ee Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/add_values.png differ diff --git a/_docs/doc-update-detection/dashboards/images/apply-button.png b/_docs/doc-update-detection/dashboards/images/apply-button.png new file mode 100644 index 000000000..57030f9a8 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/apply-button.png differ diff --git a/_docs/doc-update-detection/dashboards/images/autorefresh.png b/_docs/doc-update-detection/dashboards/images/autorefresh.png new file mode 100644 index 000000000..544a780f7 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/autorefresh.png differ diff --git a/_docs/doc-update-detection/dashboards/images/button-form.png b/_docs/doc-update-detection/dashboards/images/button-form.png new file mode 100644 index 000000000..af2cda3fa Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/button-form.png differ diff --git a/_docs/doc-update-detection/dashboards/images/buttons.png b/_docs/doc-update-detection/dashboards/images/buttons.png new file mode 100644 index 000000000..3c5c347b2 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/buttons.png differ diff --git a/_docs/doc-update-detection/dashboards/images/click-behavior-icon.png b/_docs/doc-update-detection/dashboards/images/click-behavior-icon.png new file mode 100644 index 000000000..c5a59d832 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/click-behavior-icon.png differ diff --git a/_docs/doc-update-detection/dashboards/images/click-behavior-menu.png b/_docs/doc-update-detection/dashboards/images/click-behavior-menu.png new file mode 100644 index 000000000..259440e37 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/click-behavior-menu.png differ diff --git a/_docs/doc-update-detection/dashboards/images/cross-filter.png b/_docs/doc-update-detection/dashboards/images/cross-filter.png new file mode 100644 index 000000000..6a0ff1847 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/cross-filter.png differ diff --git a/_docs/doc-update-detection/dashboards/images/custom-destination.png b/_docs/doc-update-detection/dashboards/images/custom-destination.png new file mode 100644 index 000000000..bbe86017e Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/custom-destination.png differ diff --git a/_docs/doc-update-detection/dashboards/images/dark-mode.png b/_docs/doc-update-detection/dashboards/images/dark-mode.png new file mode 100644 index 000000000..9a8b84c91 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/dark-mode.png differ diff --git a/_docs/doc-update-detection/dashboards/images/dashboard-filter-action.png b/_docs/doc-update-detection/dashboards/images/dashboard-filter-action.png new file mode 100644 index 000000000..d18c28a9f Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/dashboard-filter-action.png differ diff --git a/_docs/doc-update-detection/dashboards/images/dashboard-tabs.png b/_docs/doc-update-detection/dashboards/images/dashboard-tabs.png new file mode 100644 index 000000000..74f962ab8 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/dashboard-tabs.png differ diff --git a/_docs/doc-update-detection/dashboards/images/dashboard-with-iframe.png b/_docs/doc-update-detection/dashboards/images/dashboard-with-iframe.png new file mode 100644 index 000000000..e92179246 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/dashboard-with-iframe.png differ diff --git a/_docs/doc-update-detection/dashboards/images/dashboard-with-link-cards.png b/_docs/doc-update-detection/dashboards/images/dashboard-with-link-cards.png new file mode 100644 index 000000000..f23ecd9a4 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/dashboard-with-link-cards.png differ diff --git a/_docs/doc-update-detection/dashboards/images/dashboard.png b/_docs/doc-update-detection/dashboards/images/dashboard.png new file mode 100644 index 000000000..98ce0a0ae Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/dashboard.png differ diff --git a/_docs/doc-update-detection/dashboards/images/drill-through-menu.png b/_docs/doc-update-detection/dashboards/images/drill-through-menu.png new file mode 100644 index 000000000..292efcbbe Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/drill-through-menu.png differ diff --git a/_docs/doc-update-detection/dashboards/images/duplicate-card.png b/_docs/doc-update-detection/dashboards/images/duplicate-card.png new file mode 100644 index 000000000..ccb0d7172 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/duplicate-card.png differ diff --git a/_docs/doc-update-detection/dashboards/images/edit_modal.png b/_docs/doc-update-detection/dashboards/images/edit_modal.png new file mode 100644 index 000000000..0acb0962e Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/edit_modal.png differ diff --git a/_docs/doc-update-detection/dashboards/images/edit_modal_multi-series.png b/_docs/doc-update-detection/dashboards/images/edit_modal_multi-series.png new file mode 100644 index 000000000..3959bf0a3 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/edit_modal_multi-series.png differ diff --git a/_docs/doc-update-detection/dashboards/images/email-options.png b/_docs/doc-update-detection/dashboards/images/email-options.png new file mode 100644 index 000000000..53172b9f8 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/email-options.png differ diff --git a/_docs/doc-update-detection/dashboards/images/email-or-slack.png b/_docs/doc-update-detection/dashboards/images/email-or-slack.png new file mode 100644 index 000000000..ea6e77087 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/email-or-slack.png differ diff --git a/_docs/doc-update-detection/dashboards/images/enter-a-url.png b/_docs/doc-update-detection/dashboards/images/enter-a-url.png new file mode 100644 index 000000000..68fe5a239 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/enter-a-url.png differ diff --git a/_docs/doc-update-detection/dashboards/images/field-values-linked-filters.png b/_docs/doc-update-detection/dashboards/images/field-values-linked-filters.png new file mode 100644 index 000000000..7121af8bb Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/field-values-linked-filters.png differ diff --git a/_docs/doc-update-detection/dashboards/images/filters.png b/_docs/doc-update-detection/dashboards/images/filters.png new file mode 100644 index 000000000..7045deead Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/filters.png differ diff --git a/_docs/doc-update-detection/dashboards/images/foreign-key-linked-filters.png b/_docs/doc-update-detection/dashboards/images/foreign-key-linked-filters.png new file mode 100644 index 000000000..686671f73 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/foreign-key-linked-filters.png differ diff --git a/_docs/doc-update-detection/dashboards/images/id-value.png b/_docs/doc-update-detection/dashboards/images/id-value.png new file mode 100644 index 000000000..aeb81fd7c Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/id-value.png differ diff --git a/_docs/doc-update-detection/dashboards/images/interactive-dashboard.png b/_docs/doc-update-detection/dashboards/images/interactive-dashboard.png new file mode 100644 index 000000000..2ea88ff04 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/interactive-dashboard.png differ diff --git a/_docs/doc-update-detection/dashboards/images/kpi-grid.png b/_docs/doc-update-detection/dashboards/images/kpi-grid.png new file mode 100644 index 000000000..f5d97658f Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/kpi-grid.png differ diff --git a/_docs/doc-update-detection/dashboards/images/kpis-with-large-chart-below.png b/_docs/doc-update-detection/dashboards/images/kpis-with-large-chart-below.png new file mode 100644 index 000000000..25dba58f7 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/kpis-with-large-chart-below.png differ diff --git a/_docs/doc-update-detection/dashboards/images/large-chart-with-kpis-to-the-right.png b/_docs/doc-update-detection/dashboards/images/large-chart-with-kpis-to-the-right.png new file mode 100644 index 000000000..272901fc1 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/large-chart-with-kpis-to-the-right.png differ diff --git a/_docs/doc-update-detection/dashboards/images/linked-filter.png b/_docs/doc-update-detection/dashboards/images/linked-filter.png new file mode 100644 index 000000000..61c8c35c5 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/linked-filter.png differ diff --git a/_docs/doc-update-detection/dashboards/images/markdown.png b/_docs/doc-update-detection/dashboards/images/markdown.png new file mode 100644 index 000000000..7e0049500 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/markdown.png differ diff --git a/_docs/doc-update-detection/dashboards/images/multi-series_query_builder.png b/_docs/doc-update-detection/dashboards/images/multi-series_query_builder.png new file mode 100644 index 000000000..ae5f0e713 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/multi-series_query_builder.png differ diff --git a/_docs/doc-update-detection/dashboards/images/notebook_editor_multi-series.png b/_docs/doc-update-detection/dashboards/images/notebook_editor_multi-series.png new file mode 100644 index 000000000..3afa5c307 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/notebook_editor_multi-series.png differ diff --git a/_docs/doc-update-detection/dashboards/images/numbers_to_bar_chart.png b/_docs/doc-update-detection/dashboards/images/numbers_to_bar_chart.png new file mode 100644 index 000000000..ff6686c6d Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/numbers_to_bar_chart.png differ diff --git a/_docs/doc-update-detection/dashboards/images/pass-category-to-filter.png b/_docs/doc-update-detection/dashboards/images/pass-category-to-filter.png new file mode 100644 index 000000000..96f7e4daa Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/pass-category-to-filter.png differ diff --git a/_docs/doc-update-detection/dashboards/images/pass-value.png b/_docs/doc-update-detection/dashboards/images/pass-value.png new file mode 100644 index 000000000..19d1856c2 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/pass-value.png differ diff --git a/_docs/doc-update-detection/dashboards/images/result.png b/_docs/doc-update-detection/dashboards/images/result.png new file mode 100644 index 000000000..fd34bbc1b Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/result.png differ diff --git a/_docs/doc-update-detection/dashboards/images/selectable-values.png b/_docs/doc-update-detection/dashboards/images/selectable-values.png new file mode 100644 index 000000000..d27e5a5eb Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/selectable-values.png differ diff --git a/_docs/doc-update-detection/dashboards/images/set-filter-values.png b/_docs/doc-update-detection/dashboards/images/set-filter-values.png new file mode 100644 index 000000000..633b380d9 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/set-filter-values.png differ diff --git a/_docs/doc-update-detection/dashboards/images/share-icon.png b/_docs/doc-update-detection/dashboards/images/share-icon.png new file mode 100644 index 000000000..04b70a09e Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/share-icon.png differ diff --git a/_docs/doc-update-detection/dashboards/images/slack-subscription-options.png b/_docs/doc-update-detection/dashboards/images/slack-subscription-options.png new file mode 100644 index 000000000..37d3b51d7 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/slack-subscription-options.png differ diff --git a/_docs/doc-update-detection/dashboards/images/text-card-button.png b/_docs/doc-update-detection/dashboards/images/text-card-button.png new file mode 100644 index 000000000..9b7d8e28a Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/text-card-button.png differ diff --git a/_docs/doc-update-detection/dashboards/images/time-grouping.png b/_docs/doc-update-detection/dashboards/images/time-grouping.png new file mode 100644 index 000000000..4de5638ef Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/time-grouping.png differ diff --git a/_docs/doc-update-detection/dashboards/images/toggle-width.png b/_docs/doc-update-detection/dashboards/images/toggle-width.png new file mode 100644 index 000000000..084a9fd34 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/toggle-width.png differ diff --git a/_docs/doc-update-detection/dashboards/images/update-a-dashboard-filter.png b/_docs/doc-update-detection/dashboards/images/update-a-dashboard-filter.png new file mode 100644 index 000000000..57dabebe6 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/update-a-dashboard-filter.png differ diff --git a/_docs/doc-update-detection/dashboards/images/use-filter.png b/_docs/doc-update-detection/dashboards/images/use-filter.png new file mode 100644 index 000000000..e8c930d17 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/use-filter.png differ diff --git a/_docs/doc-update-detection/dashboards/images/visualization-settings.png b/_docs/doc-update-detection/dashboards/images/visualization-settings.png new file mode 100644 index 000000000..160328747 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/visualization-settings.png differ diff --git a/_docs/doc-update-detection/dashboards/images/wiring-cards.png b/_docs/doc-update-detection/dashboards/images/wiring-cards.png new file mode 100644 index 000000000..c00ed7652 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/wiring-cards.png differ diff --git a/_docs/doc-update-detection/dashboards/images/wiring-up-filter.png b/_docs/doc-update-detection/dashboards/images/wiring-up-filter.png new file mode 100644 index 000000000..efe1e7d45 Binary files /dev/null and b/_docs/doc-update-detection/dashboards/images/wiring-up-filter.png differ diff --git a/_docs/doc-update-detection/dashboards/interactive.md b/_docs/doc-update-detection/dashboards/interactive.md new file mode 100644 index 000000000..c519627b8 --- /dev/null +++ b/_docs/doc-update-detection/dashboards/interactive.md @@ -0,0 +1,139 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Dashboards +title: 'Dashboard interactivity' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/dashboards/interactive.md' +redirect_from: + - /docs/doc-update-detection/users-guide/interactive-dashboards +--- + +# Dashboard interactivity + +You can customize what happens when people click on questions in your dashboard. + +By default, when you create charts using Metabase's graphical query builder, your charts automatically come with [drill-through capabilities](/learn/metabase-basics/querying-and-dashboards/questions/drill-through), which let folks click on a chart to explore further. But if you have a more customized click path in mind, Metabase allows you to customize what happens when a user clicks on a chart or table in your dashboard. + +You can set up a dashboard card to: + +- Send the user to a [custom destination](#custom-destinations): a dashboard, question, or custom URL. +- [Update a dashboard filter](#use-a-chart-to-filter-a-dashboard). + +To configure this interactivity, you'll use the **click behavior** option on a dashboard card. + +## Customizing click behavior + +From your dashboard, first click on the **pencil** icon to enter dashboard edit mode. + +If you hover over the card that contains question you want to customize, Metabase will display a menu at the top right of that card containing these options, from left to right: + +- **Visualization options**: This icon looks like a painter's palette. +- **Click behavior**: This is the icon with the mouse cursor clicking on a card. +- **Add series**: If your question has a visualization to which you can add an [additional series](./multiple-series) (like a line or bar chart), you'll see this icon as a **+** next to a small representation of that chart type. Not all cards will show this option. +- **Remove**: This icon is an **X**. Selecting this will remove your question from the dashboard. + +Select the **Click behavior** option. + +![Click behavior icon](./images/click-behavior-icon.png) + +Metabase will slide out the **Click behavior sidebar**: + +![Click behavior menu](./images/click-behavior-menu.png) + +For questions composed using the query builder, you can select from three options: + +- Open the Metabase drill-through menu. +- Go to a custom destination. +- Update a dashboard filter (if the dashboard has a filter). + +SQL questions will only have the option to **Go to a custom destination**, and **Update a dashboard filter**. + +If your dashboard has a filter, you'll also see an option to [update the filter](#use-a-chart-to-filter-a-dashboard). + +## Open the drill-through menu + +For questions composed using the query builder, the default click behavior is to open the **drill-through menu**, which presents people with the option to [drill through the data](/learn/metabase-basics/querying-and-dashboards/questions/drill-through): + +![Drill-through menu](./images/drill-through-menu.png) + +## Custom destinations + +You can set custom destinations for all questions, including SQL questions. + +![Custom destinations](./images/custom-destination.png) + +Possible destinations include: + +- Dashboards +- Saved questions +- URLs + +Internal Metabase destinations (dashboards or saved questions) will load in the same browser tab or window. External URLs will open in a new tab or window. + +## Passing values to the destination + +If you're linking to a dashboard or a SQL question that has filters, you can pass values from the current dashboard to filters in the destination. + +For example, if you link to a dashboard that has a filter for `Category`, you can pass a value for `Category` from the origin question to the destination dashboard: + +![Pass value to dashboard](./images/pass-value.png) + +Once you select the column that contains the value you want to pass, the sidebar will display the column used to pass the value, as well as the target filter at the destination that Metabase will pass the value to: + +![Pass category to filter](./images/pass-category-to-filter.png) + +In the example above, when a user clicks on the **Orders by product category** card, Metabase will pass the clicked `Product -> Category` to the destination dashboard ("Interactive Dashboard"), which will then filter its cards by that `Category`. + +You can also send the currently selected value of a dashboard filter on the current dashboard to the destination. In [some plans](/pricing/), you can pass a user attribute provided by SSO to the destination, too. Those user attributes will show up as options when you click on one of the destination's filters (provided the values are compatible with that filter). + +When displaying questions as tables, you can select different click behaviors for different columns in the table. You can also modify the contents of the cells in a given column, replacing the value with custom text. For example, if you had a column that listed categories, you could change the text in the cell to read: "Click for details about {% raw %}{{Category}}{% endraw %}", where `Category` is the name of your column. + +You can also use values to construct URLs to external resources. + +![Enter a URL](./images/enter-a-url.png) + +From the **Click behavior** sidebar, select **Go to a custom destination** and link to **URL**. The **Enter a URL to link to** modal will pop up, allowing you to specify a URL, as well as a column or dashboard filter. + +What we need to do here is to type in the full URL of where a user should go when they click on a value in a card. But the really powerful thing we can do is to include variables in the URL. These variables will insert the value that the user clicks on into the URL. + +For example, we could type a URL like this: + +``` +https://www.metabase.com/search.html?query={% raw %}{{Category}}{% endraw %} +``` + +The important part is the `{% raw %}{{Category}}{% endraw %}` bit. What we’re doing here is referring to the `Category` that the user clicked on. So if someone clicks on the `Widget` bar in our chart, the value of the `Category` column for that bar (`Widget`) would be inserted into our URL: `https://www.metabase.com/search.html?query=Widget`. Your URL can use as many column variables as you want - you can even refer to the same column multiple times in different parts of the URL. To see which variables you can include in the URL, click on the dropdown menu **Values you can reference**. + +Next we’ll click **Done**, then **Save** our dashboard. Now when we click our chart, we’ll be taken to the URL that we entered above, with the value of the clicked bar inserted into the URL. + +To learn more, check out [Custom destinations: choose what happens when people click on charts in your dashboard](/learn/metabase-basics/querying-and-dashboards/dashboards/custom-destinations). + +## Use a chart to filter a dashboard + +If your dashboard contains at least one filter, you can set things up so that clicking on a chart in the dashboard will update a filter. + +When a user clicks on, say, a bar in a bar chart, you could send the value of the clicked bar to the filter, and update cards across the dashboard. We call this functionality **cross-filtering**. You can use this cross-filtering to make a chart behave as kind of "navigation question" that filters data across other cards. + +For example, clicking on the `Widget` bar will update the current dashboard's **category** filter to filter for `Widget`: + +![Cross-filtering](./images/cross-filter.png) + +To set up cross-filtering, choose a dashboard filter that you'd like to update on click, and a question to use to update that filter. You can think of this question as your "navigation question." Instead of wiring this navigation question up to the filter, you'll [wire up every other question on the dashboard to the filter](./filters). + +Below, we'll use the **Orders by product category question** as our navigation question, so we'll leave this question disconnected from the filter, and connect all the other questions to the **Category** filter. + +![Wiring up filter](./images/wiring-up-filter.png) + +With your filter wired up, stay in dashboard edit mode, and hover over the question you want to use as your navigation question to filter the dashboard. Click on the **click behavior** icon, then select the **Update a dashboard filter**. + +Metabase will list the filters you can update. Here we select the **Category** filter, and supply the value to that filter from the question's `Product -> Category` column. + +![Update a dashboard filter](./images/update-a-dashboard-filter.png) + +Click **Done** in the sidebar, then **Save** your dashboard. + +Now we can use our navigation question (Orders by product category) to interactively filter the data across your dashboard. When people click on a value in the navigation question, Metabase will send the clicked value to the filter, and update every card on the dashboard by filtering them for the clicked value - every card except for the navigation question: Orders by product category. The reason we don't want the navigation question to update is so that we can click on other bars to update the filter with a different value. + +To learn more, check out [Cross-filtering: using a chart to update a dashboard filter](/learn/metabase-basics/querying-and-dashboards/dashboards/cross-filtering). diff --git a/_docs/doc-update-detection/dashboards/introduction.md b/_docs/doc-update-detection/dashboards/introduction.md new file mode 100644 index 000000000..6b9536014 --- /dev/null +++ b/_docs/doc-update-detection/dashboards/introduction.md @@ -0,0 +1,355 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Dashboards +title: 'Introduction to dashboards' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/dashboards/introduction.md' +redirect_from: + - /docs/doc-update-detection/users-guide/07-dashboards +--- + +# Introduction to dashboards + +![Interactive dashboard](./images/interactive-dashboard.png) + +## What is a dashboard? + +**Dashboards** group a set of questions into tabs on a single page. You can think of dashboards as shareable reports that feature a set of related questions. You can set up [subscriptions to dashboards](./subscriptions) via email or Slack to receive the exported results of the dashboard's questions. + +A dashboard comprises a set of cards arranged on a grid. These cards can be: + +- [Questions](../questions/introduction). You can add questions from collections, or saved questions directly to a dashboard. +- [Text and header cards](#adding-headings-or-descriptions-with-text-cards) +- [Iframe cards](#iframe-cards) +- [Link cards](#link-cards) + +You can add [filter widgets to dashboards](./filters) that filter data identically across multiple questions, and [customize what happens when people click on a chart or a table](./interactive). + +You can make as many dashboards as you want. Go nuts. + +## How to create a dashboard + +In the top right of the screen, click the **+ New** > **Dashboard**. Give your new dashboard a name and a description, choose which [collections](../exploration-and-organization/collections) the dashboard should go in, then click **Create**, and Metabase will take you to your shiny new dashboard. + +## Adding or saving questions to a dashboard + +You can add questions that are saved to collections, or save questions directly to a dashboard. + +### From a dashboard + +When editing a dashboard, you can add a question by clicking the **+** icon in the top right. You can add a chart from a new question, SQL/native query, or an existing question. + +You can't add questions that are saved to other dashboards. If you want to add a question to multiple dashboards, you should save that question to a collection. Alternatively, if the questions don't need to stay in sync, you could duplicate a question, and save that duplicate to your dashboard. Just keep in mind that changes to one question won't affect the duplicate question. + +### From a question + +When creating or editing a question, you can [save the question directly to a dashboard](../questions/introduction#saving-questions-to-dashboards). That question can only be used by that dashboard. + +### Adding a question saved to a collection + +To add a question saved to a collection to a dashboard, visit the question and click on the three-dot menu (**...**) at the top right and select **Add to dashboard**. You can also [browse questions from dashboard edit mode](#from-a-dashboard). + +Adding a question to a dashboard does not save the question to the dashboard. + +If a question is saved to your personal collection, you'll only be able to add that question to dashboards _in_ your personal collection. If you want to add the question to a dashboard in a public collection, you'll need to move your question out of your personal collection. + +## Adding headings or descriptions with text cards + +Another neat thing you can do is add heading and text cards to your dashboards. Text cards allow you to include descriptions, explanations, notes, or even images and GIFs to your dashboards. You can also use text cards to create separations between sections of charts in your dashboards, or include links to other dashboards, questions, or websites. + +To add a new text card, create a new dashboard (or edit an existing one) and click on the text card button, **T**, in the top-right: + +![Text card button](images/text-card-button.png) + +You have two options: + +- **Heading**: a preformatted heading text card that spans the width of the dashboard. +- **Text**: a customizable text card that will render Markdown-formatted text. + +Each text card has two modes: writing and previewing. When you click to focus on the card, the card will enter editing mode. When you click away from the card, Metabase will render the card to show you what it will look like on the live dashboard. + +![Markdown](images/markdown.png) + +You can use [Markdown](http://commonmark.org/help/) to format the text in your text card, create inline tables or code snippets, or even embed linked images (easy on the GIFs, friends). To preview the rendered card, just click away from the card. + +![Result](images/result.png) + +To learn more, see [Fun with Markdown in your dashboards](/learn/metabase-basics/querying-and-dashboards/dashboards/markdown). + +### Including variables in text cards + +You can include a variable in a text card, then wire that variable up to a dashboard filter. All you need to do to create a variable is to wrap a word in double braces, `{% raw %}{{{% endraw %}` and `{% raw %}}}{%endraw%}` (the variable can't contain any spaces). For example, you could add a text card with the following text: + +``` +{% raw %} +# {{state}} orders +{% endraw %} +``` + +And connect that variable to a dashboard filter widget that filters for states. If someone selected `WI` in the state filter, the text in the markdown card would read: **WI orders**. + +You can also make text optional by wrapping the text in double brackets, `[[` and `]]`: + +``` +{% raw %} +# Orders [[from {{state}}] +{% endraw %} +``` + +In this case, the phrase `{% raw %}from {{state}}{%endraw%}` would only display if someone selected a value (or values) in the filter widget. + +To see how to wire up a filter to a card, see [dashboard filters](./filters). + +## Link cards + +![Dashboards with link cards](./images/dashboard-with-link-cards.png) + +Link cards are specialized cards that let you search and link to other items in your Metabase. You can also use them for external links. Useful for pointing people to other resources relevant to your dashboard. + +To add a link card to a dashboard, click the **pencil** icon to enter dashboard editing mode, then click on the **link** icon. Click on the input field in the link card to search your Metabase for an item to link to, or paste an external link. + +Link cards support variables so you can use dashboard filters to update values in the link card's URL. For example, you could include a variable in a URL using double braces, like so: + +``` +{% raw %} +https://www.example.com/{{path}} +{% endraw %} +``` + +To provide values for the variable, you'll need to add a filter to the dashboard, and connect that filter to the card's variable (in this case `path`). Parameters are only supported for non-Metabase URLs (that is, URLs that you manually enter, not URLs you search and select from your Metabase). You can optionally set a default value for the variable. See [Connecting a filter or parameter widget to dashboard cards](./filters#connecting-a-filter-or-parameter-widget-to-dashboard-cards). + +## Iframe cards + +[Iframes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) allow you to nest one HTML page in another HTML page. With iframe cards in Metabase, you can embed a webpage in your dashboard. You can embed: + +- Spreadsheets or surveys for data entry or workflows +- Videos or slides for contextualizing and storytelling on dashboards +- Live charts and visualizations from other tools + +To add an iframe card to a dashboard, click the **pencil** icon to enter dashboard editing mode, then click on the **link** icon and select **Iframe**. Then paste the iframe URL. Here's an iframe for our video on how to create a dashboard: + +```html + +``` + +And behold, a dashboard with an embedded video: + +![Dashboard with iframe of video](./images/dashboard-with-iframe.png) + +Iframe cards support variables so that you can use a filter widget to update values in the iframe. For example, you could include a variable in the iframe's `src` URL with double braces, like so: + +``` +{% raw %} +src="https://www.youtube.com/embed/{{video_id}} +{% endraw %} +``` + +To provide values for the variable, you'll need to add a filter to the dashboard, and connect that filter to the card's variable (in this case `video_id`). You can optionally set a default value for the variable. See [Connecting a filter or parameter widget to dashboard cards](./filters#connecting-a-filter-or-parameter-widget-to-dashboard-cards). + +## Dashboard tabs + +You can add multiple tabs to a dashboard to keep your cards organized. + +![Dashboard tabs](./images/dashboard-tabs.png) + +### Duplicate a tab + +When in dashboard edit mode, you can duplicate a tab and all the its cards by clicking on the down arrow next to the tab that you want to copy. + +### Moving cards between tabs + +See [Arranging cards](#arranging-dashboard-cards). + +## Duplicating a dashboard + +If you don't want to build a dashboard from scratch, or want to experiment by making changes to an existing dashboard without affecting the original, you can **duplicate** an existing dashboard. + +To duplicate a dashboard, click on the **...** menu in the upper right of the dashboard, and select **Duplicate**. + +By default, Metabase will create a new dashboard, with copies of the questions in the original dashboard (including the dashboard's tabs). Metabase will save the duplicated questions either to the target collection, or to the duplicated dashboard, depending on where the original questions were saved. + +Duplication only includes the dashboard, its card layout, filters, and (optionally) the questions. What's not copied: dashboard subscriptions, actions, or any sharing or embedding data settings. For example, if you copy a dashboard that has been made public, that copied dashboard will not be public by default. + +## Arranging dashboard cards + +To edit dashboard cards and move them around, click the **pencil** icon in the top right of a dashboard to enter the dashboard's editing interface. + +### Editing cards + +Once you're in edit mode, you'll see a grid appear. You can move and resize the cards in the dashboard to your liking and they'll snap to the grid. + +![Editing dashboard](images/duplicate-card.png) + +- **Duplicate a card**: hover over the card and click the Duplicate icon. +- **Move a card to a new tab**: hover over the card, click the move icon, and select that tab you want to move the card to. +- **Move a card within a tab**: click and drag the card. Other cards will move out of the way. +- **Resize a card**: click the handle at the bottom right corner of the card, and drag to resize. Nearby cards will move away to accommodate the new size. +- **Remove a card**: hover over the card and click the X icon in the top right corner. +- **Replace a card**: hover over the card and click the Replace icon in the top right corner. Search for a question to swap in for the existing question on that card. You can only replace a question with another question, not another type of card (like a text card). + +Metabase will automatically update a question's display to make sure your data looks great at any size you choose. + +### Dashboard sections + +To speed up card arrangement, you can add **sections** to your dashboards. + +![Add section](./images/add-section.png) + +Sections are templates with headings and pre-arranged cards. Once you add a section to a dashboard, you can pick questions for each card, and make any other changes you like. You can only pick questions for cards, not another type of card (like a text card). + +If you forget to set a question for a card, the dashboard will simply render a blank card. + +Sections include: + +**KPI Grid** + +![KPI Grid](./images/kpi-grid.png) + +**Large chart with KPIs to the right** + +![Large chart with KPIS to the right**](./images/large-chart-with-kpis-to-the-right.png) + +**KPIs with large chart below** + +![KPIs with large chart below](./images/kpis-with-large-chart-below.png) + +## Dashboard width + +You can change the width of a dashboard by going into the three dots menu in the upper right: + +![Change dashboard width](./images/toggle-width.png) + +- **Fixed width** (default). Metabase will restrict the layout to a fixed width in the center of the screen. This fixed width can keep dashboard layouts consistent between smaller laptop screens and larger desktop screens. +- **Full width**. The layout and cards will expand to take up the full width of the screen. + +## Changing a card's visualization settings + +You can change a card's visualization settings (to add a goal line, for example). Changing a card's visualization settings will only affect how the question appears on that dashboard card; these changes won't affect the original question's visualization settings. + +Click on the **pencil** icon to enter dashboard edit mode, hover over the question you want to edit, and click on the **palette** icon to edit a card's visualization's settings. + +![Visualization settings](images/visualization-settings.png) + +### Hiding a card when it doesn't return results + +One neat thing to call out: if you have a question card that rarely returns results, but you still want to include that card in your dashboard because you want to know when the question _does_ return results, you can tell Metabase to hide the card unless it returns at least one row of data. + +When in dashboard edit mode, click on the **Visualization settings** for the card. + +- If the card displays a table, the option is in the **Columns** tab. +- If the card displays a chart, the option is in the **Display** tab. + +Toggle the option **Hide this card if there are no results**. When you turn on this option, the query will still run in the background, but the dashboard won't display the card. If the query returns results, the dashboard will display the card, moving the other cards around to make room for it according to how you've arranged the cards in dashboard edit mode. + +### Resetting a card's visualization settings + +If you want to revert a dashboard card to its original visualization settings (i.e., the settings on the question when it was _first_ saved to your dashboard): + +1. Go to your dashboard and click the **pencil icon** to go into edit mode. +2. Hover over the card (question) that you want to edit. +3. Click the **palette icon** to bring up the visualization settings for that card. +4. Click **Reset to defaults**. +5. Click **Done** to save the card's visualization settings. +6. Click **Save** to save the dashboard. + +## Fullscreen dashboards + +After you've made your ideal dashboard, you may want to put the dashboard on a TV to help keep your team up to date throughout the day. + +To enter fullscreen mode, click the **fullscreen** icon in the top right of the dashboard (the icon with the arrows pointing in opposite directions). Once you've entered fullscreen mode, you can also switch the dashboard into "Night mode" for higher contrast. + +![Night mode](images/dark-mode.png) + +## Auto refresh + +If your data updates frequently, you can set up your dashboard to refresh automatically by clicking on the **clock** icon. + +![Autorefresh](./images/autorefresh.png) + +You can set your dashboard to update in 1, 5, 10, 15, 30, and 60 minute intervals, depending on how fresh you need the data to be. + +Enabling auto refresh will re-run all the queries on the dashboard at the interval you choose, so keep the size of the dashboard and the complexity of the questions in mind when setting up auto refresh. + +Combining fullscreen mode and auto refresh is a great way to keep your team in sync with your data throughout the day. + +## Caching dashboard results + +{% include plans-blockquote.html feature="Caching dashboard results" %} + +See [Caching per dashboard](../configuring-metabase/caching#dashboard-caching-policy). + +## Sharing dashboards with public links + +If your Metabase administrator has enabled [public sharing](../embedding/public-links) on a saved question or dashboard, you can go to that question or dashboard and click on the **sharing** icon to find its public links. + +![Share icon](./images/share-icon.png) + +Public links can be viewed by anyone, even if they don't have access to Metabase. You can also use the public embedding code to embed your question or dashboard in a simple web page or blog post. Check out examples of simple apps with embedded dashboards in our [embedding-reference-apps repository](https://github.com/metabase/embedding-reference-apps). To learn more about [embedding](../embedding/introduction), check out our article on [How to use Metabase to deliver analytics to your customers](/learn/metabase-basics/embedding/overview), as well as an article on how to combine branding, Single Sign-On, full app embedding, and data sandboxing to deliver [multi-tenant, self-service analytics](/learn/developing-applications/advanced-metabase/multi-tenant-self-service-analytics). + +## Exporting results from a dashboard + +See [Exporting results](../questions/exporting-results). + +## Configuring a dashboard through its URL + +You can amend the URL of a dashboard to automatically enter fullscreen, enable night mode, or auto-refresh the dashboard. Customizing the dashboard's URL allows you to configure the dashboard - even when you do not have any input access to the device where the dashboard will be displayed, like scripted screens, for example. + +To configure a dashboard using its URL, you can add the following optional keywords: + +- `fullscreen` +- `night` +- `refresh` + +Here's an example URL: + +``` +https://metabase.mydomain.com/dash/2#refresh=60&fullscreen&night +``` + +The part that says `refresh=60` sets the dashboard to automatically refresh every 60 seconds, `fullscreen` sets it to fullscreen mode, and `night` sets it to night mode (night mode only works when using fullscreen). Use an ampersand, `&`, in between keywords, and make sure there's a hash, `#`, after the dashboard's ID number. + +There is one important limitation with the `fullscreen` option: for security reasons, many browsers require user interaction to initiate fullscreen. In those browsers, using the `fullscreen` option will enable the fullscreen UI in Metabase, but it won't expand the browser content to fill the screen. To ensure the dashboard occupies the entire screen, either activate fullscreen by clicking the button in the UI, or use the `fullscreen` URL option and launch the browser in fullscreen or kiosk mode. + +## Dashboard version history + +For [questions](../questions/start), dashboards, and [models](../data-modeling/models), Metabase keeps a version history for the previous fifteen versions of that item. + +See [History](../exploration-and-organization/history). + +## Verifying a dashboard + +See [content verification](../exploration-and-organization/content-verification). + +## Deleting a dashboard + +See [deleting and restoring](../exploration-and-organization/delete-and-restore). + +## Tips on creating helpful dashboards + +To make a great dashboard, you first need to decide what you want the dashboard to tell about your data. What questions will give you insight into what you want to know? It helps to think of a topic or theme for your dashboard — something like “customer satisfaction,” or “second quarter sales goals". + +Some tips: + +- **Emphasize the most important questions**. To draw people’s attention to what matters most, place the most important saved question cards near the top of the dashboard, and/or make them bigger than the other cards, +- **Keep dashboards focused**. If you have more than 10 cards on a dashboard, think about breaking the dashboard into two separate ones. You don't want to overwhelm people with too much information, and each dashboard should revolve around one theme or topic. Remember — you can make as many dashboards as you want, so you don’t have to cram everything into just one. +- **Add filters to your dashboard**. [Adding filters](./filters) to dashboards makes them more useful. For example, instead of your dashboard being full of questions that are restricted to a specific time span, you can make more general questions and use dashboard filters to change the time span you're looking at. +- **Make your dashboards interactive.** [Customize what happens when users click on a chart or table in your dashboard](./interactive). + +## Further reading + +- [Dashboard filters](./filters) +- [Interactive dashboards](./interactive) +- [Dashboard charts with multiple series](./multiple-series) +- [Dashboard subscriptions](./subscriptions) +- [Making dashboards faster](/learn/metabase-basics/administration/administration-and-operation/making-dashboards-faster) diff --git a/_docs/doc-update-detection/dashboards/linked-filters.md b/_docs/doc-update-detection/dashboards/linked-filters.md new file mode 100644 index 000000000..1a21d7a28 --- /dev/null +++ b/_docs/doc-update-detection/dashboards/linked-filters.md @@ -0,0 +1,71 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Dashboards +title: 'Linked filters' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/dashboards/linked-filters.md' +--- + +# Linked filters + +You can **link filters** on a dashboard so that a child filter limits its values based on the value(s) applied by a parent filter. + +For example, let's say you want a filter for the state column to restrict the values available to a filter on the city column, so that if someone selects a state, they'll only be able to select cities in that state. To do this, you can link the city filter (child) to a (parent) state filter. + +![Linked filters](./images/field-values-linked-filters.png) + +## Set up tables for linked filters + +You can only link dashboard filters that are wired to database columns (not custom columns or summaries) on dashboard cards, because Metabase needs column metadata to create linked filters. Metabase needs to know what values are there in the columns, and how the columns in the parent and child relate to each other. + +Filters can only be linked when they're connected to columns that have an explicit relationship in the table metadata. By relationship, we mean that the columns should be either: + +- In the same table. +- In two different tables that have a foreign key relationship specified in the [table metadata](../data-modeling/metadata-editing). +- In two different tables that have a foreign key relationships to one or more intermediate tables, as specified in the [table metadata](../data-modeling/metadata-editing) + +![Setting up foreign key in table metadata](./images/foreign-key-linked-filters.png) + +If you try to set up linked filters between two columns that aren't connected, Metabase won't show an error, but you'll see that the values in the child filter aren't restricted by the parent filter. For more troubleshooting tips, see [Troubleshooting link filters](../troubleshooting-guide/linked-filters). + +## Set up linked filters + +You can link a child filter to one or more parent filters. The child filter must be either an ID, Location, or Text or Category filter. Parent filters can be any [filter type](./filters). + +To link a child filter on a dashboard to one or more parent filters: + +1. Edit the dashboard by clicking on the pencil icon in the top right of the dashboard. +2. Edit the child filter by clicking on the gear icon in the filter. +3. In the filter settings sidebar, switch to **Linked filters** tab. +4. Select the parent filter(s). + +![Linked filters](./images/linked-filter.png) + +The filter(s) you select in the **linked filters** tab will be the parent filter(s), that is, the filter(s) that limit the values this (child) filter that you're currently editing. + +## Limitations of linked filters + +### Linked filters ignore relationships defined by models and questions + +Linked filters are only "aware" of relationships defined in the table metadata. This constraint lets people connect filters to the same column on multiple dashboard cards (across multiple tabs), but the constraint also means that: + +- Linked filters can't see relationships defined by joins in models or questions. +- Linked filters can't use any filter or join logic from any underlying card or model + +For example, say you have a table with State and City columns, and you build a model that filters out rows with `City = San Francisco`. You ask a question based on that model, and add it to a dashboard. You add State and City filters to the dashboard, and link them. If you select were to select `State = CA`, the city filter may still show `San Francisco` as option, even though there are no records with `San Francisco` in the question and the underlying model, because the filter only "knows" about the underlying table metadata (which includes sample values for the column). + +### Linked filters don't work with custom columns or summaries + +Metabase uses database column metadata to populate values for linked filters, which means that linked filters have to be connected to database columns. In particular: + +- You can't create linked filters on custom columns + +- Native/SQL questions must have a [field filter](../questions/native-editor/sql-parameters#the-field-filter-variable-type) variable in order to be linked. Basic SQL variables aren't connected to database columns, so they won't work for linked filters. + +- You can't link filters that use "Custom List" or "From another model or question" as their value's source. + +## Troubleshooting linked filters + +If you're not seeing what you expect with linked filters, make sure that your table relationships are [set up to support linked filters](#set-up-tables-for-linked-filters) . See [Troubleshooting linked filters](../troubleshooting-guide/linked-filters) for more troubleshooting information. diff --git a/_docs/doc-update-detection/dashboards/multiple-series.md b/_docs/doc-update-detection/dashboards/multiple-series.md new file mode 100644 index 000000000..0a2f893da --- /dev/null +++ b/_docs/doc-update-detection/dashboards/multiple-series.md @@ -0,0 +1,110 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Dashboards +title: 'Charts with multiple series' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/dashboards/multiple-series.md' +redirect_from: + - /docs/doc-update-detection/users-guide/09-multi-series-charting +--- + +# Charts with multiple series + +Data in isolation is rarely all that useful. One of the best ways to add context and clarity when communicating with data is to show data side-by-side with other data. Here are just a few examples of data that is better together than apart. + +- Your company’s revenue vs. its costs over time. +- Average order price this month and user signups for that month. +- New users per day vs. returning users per day. +- Orders per day from a few different product lines. + +## Displaying data side by side + +There are two main ways to visualize data side by side: + +1. [**Ask a question that involves multiple dimensions**](#ask-a-question-that-involves-multiple-dimensions) with the query builder (or in SQL, if you’re fancy). Example: the count of users by region over time. + +2. [**Combine two saved questions**](#combining-two-saved-questions) that share a common dimension (like time) on a dashboard. For example, you could look at revenue over time and costs over time together. + +## Ask a question that involves multiple dimensions + +If you’re creating a new question, you can view the results as a multi-series visualization by summarizing your data and grouping it into two groups. + +As an example, we might want to see which website or service is referring the most people to our website. In the **Sample Database** that ships with Metabase, you would group by the `Source` and `Created At` columns of the **People** table. + +To create the multi-series chart, select the **People** table, click on the **Summarize** button in the upper right, then add `Source` and `Created At` as groupings (the `count of rows` metric that we want is selected by default). Be sure to click the plus button to the right of your selection, so Metabase knows to add the grouping; otherwise, Metabase will switch to that grouping. [Learn more about asking questions](../questions/start). + +Metabase will automatically display a multi-series line chart visualization of how each referrer has performed for us. + +![multi-series in the query builder](./images/multi-series_query_builder.png) + +You can also create a multi-series chart by composing a custom question in the notebook editor. All you need to do is summarize your data (e.g., count the rows) and group that data into multiple groups (e.g. `Created At` by month and Product Category). + +![Composing a multi-series question in the notebook editor](./images/notebook_editor_multi-series.png) + +Note: you won’t be able to add another saved question to multi-series visualizations made in this fashion. Metabase can visualize up to 100 distinct values of a dimension at once, so if you're selecting a field that contains a lot of values, you might need to filter the values. + +## Combining two saved questions + +If you already have two or more saved questions you’d like to compare, and they have the same first dimension, they can be combined onto a single dashboard card. You can even compare questions that pull data from different databases. Here’s how: + +1. Add a question with a dimension like time or category to a dashboard. In practice, these will usually be line charts or bar charts. + +2. While in edit mode on the dashboard, hovering over a card will display some editing options in the upper right of the question, including an option to **add a line**, as well as a **gear** icon. Click on the add a line option (the **+** with a line and the word "Add" next to it). + +![add multi-series](./images/add_series.png) + +3. In the Edit Data modal, you’ll see the original question on the left, with a list of compatible questions you can choose from on the right. Search question(s) to add, and check the box next to each question you’d like to see alongside with the original. Metabase will add the question(s) to the same chart. + +![multi-series edit modal](./images/edit_modal.png) + +If necessary, the X and Y axes will automatically update. Metabase will create a legend using the existing card titles to help you understand which question maps to which series on the chart. Repeat this process as many times as you need. + +![Edit modal with multi-series](images/edit_modal_multi-series.png) + +To remove a series, simply uncheck its box. + +Once you have your chart looking how you’d like, hit done. Metabase will show your changes on the card in the dashboard. Depending on how dense your data is, at this point you might want to consider enlarging your chart to make sure the data is legible. + +> **SQL questions may not work**. Metabase has less information about SQL-based questions, so we cannot guarantee they can be added reliably. You'll see a little warning sign next to SQL questions to indicate this uncertainty, so be aware that adding these kinds of questions may not work. + +## Combining Number charts + +If you need to compare single numbers to get a sense of how they differ, Metabase can turn multiple number charts into a bar chart. + +As above, while editing a dashboard, hover over a number chart of your choice, and click on the icon with the **+** and bar chart icon to add a saved question. + +Use the search bar to find other saved question(s) that you’d like to see represented on the bar chart, and click the checkbox to add them to your chart. In this case, we added **Widget orders** to compare them to **Gadget orders**. + +![From numbers to bar chart](./images/numbers_to_bar_chart.png) + +## Multi-series charts, values, and legibility + +When displaying multiple series, it’s important to keep legibility in mind. Combining many series can sometimes decrease the communication value of the data. + +Metabase allows you to add values to multi-series charts, but go easy on this feature, especially on charts with lots of data points. Adding values to multiple series, each with many data points, can make charts more difficult to read. + +From the **Visualization > Display** options, you can toggle the option: **Show values on data points**. Metabase will do its best to fit as many values as can fit nicely. You can also force Metabase to (begrudgingly) show values for all data points, by setting the **Values to show** to **All**. + +![add values to multi-series chart](./images/add_values.png) + +You can also toggle values for each individual series. If you have three series, for example, you can show values on one, two, or all three series. + +- For a question with multiple dimensions, go to **Visualization > Data** tab, click on the three dots menu **...** to the right of a series, and toggle **Show values for this series** to show or hide its values. + +- For a dashboard card that combines multiple saved questions, go to the **Visualization > Display** tab, click on the down arrow to the right of a series to expand its details, and toggle **Show values for this series** to show or hide its values. + +You can also toggle values for the whole chart, then selectively hide values for individual series until you have your chart looking just right. + +Additionally, there is an option to configure the formatting of the values: + +- **Auto**. Metabase selects the appropriate style for you +- **Compact**. Metabase abbreviates values, e.g., 1,000 becomes 1K. +- **Full**. Values are displayed in their natural beauty. + +Now go forth and start letting your data get to know each other! + +## Further reading + +- [Time series comparisons](/learn/metabase-basics/querying-and-dashboards/time-series/time-series-comparisons) diff --git a/_docs/doc-update-detection/dashboards/start.md b/_docs/doc-update-detection/dashboards/start.md new file mode 100644 index 000000000..c8030659e --- /dev/null +++ b/_docs/doc-update-detection/dashboards/start.md @@ -0,0 +1,37 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: Dashboards +title: 'Dashboards overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/dashboards/start.md' +--- + +# Dashboards overview + +![Example dashboard](./images/dashboard.png) + +## [Introduction to dashboards](./introduction) + +Learn how to arrange tables, charts, and text cards on a dashboard. + +## [Dashboard filters](./filters) + +Add filters to dashboards to update tables and charts. + +## [Interactive dashboards](./interactive) + +Customize what happens when people click on a chart in your dashboard. + +## [Charts with multiple series](./multiple-series) + +Combine multiple questions on a single chart. + +## [Dashboard subscriptions](./subscriptions) + +Set up a dashboard to email or Slack its results on a schedule. + +## [Actions on dashboards](./actions) + +Add action buttons to dashboards. diff --git a/_docs/doc-update-detection/dashboards/subscriptions.md b/_docs/doc-update-detection/dashboards/subscriptions.md new file mode 100644 index 000000000..9410802fb --- /dev/null +++ b/_docs/doc-update-detection/dashboards/subscriptions.md @@ -0,0 +1,146 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Dashboards +title: 'Dashboard subscriptions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/dashboards/subscriptions.md' +redirect_from: + - /docs/doc-update-detection/users-guide/dashboard-subscriptions + - /docs/doc-update-detection/enterprise-guide/dashboards-subscriptions +--- + +# Dashboard subscriptions + +Dashboard subscriptions allow you to send the results of questions on a dashboard to people via email or Slack - even to people who lack an account in your Metabase. + +If your Metabase has email or Slack set up, all you need to do is create a dashboard, add subscribers to it, and tell Metabase how often you'd like the send out an update. You can set up as many subscriptions to a dashboard as you like, and if you make any changes to the dashboard, Metabase will update the subscriptions the next time they're delivered. + +## Enabling dashboard subscriptions + +To enable dashboard subscriptions, your administrators will need to have set up email or Slack for your Metabase. See [Setting up email](../configuring-metabase/email) or [Setting up Slack](../configuring-metabase/slack). + +## Setting up a dashboard subscription + +To set up a subscription to a dashboard, click on the **Sharing** icon and select **Subscriptions**. Metabase will slide out a sidebar on the right, with an option to set up a subscription via email or Slack: + +![Set up a dashboard subscription with email or slack](./images/email-or-slack.png) + +Let's say we want to email a dashboard. We'll click on the **Email it** option in the sidebar, and Metabase will give us some options: + +![Dashboard subscription email options](./images/email-options.png) + +## Email subscription options + +For emails, we can: + +### Add subscribers + +Add email addresses to register subscribers. On Metabase [Pro](/product/pro) and [Enterprise](/product/enterprise), admins can limit email recipients to [approved domains for notifications](../configuring-metabase/email#approved-domains-for-notifications) and [configure which recipients Metabase suggests](../configuring-metabase/email#suggest-recipients-on-dashboard-subscriptions-and-alerts). + +### Determine frequency and timing + +Tell Metabase how often it should send the dashboard: + +- Hourly +- Daily +- Weekly +- Monthly + +And what time of day to send the dashboard. + +### Send email now + +A button that sends an email to all subscribers each time you touch it. + +### Don't send if there aren't results + +If there are no results, you can tell Metabase to skip sending the email. + +### Set filter values for when this gets sent + +{% include plans-blockquote.html feature="Dashboard subscription filter customization" %} + +Here you can set filters to apply when Metabase sends the subscription. + +### Attach results + +Tell Metabase if it should attach results to the email as a file, in addition to displaying the table in the email body. + +If you've added filters to your dashboard and set default values for those filters, Metabase will apply those default values to your subscriptions, filtering the results of all questions that are connected to those filters when the subscriptions are sent. To learn more, check out [dashboard filters](./filters). + +#### File format + +You can choose between the following file formats: + +- .csv +- .xlsx +- .json + +#### Use unformatted values in attachments + +If you check this box, Metabase will drop any visualization settings applied to the questions' results (e.g., date formatting) and send only the raw, unformatted results. + +#### Questions to attach + +Here you can specify which questions Metabase should attach results for. + +The attached files will include up to 2000 rows by default. If you're self-hosting Metabase, you can adjust this row limit by setting the environment variable [MB_UNAGGREGATED_QUERY_ROW_LIMIT](../configuring-metabase/environment-variables#mb_unaggregated_query_row_limit). To change this row limit on your Metabase Cloud instance, you can [contact us](/help/premium) and request a different row limit. + +## Slack subscription options + +For Slack subscriptions, you can set up a subscription for a channel (like #general), or for a single person via their Slack username. + +> Note that Slack username can be different from Slack display name. + +![slack subscription options](./images/slack-subscription-options.png) + +> If you rename the subscribed channel in Slack, you'll need to update the subscription to point to the new Slack channel name. + +You can specify how often Metabase sends a Slack message (hourly, daily, weekly, or monthly), and whether to send a message if the dashboard fails to return results. + +### Sending subscriptions to private channels + +See [Sending alerts and subscriptions to private Slack channels](../configuring-metabase/slack#sending-alerts-and-subscriptions-to-private-slack-channels). + +## Adding multiple subscriptions + +You can add multiple subscriptions to a single dashboard. To add a subscription, click on the **+** icon in the dashboard subscription panel. + +## Deleting a subscription + +To remove a subscription from a dashboard, select the subscription you'd like to remove. At the bottom of the sidebar, select **Delete this subscription**. Follow the instructions on the modal that pops up to confirm you'd like to delete the subscription. + +## Viewing existing dashboard subscriptions + +{% include plans-blockquote.html feature="Usage analytics" %} + +You can view a list of all alerts and dashboard subscriptions that people have set up in your Metabase in **Usage analytics** collection. See [Usage analytics](../usage-and-performance-tools/usage-analytics). + +## Customize filter values for each dashboard subscription + +{% include plans-blockquote.html feature="Dashboard subscription filter customization" %} + +You can customize which filter values to apply to each dashboard subscription. That way you can send different groups of people an email (or Slack message) the contents of the dashboard with different filters applied. You only need to maintain one dashboard, which you can use to send results relevant to each subscriber. + +### Setting filter values + +You can set values for each filter on the dashboard. If you have any dashboard filters with default values, you can override those defaults for a given subscription, or leave them as-is. + +Here's the sidebar where you can set the filter values: + +![Setting a filter value](./images/set-filter-values.png) + +The section to call out here is the **Set filter values for when this gets sent**. Here we've set "VT" as the value for the dashboard's State filter to scope results to records from Vermont. We didn't set a value for the Created_At filter, so the subscription will send the results without a filter applied. If you've set a default value for the filter, the subscription will list the value here. + +## How permissions work with dashboard subscriptions + +See [Notification permissions](../permissions/notifications). + +## Further reading + +- [Alerts](../questions/alerts) +- [Setting up email](../configuring-metabase/email) +- [Setting up Slack](../configuring-metabase/slack) +- [Usage analytics](../usage-and-performance-tools/usage-analytics) diff --git a/_docs/doc-update-detection/data-modeling/field-types.md b/_docs/doc-update-detection/data-modeling/field-types.md new file mode 100644 index 000000000..6ae3ef1b4 --- /dev/null +++ b/_docs/doc-update-detection/data-modeling/field-types.md @@ -0,0 +1,161 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Data Modeling' +title: 'Field types' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/data-modeling/field-types.md' +redirect_from: + - /docs/doc-update-detection/users-guide/field-types +--- + +# Field types + +While data types indicate to a database how it should interpret the values in a field, **field types** or **semantic types** describe the _meaning_ of a field. For example, a column's data type could be `type/text` but the semantic type may be **Email**. Field types are just one example of metadata—information about data—that [Admins can change](./metadata-editing) in Metabase. + +Field types dictate how Metabase displays its data, as well as the column’s special functionality, if any. By marking columns in a table as **Latitude** and **Longitude**, Metabase can use the columns to create pin and heat maps. Similarly, designating a column as a **URL** allows users to click on the link to visit that URL. + +## Overall Row + +- **Entity Key**: The field in this table that uniquely identifies each row. Could be a product ID, serial number, etc. +- **Entity Name**: Different from the entity key, the entity name represents what each row in the table _is_. For example, in a Users table, you might want to use a field containing usernames as the entity name. +- **Foreign Key**: The column in this table that (usually) refers to the entity key of another table in order to connect data from different tables that are related. For example, in a Products table, you might have a Customer ID field that points to a Customers table, where Customer ID is the primary key. + +## Common + +Common field types are text/varchar types. + +- **Category**: If set to category, Metabase will know that it can use this field to group results when creating questions for automatic insights like [X-rays](../exploration-and-organization/x-rays). +- **Comment** +- **Description** +- **Title** + +## Location + +Marking fields as locations tell Metabase that it can use the field to display data on a [map chart](../questions/visualizations/map). + +- **City** +- **Country** +- **Latitude**: Tells Metabase that the data could be plotted on a [pin map](../questions/visualizations/map). +- **Longitude**: Did you know that you can use the moons of Jupiter to calculate longitude? +- **State** +- **Zip Code** + +## Financial + +Financial field types tell Metabase to treat the field's values as money. If you select any of the financial field types, Metabase will ask which currency you want to use. Metabase treats each of the following types as money, their differences are purely semantic. + +- **Cost** +- **Currency** +- **Discount** +- **Gross margin** +- **Income** +- **Price** + +See [Currency formatting options](../questions/visualizations/table#currency-formatting-options). + +## Numeric + +Metabase will treat numeric field types as [numbers](../questions/visualizations/table#number-formatting-options). + +- **Percentage**: Displays the number as a percentage by default. +- **Quantity**: Displays the number as normal by default. +- **Score**: Displays the number as normal by default. +- **Share**: The same as percentage, so prefer "Percentage". + +See [Number formatting options](../questions/visualizations/table#number-formatting-options). + +## Profile + +Fields that deal with people. + +- **Birthday**. Date field. +- **Company**: Text field. +- **Email**: Displays as a [mailto](https://en.wikipedia.org/wiki/Mailto) link. +- **Owner**: Text field. +- **Subscription**: Text field. +- **User**: Text field. + +## Date and Time + +Date and time field types tell Metabase the field contains datetime values, so it can use date pickers and display time series (e.g., a line chart). + +If your database stores datetimes as a number or string, you can [cast that column to a datetime](./metadata-editing#casting-to-a-specific-data-type). + +- **Cancelation date** +- **Cancelation time** +- **Cancelation timestamp** +- **Creation date** +- **Creation time** +- **Creation timestamp** +- **Deletion date** +- **Deletion time** +- **Deletion timestamp** +- **Updated date** +- **Updated time** +- **Updated timestamp** +- **Join date** +- **Join time** +- **Join timestamp** +- **UNIX Timestamp (Milliseconds)** +- **UNIX Timestamp (Seconds)** + +See [Date formatting options](../questions/visualizations/table#date-formatting-options). + +## Categorical + +- **Enum**: An abbreviation for “enumerated type,” the value of an enum draws on a predefined list of options. An example of an enum would be a field for the months of the year. This list of twelve options is defined in the makeup of the column, and no options outside this list would be valid. +- **Product** +- **Source**: For example, the source of a visitor to your website (such as a search engine or other website). + +## URLs + +Metabase can display fields with URLs as images or links. + +- **Avatar Image URL**: Displays the field as an image in table and detail views. +- **Image URL**: Displays the field as an image in table and detail views. +- **URL**: Displays the field as a link. + +## Other + +- **Field containing JSON**. See [Working with JSON](./json-unfolding) +- **No semantic type** – Used for fields that don't fall into any of the above field types. + +## Using field types in Metabase + +### Set column types in models to enable people to explore results with the query builder + +You can set field types for [models](./models), which helps Metabase understand how to work with data in models built using SQL. If you set each column type in a SQL model, people will be able to explore that model using the query builder and drill-through menus. + +With records that include integer entity keys, you can also configure text fields in models to [surface individual records in search](./models#surface-individual-records-in-search-by-matching-against-this-column). + +### X-rays + +When you [X-ray](../exploration-and-organization/x-rays) a table, model, or entity, Metabase considers both the data type and the field type to display different charts that summarize that data. + +### Field Filters + +Knowing what field types are and how they work is helpful when using [field filters](/learn/metabase-basics/querying-and-dashboards/sql-in-metabase/field-filters), as you can only create field filters for [certain field types](../questions/native-editor/sql-parameters#field-filter-compatible-types). + +### Editing types in the Table Metadata page + +If you're an administrator, you can edit field types using the [Table Metadata page](./metadata-editing) in the Admin Panel. + +While data types themselves can't be edited in Metabase, admins can manually [cast certain data types](./metadata-editing#casting-to-a-specific-data-type) to be read differently, like interpreting a numerical data type as a date format. + +> Metabase currently supports only casting to a datetime type in Metadata settings. + +### JSON unfolding + +See [Working with JSON](./json-unfolding). + +### Arrays + +Metabase currently does not support array types with any database. You'll only be able to use **Is empty** or **Is not empty** filters on columns containing arrays. + +## Further Reading + +- [Exploring data with Metabase's data browser](/learn/metabase-basics/querying-and-dashboards/data-browser). +- [The Table Metadata page: editing metadata](./metadata-editing). +- [Field Filters: create smart filter widgets for SQL questions](/learn/metabase-basics/querying-and-dashboards/sql-in-metabase/field-filters). diff --git a/_docs/doc-update-detection/data-modeling/formatting.md b/_docs/doc-update-detection/data-modeling/formatting.md new file mode 100644 index 000000000..777d7dc5f --- /dev/null +++ b/_docs/doc-update-detection/data-modeling/formatting.md @@ -0,0 +1,65 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Data Modeling' +title: 'Formatting defaults' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/data-modeling/formatting.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/19-formatting-settings +--- + +# Formatting defaults + +There are Metabase users around the world, each with different preferences for how dates, times, numbers, and currencies should be formatted and displayed. Metabase allows you to customize these formatting options at three different levels: + +1. **Global**. Set global defaults in the [Localization](../configuring-metabase/localization) section in Admin -> Settings -> Localization. +2. **Field**. Set field (column) defaults in Admin -> Table Metadata. Field defaults override global defaults. +3. **Question**. Set formatting defaults for individual questions in the visualization settings of that question. Question defaults override global and field defaults. + +## Field-level formatting + +You can override the global defaults for a specific field by going to the `Table Metadata` section of the Admin Panel, selecting the database and table of the field in question, and clicking the gear icon on the far right of the screen next to that field to go to its options page, then clicking on the `Formatting` tab. + +The options you'll see here will depend on the field's type. They're generally the same options as in the global formatting settings, with a few additions: + +### Dates and Times + +- `Show the time:` this lets you choose if this time field should be displayed by default without the time; with hours and minutes; with hours, minutes, and seconds; or additionally with milliseconds. + +### Numbers + +- `Show a mini bar chart:` only applies to table visualizations. Displays a bar for each value to show large or small it is relative to the other values in the column. +- `Style:` lets you choose to display the number as a plain number, a percent, in scientific notation, or as a currency. +- `Separator style:` this gives you various options for how commas and periods are used to separate the number. +- `Number of decimal places:` forces the number to be displayed with exactly this many decimal places. +- `Multiply by a number:` multiplies this number by whatever you type here. +- `Add a prefix/suffix:` lets you put a symbol, word, etc. before or after this number. + +### Currency + +Currency field formatting settings include all the same options as in the global formatting section, as well as all the options that Number fields have. + +See [Currency formatting options](../questions/visualizations/table#currency-formatting-options). + +## Question-level formatting + +Lastly, you can override all formatting settings in any specific saved question or dashboard card by clicking on the gear to open up the visualization options. To reset any overridden setting to the default, just click on the rotating arrow icon next to the setting's label. This will reset the setting to the field-level setting if there is one; otherwise it will be reset to the global default. + +Formatting options vary depending on the type of visualization: + +- [Combo chart](../questions/visualizations/combo-chart) +- [Detail](../questions/visualizations/detail) +- [Funnel](../questions/visualizations/funnel) +- [Gauge](../questions/visualizations/gauge) +- [Line, Bar, and area charts](../questions/visualizations/line-bar-and-area-charts) +- [Maps](../questions/visualizations/map) +- [Numbers](../questions/visualizations/numbers) +- [Pie or donut chart](../questions/visualizations/pie-or-donut-chart) +- [Pivot table](../questions/visualizations/pivot-table) +- [Progress bar](../questions/visualizations/progress-bar) +- [Scatter plot or bubble chart](../questions/visualizations/scatterplot-or-bubble-chart) +- [Tables](../questions/visualizations/table) +- [Trend](../questions/visualizations/trend) +- [Waterfall chart](../questions/visualizations/waterfall-chart) diff --git a/_docs/doc-update-detection/data-modeling/images/AddSegment.png b/_docs/doc-update-detection/data-modeling/images/AddSegment.png new file mode 100644 index 000000000..ca3e5390d Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/AddSegment.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/CreateSegment.png b/_docs/doc-update-detection/data-modeling/images/CreateSegment.png new file mode 100644 index 000000000..01dda9696 Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/CreateSegment.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/EditMessage.png b/_docs/doc-update-detection/data-modeling/images/EditMessage.png new file mode 100644 index 000000000..d789d4dcc Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/EditMessage.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/FinishedSegment.png b/_docs/doc-update-detection/data-modeling/images/FinishedSegment.png new file mode 100644 index 000000000..f20413fa0 Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/FinishedSegment.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/Segment.png b/_docs/doc-update-detection/data-modeling/images/Segment.png new file mode 100644 index 000000000..7d42b3898 Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/Segment.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/SegmentActions.png b/_docs/doc-update-detection/data-modeling/images/SegmentActions.png new file mode 100644 index 000000000..8761b49c7 Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/SegmentActions.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/column-settings.png b/_docs/doc-update-detection/data-modeling/images/column-settings.png new file mode 100644 index 000000000..b586ed96e Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/column-settings.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/common-metrics.png b/_docs/doc-update-detection/data-modeling/images/common-metrics.png new file mode 100644 index 000000000..de62e21fc Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/common-metrics.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/entity-picker-metrics-tab.png b/_docs/doc-update-detection/data-modeling/images/entity-picker-metrics-tab.png new file mode 100644 index 000000000..d4fb36f9a Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/entity-picker-metrics-tab.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/format-as-url.png b/_docs/doc-update-detection/data-modeling/images/format-as-url.png new file mode 100644 index 000000000..233f72989 Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/format-as-url.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/formula.png b/_docs/doc-update-detection/data-modeling/images/formula.png new file mode 100644 index 000000000..8087cdd4c Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/formula.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/metrics-built-on-other-metrics.png b/_docs/doc-update-detection/data-modeling/images/metrics-built-on-other-metrics.png new file mode 100644 index 000000000..70f5fdfcc Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/metrics-built-on-other-metrics.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/original-schema.png b/_docs/doc-update-detection/data-modeling/images/original-schema.png new file mode 100644 index 000000000..88561335b Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/original-schema.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/pinned-metrics.png b/_docs/doc-update-detection/data-modeling/images/pinned-metrics.png new file mode 100644 index 000000000..5b76103b6 Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/pinned-metrics.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/table-metadata.png b/_docs/doc-update-detection/data-modeling/images/table-metadata.png new file mode 100644 index 000000000..ea68179f9 Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/table-metadata.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/table-with-json-column.png b/_docs/doc-update-detection/data-modeling/images/table-with-json-column.png new file mode 100644 index 000000000..3a9e702c1 Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/table-with-json-column.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/turn-into-a-model.png b/_docs/doc-update-detection/data-modeling/images/turn-into-a-model.png new file mode 100644 index 000000000..edcde276b Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/turn-into-a-model.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/unfold-json-setting.png b/_docs/doc-update-detection/data-modeling/images/unfold-json-setting.png new file mode 100644 index 000000000..36a7f2f92 Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/unfold-json-setting.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/unfolded-fields.png b/_docs/doc-update-detection/data-modeling/images/unfolded-fields.png new file mode 100644 index 000000000..e6878fbc7 Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/unfolded-fields.png differ diff --git a/_docs/doc-update-detection/data-modeling/images/unfolded-values.png b/_docs/doc-update-detection/data-modeling/images/unfolded-values.png new file mode 100644 index 000000000..b2a104a39 Binary files /dev/null and b/_docs/doc-update-detection/data-modeling/images/unfolded-values.png differ diff --git a/_docs/doc-update-detection/data-modeling/json-unfolding.md b/_docs/doc-update-detection/data-modeling/json-unfolding.md new file mode 100644 index 000000000..5d47c35e1 --- /dev/null +++ b/_docs/doc-update-detection/data-modeling/json-unfolding.md @@ -0,0 +1,78 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Data Modeling' +title: 'Working with JSON' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/data-modeling/json-unfolding.md' +--- + +# Working with JSON + +## Filtering JSON + +In the [query builder](../questions/query-builder/editor), Metabase can't parse JSON in columns, so you can only filter by "Is empty" or "Not empty". + +## JSON unfolding + +With [some databases](#databases-that-support-json-unfolding), Metabase can unfold JSON columns into their component fields, which you can then filter on using the query builder. + +Here is a table with a column that contains JSON. + +![A table with a JSON column](./images/table-with-json-column.png) + +Metabase can unfold that JSON column so that each key in the JSON object gets its own column in the table. Here are the unfolded fields of the table with the JSON column pictured above: + +![Unfolded fields](./images/unfolded-fields.png) + +And here are the values as seen in the table: + +![Unfolded values](./images/unfolded-values.png) + +This unfolding allows you to filter for values found in the original JSON object. + +Metabase will prefix the unfolded column names with the name of the original column that contained the JSON. You can change the column names in **Admin settings** > [Table metadata](metadata-editing), or by creating a [model](./models) and editing the column metadata. + +## Toggling JSON unfolding for a database + +If you notice a hit to performance from this JSON unfolding, we recommend turning it off. + +To turn off JSON unfolding for a database: + +1. Click on the **Gear** in the upper right. +2. Select **Admin settings** +3. Visit the **Databases** tab. +4. Select the relevant database. +5. Click **Show advanced options**. +6. Toggle **Allow unfolding of JSON columns**. +7. Scroll down and click the **Save changes** button. +8. Click **Sync database schema**. +9. Click **Re-scan field values**. + +## Toggling JSON unfolding for a specific column + +If performance degrades, or you'd rather keep the JSON contained in the original column, you can turn off unfolding for individual fields in their settings. + +1. Click on the **Gear** in the upper right. +2. Select **Admin settings**. +3. Visit the **Table metadata** tab. +4. Select the database that contains the field you want to update. +5. Select the table that contains the field. +6. Select the field containing the original JSON +7. Scroll to the **Unfold JSON** option and select **Yes** or **No**. If the column was unfolded, Metabase will have hidden this JSON columnn from view, so if you want the JSON column to be visible again, you'll need to change the column's visibility to **Everywhere**. +8. Scroll down and click on the **Re-scan this field**. + +![Unfolded JSON setting](./images/unfold-json-setting.png) + +## For JSON unfolding to work, the column's data type must be JSON + +For example, if you upload a CSV with JSON in it, you might need to update the data/type in the database. Note that you can't edit the data type via Metabase; you can only change its field type. So even if the field type in Metabase is `Field containing JSON`, if the data/type isn't `JSON`, Metabase won't give you the option to unfold the column. You'll need to change the column type in the database itself. + +## Databases that support JSON unfolding + +- [PostgreSQL](../databases/connections/postgresql) +- [MySQL](../databases/connections/mysql) +- [Druid (JDBC)](../databases/connections/druid) + +A note on [BigQuery](../databases/connections/bigquery): Metabase supports the [STRUCT data type](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type) in BigQuery, but it won't unfold JSON stored in BigQuery as the `JSON` type. If your data is stored in the `STRUCT` type in BigQuery, you can query the table's nested fields. Some background here: BigQuery differs from other databases in that nested fields are _part of the table definition itself_. So when Metabase syncs with your BigQuery database, it'll be able to get metadata about any of your tables, including tables with nested fields. Querying nested fields, however, doesn't extend to arrays (REPEATED (STRUCT)) in BigQuery. diff --git a/_docs/doc-update-detection/data-modeling/legacy-metrics.md b/_docs/doc-update-detection/data-modeling/legacy-metrics.md new file mode 100644 index 000000000..2380cc141 --- /dev/null +++ b/_docs/doc-update-detection/data-modeling/legacy-metrics.md @@ -0,0 +1,22 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Data Modeling' +title: 'Legacy metrics' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/data-modeling/legacy-metrics.md' +--- + +# Legacy metrics + +Metabase upgraded [metrics](./metrics) starting in version 51. + +If you're upgrading from Metabase 50 or earlier, all of your existing metrics will be migrated to the new metrics, which you can find in the Migrated Metrics V1 collection with curate access only for admins. You can leave the metrics there, or move them into different collections. + +## What's new with metrics + +- Anyone can create a new metric. +- Metrics can be stored (and pinned) to collections. +- If you have curate access to the collection, you can edit a metric in that collection. +- You can explore metrics in your Metabase in the data browser. diff --git a/_docs/doc-update-detection/data-modeling/metadata-editing.md b/_docs/doc-update-detection/data-modeling/metadata-editing.md new file mode 100644 index 000000000..1e67fc883 --- /dev/null +++ b/_docs/doc-update-detection/data-modeling/metadata-editing.md @@ -0,0 +1,259 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Data Modeling' +title: 'Table metadata admin settings' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/data-modeling/metadata-editing.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/03-metadata-editing +--- + +# Table metadata admin settings + +Metabase lets you add and edit metadata to your tables and columns so that you can manage your org's business logic as it changes. Go to the **Table Metadata** tab in your **Admin settings** to: + +- [Set display names and descriptions](#table-display-name). +- [Hide outdated data](#table-visibility). +- [Cast a text or number column to a date column](#casting-to-a-specific-data-type). +- [Change the style of a filter widget](#changing-the-filter-widget). +- [Display a column as a link](#displaying-a-column-as-a-link). + +> The **Table Metadata** admin settings only affect the way data's displayed and interpreted in Metabase. None of the settings will change the data in your database. + +## Table settings + +Click on a table name in the left sidebar to view the table's settings in Metabase. + +If you've got more than one database connected to Metabase, click on the database name (for example, "Sample Database") and select another database from the dropdown menu. Once you select a database, the tables in that database will appear in the sidebar. + +![Table metadata](./images/table-metadata.png) + +- [Change the display name](#table-display-name). +- [Add or edit the description](#table-description). +- [Show or hide the table across Metabase](#table-visibility). +- [View the original schema](#original-schema). +- [Edit column (field) settings](#column-field-settings). + +### Table display name + +To edit a table's display name in Metabase, click into the box that contains the current table name. Changes will be saved automatically once you click out of the box. + +### Table description + +To add a table description, click into the box below the table name. Descriptions are displayed in Metabase's [data reference](../exploration-and-organization/data-model-reference) to help people find the right table for their use case. + +### Table visibility + +**Queryable** tables are visible across all of Metabase. + +**Hidden** tables won't show up in the [query builder](../questions/query-builder/editor) or [data reference](../exploration-and-organization/data-model-reference). But this is not a security feature: hidden tables can still be used in SQL questions if someone writes `SELECT * FROM hidden_table` from the [SQL editor](../questions/native-editor/writing-sql). To prevent people from writing queries against specific tables, see [data permissions](../permissions/data). + +Tip: To hide all of the tables in a database (say, if you've migrated to a new database), click on the **hidden eye** icon beside "# queryable tables" in the left sidebar. + +### Original schema + +To remind yourself of column names and data types as they're stored in your database, click **Original schema** (below **Visibility**). + +![Original schema](./images/original-schema.png) + +## Column (field) settings + +Select a database and click on a table's name in the sidebar to bring up basic column display settings: + +- [Change the display name](#column-name) +- [Add or edit the description](#column-description) +- [Show or hide the column across Metabase](#column-visibility) +- [Set a default column order](#column-order) +- [Change the column's field type](#field-type) + +For extra column settings, click on the **gear** icon at the right of a column's settings box: + +![Column settings](./images/column-settings.png) + +- [Cast text or numbers to dates](#casting-to-a-specific-data-type) +- [Change the filter widget](#changing-the-filter-widget) (for example, to a dropdown menu) +- [Remap column values](#remapping-column-values) (for example, from "5" to "Great") +- [Display the column as a link](#displaying-a-column-as-a-link) + +### Column name + +To change the _global_ display name of a column in Metabase, click on the name of the column. For example, you could display "auth.user" as "User" to make the column more readable. People can use [models](./models) to give columns a display name that's local to the model. + +### Column description + +To add a description, click into the box below the column name. Descriptions are displayed in the [data reference](../exploration-and-organization/data-model-reference) to help people interpret the column's values. You should consider adding a description if your column contains: + +- abbreviations or codes +- zeroes, nulls, or blank values +- placeholder values, like `9999-99-99` + +### Column visibility + +**Everywhere**: by default, users can see all of the columns in a table. + +**Only in detail views** will hide lengthy text from question results. This setting is applied by default if a column's values have an average length of more than 50 characters. For example, you could use this setting on a column like "Customer Comments" if you already have a column for "Customer Rating". + +**Do not include** columns won't show up in the query builder or data reference. You can set "do not include" on sensitive columns (such as PII) or irrelevant columns. But this visibility option is a simple omit/hide option; it's not a security feature. These columns are still accessible for people with native query privileges; they can write `SELECT hidden_column FROM table` or `SELECT * from table` in the [SQL editor](../questions/native-editor/writing-sql) and they'll be able to view these fields and their values. To prevent people from viewing certain columns, see [data sandboxing](../permissions/data-sandboxes). + +### Column order + +Metabase defaults to the column order defined in your database schema. To reorder the column display order in question results and menus **manually**, click on the grab bar to the right of each column, and drag the column to a new position. + +To sort the columns **automatically**, click on the **sort** icon at the top right of the first column's settings box. The sorting options are: + +- **Database.** (Default) The order of columns as they appear in the database. +- **Alphabetical.** A, B, C... however the alphabet works. +- **Custom.** You choose the order. Metabase will automatically switch the sort order to "Custom" if you rearrange any of the columns. +- **Smart.** Metabase chooses for you. + +### Field type + +To change the [field type](../data-modeling/field-types) of a column, click on the **Type** dropdown menu in a column's setting box. You can also use the **Type** dropdown to label a column as an [entity key](/glossary/entity_key) (primary key) or [foreign key](/glossary/foreign_key) in Metabase (with no consequence to your database). + +### Casting to a specific data type + +If you want Metabase to treat a text or number column as a datetime column: + +1. Go to **Admin settings** > **Table Metadata**. +2. Find your database and table. +3. Click on the **gear** icon at the right of a column's settings box. +4. Scroll to **Cast to a specific data type** +5. Select a casting option. + +> Metabase currently supports only casting to a datetime type in **Cast to a specific data type**. If you need to cast to a different type (like float), you can [create a SQL question](../questions/native-editor/writing-sql#starting-a-new-sql-query) that casts the data and [save it as a model](./models#create-a-model-from-a-saved-question), or create a view directly in your database. + +**Text to datetime casting options**: + +- ISO8601->Date +- ISO8601->Datetime +- ISO8601->Time + +**Numeric to datetime casting options**: + +- UNIXMicroSeconds->DateTime +- UNIXMilliSeconds->DateTime +- UNIXNanoSeconds->DateTime +- UNIXSeconds->DateTime + +Casting is different from setting the [field type](./field-types). For example, say you have a "Created At" column with a string [data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview) in your database. You'll need to cast "Created At" to one of the datetime types above if you want to do things like: + +- Create relative date filters, such as "Created At = Last week". +- Use "Created At" with formulas like [datetimeAdd](../questions/query-builder/expressions/datetimeadd). + +> Casting data types from the **Table Metadata** admin settings won't affect the original data types in your database. + +### Changing the filter widget + +To change a column's [filter widget](../dashboards/filters): + +1. Go to **Admin settings** > **Table Metadata**. +2. Find your database and table. +3. Click on the **gear** icon at the right of a column's settings box. +4. Scroll to **Filtering on this field**. +5. Select a filter widget option. + +#### Filter widget options + +The default behavior for the `Is` filter for the field. + +- **Search box**: Display a search box and suggest autocompletions for values in that column that match the search term(s). +- **A list of all values**: Display a search box, as well as a list of checkboxes for values in a dropdown menu that people can select as search terms. +- **Plain input box**: Display a search box, but do NOT suggest autocompletions. + +### Changing a search box filter to a dropdown filter + +The dropdown filter widget can be finicky, because Metabase needs to run a [scan](../databases/sync-scan#how-database-scans-work) to get the list of values for the dropdown menu. + +1. Go to **Admin settings** > **Table Metadata**. +2. Find your database and table. +3. Scroll to your column. +4. In the column's settings box, set **Type** to “Category”. +5. Set **Filtering on this field** to “A list of all values". + +When you change a default filter to a dropdown filter, you'll trigger a database query that gets the first 1,000 distinct values (ordered ascending) for that column. Metabase will cache the first 100kB of text to display in the dropdown menu. If you have columns with more than 1,000 distinct values, or columns with text-heavy data, we recommend setting **Filtering on this field** to "Search box" instead. + +### Remapping column values + +Say you have a column with the values 1, 2, and 3, and you want to map each number to the values "low", "medium" and "high". This kind of mapping can be done on columns that have numeric or foreign key [field types](#field-type). + +#### Remapping numbers + +1. Go to **Admin settings** > **Table Metadata**. +2. Find your database and table. +3. Click **gear** icon at the right of a column's settings box. +4. Scroll to **Display values**. +5. Select "Custom mapping" from the dropdown menu. +6. Enter the display values under **Mapped values**. + +#### Remapping foreign keys + +1. Go to **Admin settings** > **Table Metadata**. +2. Find your database and table. +3. Click **gear** icon at the right of a column's settings box. +4. Scroll to **Display values**. +5. Select "Use foreign key" from the dropdown menu. +6. Select a column name from the second dropdown menu. + +### Displaying a column as a link + +1. Go to **Admin settings** > **Table Metadata**. +2. Find your database and table. +3. Click on the **gear** icon at the right of a column's settings box. +4. Select **Formatting** from the sidebar. +5. From **Display as**, select **Link**. +6. Optional: set display text under **Link text**. +7. Enter the URL in the **Link URL** field. +8. Optional: create a dynamic URL by adding the column name as a `{% raw %}{{parameter}}{% endraw %}`. + +![Format as URL](./images/format-as-url.png) + +For example, if you set the **Link URL** for an "Adjective" column to: + +``` +https://www.google.com/search?q={% raw %}{{adjective}}{% endraw %} +``` + +When someone clicks on the value "askew" in the "Adjective" column, they'll be taken to the Google search URL: + +``` +https://www.google.com/search?q=askew +``` + +## Refresh or discard cached values + +To update the values in your filter dropdown menus, refresh or reset the cached values. **Cache actions** include: + +- **Re-scan this table or field** to run a manual scan for new or updated column values. If possible, re-scan the table during off-peak hours, as [scans](../databases/sync-scan#how-database-scans-work) can slow down your database. +- **Discard cached field values** to clear cached values and stop them from showing up in your [filter widgets](#changing-the-filter-widget). + +### Table cache actions + +1. Go to **Admin settings** > **Table Metadata**. +2. Find your database and table. +3. Click the **gear** icon at the top right (below **Exit admin**). +4. Select a cache action. + +### Column cache actions + +1. Go to **Admin settings** > **Table Metadata**. +2. Find your database and table. +3. Click the **gear** icon at the right of a column's settings box. +4. Scroll to **Cached field values**. +5. Select a cache action. + +## Unfold JSON + +If Metabase supports JSON unfolding for your database, you can decide whether to unfold JSON into component fields, where each JSON key becomes a column. You can turn this off if performance is slow. + +1. Go to **Admin settings** > **Table Metadata**. +2. Find your database and table. +3. Click the **gear** icon at the right of a column's settings box. +4. Scroll to **Unfold JSON**. +5. Toggle JSON unfolding. + +## Further reading + +- [Keeping your analytics organized](/learn/metabase-basics/administration/administration-and-operation/same-page) +- [Data modeling tutorials](/learn/metabase-basics/getting-started/models) diff --git a/_docs/doc-update-detection/data-modeling/metrics.md b/_docs/doc-update-detection/data-modeling/metrics.md new file mode 100644 index 000000000..e120ce052 --- /dev/null +++ b/_docs/doc-update-detection/data-modeling/metrics.md @@ -0,0 +1,102 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Data Modeling' +title: Metrics +source_url: 'https://github.com/metabase/metabase/blob/master/docs/data-modeling/metrics.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/07-segments-and-metrics + - /docs/doc-update-detection/data-modeling/segments-and-metrics +--- + +# Metrics + +Create metrics to define the official way to calculate important numbers for your team. + +Metrics are like pre-defined calculations: create your aggregations once, save them as metrics, and use them whenever you need to analyze your data. + +For example, you may want to create a metric that calculates revenue, so people can refer to revenue in their own questions. That way you standardize how revenue is calculated (so you don't end up with five different calculations for the revenue). + +## Using metrics + +You can: + +- Save metrics to [collections](../exploration-and-organization/collections). +- Add metrics to [dashboards](../dashboards/introduction). +- View metrics in the [database browser](../exploration-and-organization/exploration#browse-your-databases). +- Pick metrics as aggregation columns in the Summarize block when creating questions, modify them or combine. +- [Pro](/product/pro) and [Enterprise](/product/enterprise) plans include the ability to [mark metrics as verified](../exploration-and-organization/content-verification). + +### Metrics in the query builder + +When asking questions in the query builder, you can find metrics that your team created in the summarization section under **Common metrics**. You can pick multiple metrics and they will be calculated independently and joined automatically along the chosen dimensions. + +![Common metrics](./images/common-metrics.png) + +You can also pick a metric as a data source when creating a new question. If the metric has a time dimension, Metabase will include the time dimension as a grouping. You can change the groupings to break out the metric by other dimensions. + +![Metrics tab in the entity picker](./images/entity-picker-metrics-tab.png) + +You can use custom expressions to combine multiple metrics, or perform calculations on top of metrics. + +## Creating a metric + +You can create a metric by clicking on the **+ New** menu and selecting **Metric**. + +Select your starting data. You can start from a model, metric, table, or saved question. + +You can only use the query builder to define a metric. + +The metric editor is similar to the regular query builder, with two key differences: + +- The aggregation section is called [**Formula**](#metric-formula) +- The group by section is called the [**Default time dimension**](#metric-default-time-dimension). You can only group by a single time dimension. + +![Formula](./images/formula.png) + +Only the data and formula steps are required to define a metric. You can join and filter data before the formula step, and set a default time dimension to group by. + +## Metric formula + +The formula is the core of the metric. It's the thing you are aggregating, and it's required when defining a metric. + +You can build metrics on top of existing metrics. + +![Metric built on top of other metrics](./images/metrics-built-on-other-metrics.png) + +## Metric default time dimension + +You can optionally set a default time dimension for the metric. Metabase will use this default time dimension when the metric is opened or displayed on a card in a collection or dashboard. In the image below that shows two pinned metrics at the top of a collection, the left metric lacks a default time dimension, so Metabase displays the metric as a number chart. The right metric has a default time dimension, so Metabase displays it as a line chart. + +![Pinned metrics](./images/pinned-metrics.png) + +Setting a time dimension doesn't lock the metric to that specific dimension. If someone uses the metric in a question or dashboard, they'll be able to group by other time dimensions and granularities as well. + +For example, you could calculate revenue and set a default time dimension of `Created At` by month, but if someone added that metric to a dashboard, they could group revenue by a different time granularity (e.g., by quarter). This is just an FYI so that you don't name a metric "Monthly Revenue" and think that by setting a default time dimension to "month", Metabase will prevent people from slicing revenue by other time granularities. + +## Editing a metric + +To edit a metric, click on the three dot menu (**...**) and select **Edit metric definition**. Editing a metric requires curate access to the metric's collection. + +Do your thing, and save your changes. + +When you click on a metric, Metabase will assume that you're using that metric as the starting point for a new question. You can save any changes you make as a new question, but these changes won't affect the metric's definition. + +## Metric permissions + +Like questions, models, and dashboards, whether a group can view or edit a metric depends on [collection permissions](../permissions/collections). By "view" we mean the ability to see the metric in a collection, or see the metric as an option when building a query with the metric's data source. If a metric is used in another question, whether a group can view the question depends on the question's collection, not the metric's collection. + +By "editing" a metric, we mean [editing the metric's query definition](#editing-a-metric). + +These collection permissions also interact with the group's [data permissions](../permissions/data), which define whether the group can view or query the metric's source data. + +## Verifying a metric + +See [content verification](../exploration-and-organization/content-verification). + +## Further reading + +- [Models](./models) +- [Segments](./segments) diff --git a/_docs/doc-update-detection/data-modeling/model-persistence.md b/_docs/doc-update-detection/data-modeling/model-persistence.md new file mode 100644 index 000000000..66a9e6ea2 --- /dev/null +++ b/_docs/doc-update-detection/data-modeling/model-persistence.md @@ -0,0 +1,79 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Data Modeling' +title: 'Model persistence' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/data-modeling/model-persistence.md' +--- + +# Model persistence + +> Currently available for PostgreSQL, MySQL, and Redshift. + +Metabase can persist the results of your models so that your models (and the questions based on those models) load faster. + +Metabase will store model results in tables in a bespoke schema in your data warehouse (not the Metabase application database). When people ask questions based on your models, Metabase will use the tables with the stored results instead of re-running the model's query. + +> Model persistence doesn't work with [data sandboxing](../permissions/data-sandboxes) or [impersonation](../permissions/impersonation). + +## Turn on model persistence in Metabase + +To persist models for faster loading, you'll need to turn on model persistence for: + +1. [Your Metabase](#turn-on-model-persistence-for-your-metabase) +2. [Individual databases](#turn-on-model-persistence-for-each-database) +3. [(Optional) individual models](#turn-on-model-persistence-for-individual-models) + +### Turn on model persistence for your Metabase + +To turn on model persistence for your Metabase, go to **Admin settings** > **Performance** > **Model persistence**. + +You can set models to refresh based on one of the default frequencies (every 1 hour, 2 hours, etc.), or select the **Custom** option to use [cron syntax](https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html) to specify your own update frequency. + +The cron scheduler uses the [Report Timezone](../configuring-metabase/localization#report-timezone) if selected. Otherwise the scheduler will use the System Timezone (which defaults to GMT in [Metabase Cloud](/cloud/)). + +We recommend scheduling your models to refresh on a frequency that makes sense with how often your source tables update with new data. + +If someone [changes the query definition of a model](./models#edit-a-models-query), any question based on that model will re-run the model's query until the next scheduled model refresh. + +## Turn on model persistence for each database + +Once you've turned on model persistence for your Metabase, you'll need to set it up for each specific database, as Metabase will need to create a schema in your data warehouse to store the persisted models. + +1. Go to **Admin settings** > **Databases** > [your database] > **Turn model persistence on**. If the credentials you've given Metabase to connect to your database are permissive, Metabase should do all the work for you: Metabase will check if the schema already exists, or otherwise attempt to create it. If the connection's credentials _lack_ the necessary permissions to create the schema in your database, you'll need to create the schema in the database yourself. + +2. To manually create the schema in your data warehouse, click on the **info icon** to get the schema name. + +3. Create the schema in your database---make sure you use the exact schema name from step 1. For example, if you're running PostgreSQL as your data warehouse, you'd create the schema by running `CREATE SCHEMA IF NOT EXISTS schema_name`, with `schema_name` being whatever Metabase showed you in the info icon. + +4. Ensure that the credentials Metabase uses to connect to your data warehouse can manage and write to that schema. + +## Turn on model persistence for individual models + +{% include plans-blockquote.html feature="Individual model persistence" %} + +You can also toggle persistence on or off for individual models. When viewing a model, click on the **...** in the upper right and select **Edit settings**. Toggle **Persist model data** on (you'll need [Curate access](../permissions/collections#curate-access) to the model's collection to do this). + +Toggling persistence for individual models is useful for models with data that updates at different frequencies than the schedule you set for other models in that database, or for models that are used more or less than other models in that database. + +## Refreshing a model's persisted results + +To refresh a model's results, go to the model and click on the three-dot menu (**...**) and select **Edit settings**. In the info sidebar that opens, you'll see a note about when Metabase last refreshed the model's results, and an icon to refresh the results. + +## View model persistence logs + +You can view the logs for model persistence by clicking on the **gear** icon in the upper right and selecting **Admin settings** > **Tools** > **Model caching logs**. See [Admin tools](../usage-and-performance-tools/tools). + +## Difference between persisted models and caching + +Persisted models differ from [cached results](../configuring-metabase/caching): + +- **Models are persisted in your data warehouse; cached results are stored in the application database**. Metabase stores cached results in its application database. Metabase persists models in your connected data warehouse as tables. +- **Metabase refreshes model results and invalidates cached results**. Metabase will refresh results of models according to the schedule you set. That is, Metabase will re-run the model's query and store the results in your data warehouse. For cached results of saved questions and dashboards, Metabase won't run the queries automatically; it will cache results when people view the question or dashboard, and invalidate the cached results according to the caching policy you set. + +## Further reading + +- [Models](./models) +- [Caching policies](../configuring-metabase/caching) diff --git a/_docs/doc-update-detection/data-modeling/models.md b/_docs/doc-update-detection/data-modeling/models.md new file mode 100644 index 000000000..20a552226 --- /dev/null +++ b/_docs/doc-update-detection/data-modeling/models.md @@ -0,0 +1,182 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Data Modeling' +title: Models +source_url: 'https://github.com/metabase/metabase/blob/master/docs/data-modeling/models.md' +redirect_from: + - /docs/doc-update-detection/users-guide/models +--- + +# Models + +Models are a fundamental building block in Metabase. Models curate data from another table or tables from the same database to anticipate the kinds of questions people will ask of the data. You can think of them as derived tables, or a special kind of saved question meant to be used as the starting point for new questions. You can base a model on a SQL or query builder question, which means you can include custom, calculated columns in your model. + +Models: + +- Let you update column descriptions and customize metadata to create great starting points for exploration. +- Show up higher in search results and get highlighted when other users start new questions to promote reuse. +- Live in collections to keep them separate from messy database schemas. +- Can [surface individual records in search results](#surface-individual-records-in-search-by-matching-against-this-column). +- Can be [persisted for faster loading](./model-persistence). + +For a deep dive on why and how to use models, check out our [Learn article on models][learn-models]. + +## How to use models + +You can use models to: + +- Create, uh, models, with model here meaning an intuitive description of some concept in your business that you codify as a set of columns. An example model could be a "customer", which is a table that pulls together customer information from multiple tables and adds computed columns, like adding a lifetime value (LTV) column. This model represents the [measures and dimensions][measures-dimensions] that you think are relevant to your understanding of your customers. +- Let people explore the results of SQL queries with the query builder (provided you [set the column types](#column-type)). +- Create summary tables that pull in or aggregate data from multiple tables. +- Clean up tables with unnecessary columns and rows filtered out. + +The idea with models is to give other people a good "starting point table" that makes it easier to answer any questions they have about the subject being modeled. + +## Create a model + +First, search for models that already exist. If you can't find one that meets your needs, you can create a model: + +- [from scratch](#create-a-model-from-scratch), or +- [from a saved question](#create-a-model-from-a-saved-question). + +Models you create are automatically [pinned to the current collection](../exploration-and-organization/collections#pinned-items). + +### Create a model from scratch + +1. In the upper right, click **New +** > **Model**. +2. Choose either the query builder or a native query (if you want to use SQL). The advantage of using the query builder is that Metabase will be able to fill out some of the metadata for you; if you use SQL, you'll have to fill out that metadata manually. +3. Select your data. +4. Create and save your query. + +### Create a model from a saved question + +1. [Ask a question][question] using either the query builder or the SQL editor, or select an existing saved question that you want to convert to a model. +2. Save the question. +3. Click on the **...** > **Turn this into a model**. + +![Turn a saved question into a model](./images/turn-into-a-model.png) + +## Model details + +To view a model's details, visit the model and click on the **info** button in the upper right. Here you'll see several tabs: + +- **Overview**: Includes the description, Creator and Last Editor, and the list of fields included in the model. As well as the model's [Entity ID](../installation-and-operation/serialization#metabase-uses-entity-ids-to-identify-and-reference-metabase-items). +- **History**: Lists changes to the model, and by whom. +- **Relationships**: Lists which questions use the model, and which tables the model is linked to. +- **Actions**: Lists actions created based on the model. +- **Insights**: Info about the [model's usage](../usage-and-performance-tools/usage-analytics). Only visible to admins on a [Pro or Enterprise plan](/pricing/). + +## Add metadata to columns in a model + +Metadata is the secret sauce of models. When you write a SQL query, Metabase can display the results, but it can't "know" what kind of data it's returning (like it can with questions built using the query builder). What this means in practice is that people won't be able explore the results with the query builder, because Metabase doesn't understand what the results are. With models, however, you can tell Metabase what kind of data is in each returned column so that Metabase can still do its query magic. Metadata will also make filtering nicer by showing the correct filter widget, and it will help Metabase to pick the right visualization for the results. + +If you only set one kind of metadata, set the **Column type** to let Metabase know what kind of data it's working with. + +### Display name + +What people will see as the column's name. + +### Description + +A place to write helpful context for the column. + +### Database column this maps to + +For models based on SQL queries, you can tell Metabase if the column has the same type as an existing database column. + +### Column type + +You can set the [column type][column-type]. The default is "No special type". + +If your model is based on a SQL query and you want people to be able to explore the results with the query builder, you'll need to set the [column type](./field-types) for each column in your model. + +### This column should appear in... + +You can specify whether a column should appear in the table view, or just in a detail view (when you click on the entity/primary key for the row). + +- Table and detail views +- Detail views only + +### Display as + +- Text +- Link (it's a URL people should be able to click on) + +### Surface individual records in search by matching against this column + +For string fields in records with integer entity keys, Metabase will give you the option make the values in that field show up when people search your Metabase. Essentially, Metabase will index these values and make them available to Metabase's search engine. This option is handy when people often want to jump straight to an individual record in your model. + +For example, if you have a model with accounts, you could turn on this option for a column listing the account's name or email so that people can quickly search for specific accounts in the model from anywhere in your Metabase. When people click on a record in the search results, Metabase will jump straight to the model and the object detail for that record. + +There are some limitations to this indexing: + +- The indexed field must be a text/string type. +- The record containing the field must have an integer entity key. +- To keep your search speedy, Metabase will only index 5000 unique values from that field, so this option isn't the best choice to turn on for tables with a ton of records. + +## Edit a model's query + +You can edit a model's query by clicking on the down arrow next to the model's name and clicking on **Edit query definition**. When you're doing editing, be sure to save your changes. Unlike questions, which prompt you to save as a new question, any changes here will overwrite the existing model. If you want to create a new model from an existing model, select **Duplicate this model** from the model sidebar (the icon of two overlapping squares). + +## Start a question from a model + +See [asking questions][question]. + +## [Refer to a model in the SQL query editor](../questions/native-editor/referencing-saved-questions-in-queries) + +You can refer to a model in a SQL query just like you can refer to a saved question: + +```sql +{% raw %} +SELECT * FROM {{#1-customer-model}} +{% endraw %} +``` + +Or as a [common table expression (CTE)][cte]: + +```sql +{% raw %} +WITH model AS {{#3807-invoice-model}} +SELECT * +FROM model; +{% endraw %} +``` + +Simply typing `{% raw %}{{#}} {% endraw %}` will allow you to search for models (for example, you could type in `{% raw %}{{#customer}}{% endraw %}` to search models, questions, and tables with the word "customer" in the title. + +You can also use the data reference sidebar to browse the models available. To open the data reference sidebar, click on the **book** icon. + +## Model version history + +For [questions](../questions/start), [dashboards](../dashboards/start), and models, Metabase keeps a version history for the previous fifteen versions of that item. You can view changes and revert to previous versions. + +See [History](../exploration-and-organization/history). + +## Delete a model + +You can move outdated or unneeded models to trash, or delete them permanently. Deleting a model will affect questions that use it as a data source. + +See [Deleting and restoring items](../exploration-and-organization/delete-and-restore). + +## Verifying a model + +See [content verification](../exploration-and-organization/content-verification). + +## Model persistence + +See [Model persistence](./model-persistence) + +## Further reading + +- [Models in Metabase][learn-models] +- [Troubleshooting models][troubleshooting-models]. + +[column-type]: ./field-types +[cte]: /learn/grow-your-data-skills/learn-sql/working-with-sql/sql-cte +[measures-dimensions]: /learn/grow-your-data-skills/data-fundamentals/dimensions-and-measures +[question]: ../questions/start +[learn-models]: /learn/metabase-basics/getting-started/models +[troubleshooting-models]: ../troubleshooting-guide/models diff --git a/_docs/doc-update-detection/data-modeling/segments.md b/_docs/doc-update-detection/data-modeling/segments.md new file mode 100644 index 000000000..096e08ca1 --- /dev/null +++ b/_docs/doc-update-detection/data-modeling/segments.md @@ -0,0 +1,47 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Data Modeling' +title: Segments +source_url: 'https://github.com/metabase/metabase/blob/master/docs/data-modeling/segments.md' +--- + +# Segments + +Metabase allows admins to create segments so people can quickly and easily reference them in the query builder. Just head over to the **Admin Panel** and select **Table Metadata** from the top menu. + +## Creating a Segment + +A segment is just a special named filter or set of filters. You can create these to make sure that there is an official definition of a subset of customers, users, or products that everyone on your team can refer to consistently. For example, you might create a segment called “Active Users” that contains all the filters that are needed to correctly select active users. + +To start, select the **Segments** tab, followed by the **New segment** button on the right side of the screen. Choose the appropriate table and filters for your new segment and add a title and description. When you’re done, this segment will be accessible from the filter list in the query builder when viewing this table (the segment will not be automatically applied to the table). + +![Add a segment](images/AddSegment.png) + +Now you’ll be looking at the segment builder, which is a limited version of the query builder, with only the option to add filters. Add your filter(s) as you would in the query builder, and then give your segment a name and a description (these will be visible in the query builder filter dropdown after you’ve saved). If you want to test out your segment in the query builder before you save it, just click the Preview button, which will open a new query builder window with your segment applied. + +![Creating a segment](images/CreateSegment.png) + +Once you’re done, click **Save changes**. Now your new segment will appear in the segments list of your table. + +![Finished segment](images/FinishedSegment.png) + +If you exit the Admin Panel and try asking a new question, then click on the button to add a filter, you’ll see your segment at the top of the list. + +![Segment in dropdown](images/Segment.png) + +## Editing and retiring segments + +You can edit and retire segments from the Table Metadata screen in the Admin Panel. Select the table with the segment you’re looking for, and click the ellipsis (…) icon to the right of that segment. + +![Segment Actions](images/SegmentActions.png) + +When editing a segment, you’ll be required to leave a note about why you’re changing it, just so everyone can understand why things are different. If any user is the creator of a saved question or dashboard that utilized the segment you’ve edited, they’ll receive an email letting them know that things have changed, along with the explanation that you write in this box. + +![Edit message](images/EditMessage.png) + +Retiring a segment will make it no longer selectable from the query builder. However, **it won’t break existing saved questions that depend on that segment**. + +Lastly, you can also view the revision history for each segment from the actions list. diff --git a/_docs/doc-update-detection/data-modeling/start.md b/_docs/doc-update-detection/data-modeling/start.md new file mode 100644 index 000000000..37312ccc5 --- /dev/null +++ b/_docs/doc-update-detection/data-modeling/start.md @@ -0,0 +1,45 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: 'Data Modeling' +title: 'Data modeling overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/data-modeling/start.md' +--- + +# Data modeling overview + +Metabase provides tools for organizing your data and making it easier for people to understand. + +## [Models](./models) + +Models curate data from another table or tables from the same database to anticipate the kinds of questions people will ask of the data. You can think of them as derived tables, or a special kind of saved question meant to be used as the starting point for new questions. + +## [Model persistence](./model-persistence) + +Persist model results for faster loading times. + +## [Metrics](./metrics) + +Create metrics to define the official way to calculate important numbers for your team. + +## [Table metadata admin settings](./metadata-editing) + +Guide people to the right data by adding display names, hiding outdated tables, configuring filter types, and more. + +## [Field types](./field-types) + +Field types dictate how Metabase displays its data, as well as the column’s special functionality, if any. + +## [Setting default formatting for your data](./field-types) + +Define formatting and display defaults for numbers, currencies, datetimes, and more. + +## [Working with JSON](./json-unfolding) + +Metabase can unfold JSON columns into their component fields, which you can then filter on using the query builder. + +## [Segments](./segments) + +Admins can define segments to create official filters for your data. diff --git a/_docs/doc-update-detection/databases/connecting.md b/_docs/doc-update-detection/databases/connecting.md new file mode 100644 index 000000000..ff40d975d --- /dev/null +++ b/_docs/doc-update-detection/databases/connecting.md @@ -0,0 +1,90 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'Adding and managing databases' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connecting.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/01-managing-databases + - /docs/doc-update-detection/databases/connections/sql-server + - /docs/doc-update-detection/administration-guide/databases/h2 + - /docs/doc-update-detection/databases/connections/h2 +--- + +# Adding and managing databases + +Connect Metabase to your data sources. + +## Adding a database connection + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +Fill out the fields for that database, and click **Save changes** at the bottom. + +The connection settings differ database to database. For the list of connection settings available for your database, click on the link to your database below. + +## Connecting to supported databases + +The databases listed below have official drivers maintained by the Metabase team. Customers on [Pro and Enterprise](/pricing/) will get official support. For each database, Metabase supports the oldest supported version through the latest stable version. + +- [Athena](./connections/athena) +- [BigQuery](./connections/bigquery) (Google Cloud Platform) +- [ClickHouse](./connections/clickhouse) +- [Databricks](./connections/databricks) +- [Druid](./connections/druid) +- [MongoDB (recommend version 4.2 or higher)](./connections/mongodb) +- [MariaDB](./connections/mariadb) +- [MySQL](./connections/mysql) +- [Oracle](./connections/oracle) +- [PostgreSQL](./connections/postgresql) +- [Presto](./connections/presto) +- [Redshift (Amazon Web Services)](./connections/redshift) +- [Snowflake](./connections/snowflake) +- [SparkSQL](./connections/sparksql) +- [SQL Server](./connections/sql-server) +- [SQLite](./connections/sqlite) +- [Starburst](./connections/starburst)] +- [Vertica](./connections/vertica) + +If you don't see your database listed here, see [Community drivers](../developers-guide/community-drivers). + +As of version 46.6.4, Metabase [no longer supports H2 connections](/blog/vulnerability-post-mortem). But Metabase still ships with an H2 database to include an embedded application database, as well as to provide some sample data out of the box. + +## Connecting to databases hosted by a cloud provider + +For provider-specific connection details, like connecting to a PostgreSQL data warehouse on RDS: + +- [AWS's Relational Database Service (RDS)](./connections/aws-rds) + +## Granting database privileges + +For Metabase to connect, query, or write to your database, you must give Metabase a database user account with the correct database privileges. See [Database roles, users, and privileges](./users-roles-privileges). + +## Syncing and scanning databases + +See [Syncing and scanning](./sync-scan). + +## Deleting databases + +**Caution: Deleting a database is irreversible! All saved questions and dashboard cards based on the database will be deleted as well!** + +Go to **Admin settings** > **Databases** > your database and click **Remove this database**. + +## Restoring the Sample Database + +If you've deleted the Metabase [Sample Database](/glossary/sample_database), go to **Admin settings** > **Databases** and click **Bring the Sample Database back**. + +## Troubleshooting + +- [Troubleshooting database connections](../troubleshooting-guide/db-connection) +- [Troubleshooting syncs, scans, and fingerprinting](../troubleshooting-guide/sync-fingerprint-scan) +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](../troubleshooting-guide/known-issues). + +## Further reading + +- [Metadata editing](../data-modeling/metadata-editing). +- [Setting data access permissions](../permissions/data). +- [Metabase at scale](/learn/metabase-basics/administration/administration-and-operation/metabase-at-scale). diff --git a/_docs/doc-update-detection/databases/connections/athena.md b/_docs/doc-update-detection/databases/connections/athena.md new file mode 100644 index 000000000..7db8ade8f --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/athena.md @@ -0,0 +1,225 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'Amazon Athena' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/athena.md' +--- + +# Amazon Athena + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +## Connection and sync + +After connecting to a database, you'll see the "Connection and sync" section that displays the current connection status and options to manage your database connection. + +Here you can [sync the database schema and rescan field values](../sync-scan), and edit connection details. + +### Edit connection details + +You can edit these settings at any time (and remember to save your changes). + +### Display name + +The display name for the database in the Metabase interface. + +### Region + +The AWS region where your database is hosted, for Amazon Athena. For example, you might enter `us-east-1`. + +### Workgroup + +AWS workgroup. For example: `primary`. See [documentation on workgroups](https://docs.aws.amazon.com/athena/latest/ug/user-created-workgroups.html). + +### S3 Staging directory + +This S3 staging directory must be in the same region you specify above. + +### Access key + +Part of IAM credentials for AWS. Metabase will encrypt these credentials. + +If you're running Metabase on AWS and want to use [AWS Default Credentials Chain](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default), leave the Access and Secret keys blank. + +See also our [notes on connecting to Athena](#notes-on-connecting-to-athena). + +### Secret Key + +Part of IAM credentials for AWS. Metabase will encrypt these credentials. + +### Additional Athena connection string options + +You can specify additional options via a string, e.g., `UseResultsetStreaming=0;LogLevel=6`. + +### Include User ID and query hash in queries + +This can be useful for auditing and debugging, but prevents databases from caching results and may increase your costs. Enable this feature if you need to track which users are running specific queries. + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Notes on connecting to Athena + +If you use other AWS services, we recommend that you create a special AWS Service Account that only has the permissions required to run Athena, and input the IAM credentials from that account to connect Metabase to Athena. + +See [Identity and access management in Athena](https://docs.aws.amazon.com/athena/latest/ug/security-iam-athena.html). + +### Connecting using AWS Default Credentials Chain + +If you're running Metabase on AWS and want to use [AWS Default Credentials Chain](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default), leave the Access and Secret keys blank. + +- For EC2, you can use [instance profiles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html). +- For ECS, you can use [IAM roles for tasks](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html) + +In both cases, the Athena driver will automatically fetch session credentials based on which IAM role you've configured. + +### Permissions and IAM Policies + +Most issues that we see when people attempt to connect to AWS Athena involve permissions. Querying AWS Athena requires permissions to: + +- AWS Athena. +- AWS Glue. +- The S3 bucket where Athena results are stored. +- The resources that Athena is querying against (i.e., the S3 bucket(s) Athena is querying). +- If you're using AWS Lake Formation, then you also need to grant AWS Lake Formation permissions through the AWS Console (AWS Lake Formation > Permissions > Data Lake Permissions > Grant data lake permissions; the role Metabase uses needs SELECT and DESCRIBE table permissions). + +### Example IAM Policy + +This policy provides read-only permissions for data in S3. You'll need to specify any S3 buckets that you want Metabase to be able to query from _as well as_ the S3 bucket provided as part of the configuration where results are written to. + +There may be additional permissions required for other Athena functionality, like federated queries. For details, check out the [Athena docs](https://docs.aws.amazon.com/athena/latest/ug/security-iam-athena). + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Athena", + "Effect": "Allow", + "Action": [ + "athena:BatchGetNamedQuery", + "athena:BatchGetQueryExecution", + "athena:GetNamedQuery", + "athena:GetQueryExecution", + "athena:GetQueryResults", + "athena:GetQueryResultsStream", + "athena:GetWorkGroup", + "athena:ListDatabases", + "athena:ListDataCatalogs", + "athena:ListNamedQueries", + "athena:ListQueryExecutions", + "athena:ListTagsForResource", + "athena:ListWorkGroups", + "athena:ListTableMetadata", + "athena:StartQueryExecution", + "athena:StopQueryExecution", + "athena:CreatePreparedStatement", + "athena:DeletePreparedStatement", + "athena:GetPreparedStatement" + ], + "Resource": "*" + }, + { + "Sid": "Glue", + "Effect": "Allow", + "Action": [ + "glue:BatchGetPartition", + "glue:GetDatabase", + "glue:GetDatabases", + "glue:GetPartition", + "glue:GetPartitions", + "glue:GetTable", + "glue:GetTables", + "glue:GetTableVersion", + "glue:GetTableVersions" + ], + "Resource": "*" + }, + { + "Sid": "S3ReadAccess", + "Effect": "Allow", + "Action": ["s3:GetObject", "s3:ListBucket", "s3:GetBucketLocation"], + "Resource": [ + "arn:aws:s3:::bucket1", + "arn:aws:s3:::bucket1/*", + "arn:aws:s3:::bucket2", + "arn:aws:s3:::bucket2/*" + ] + }, + { + "Sid": "AthenaResultsBucket", + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:GetObject", + "s3:AbortMultipartUpload", + "s3:ListBucket", + "s3:GetBucketLocation" + ], + "Resource": ["arn:aws:s3:::bucket2", "arn:aws:s3:::bucket2/*"] + } + ] +} +``` + +If Metabase also needs to create tables, you'll need additional AWS Glue permissions. The `"Resource": "*"` key-value pair gives the account Delete and Update permissions to any table: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "VisualEditor0", + "Effect": "Allow", + "Action": [ + "glue:BatchCreatePartition", + "glue:UpdateDatabase", + "glue:DeleteDatabase", + "glue:CreateTable", + "glue:CreateDatabase", + "glue:UpdateTable", + "glue:BatchDeletePartition", + "glue:BatchDeleteTable", + "glue:DeleteTable", + "glue:CreatePartition", + "glue:DeletePartition", + "glue:UpdatePartition", + "glue:GetCatalogImportStatus" + ], + "Resource": "*" + } + ] +} +``` +## Model features + +There aren't (yet) any model features available for Athena. + +## Danger zone + +See [Danger Zone](../danger-zone). + +## Further reading + +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/aws-rds.md b/_docs/doc-update-detection/databases/connections/aws-rds.md new file mode 100644 index 000000000..ec5d2617c --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/aws-rds.md @@ -0,0 +1,28 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'Connecting to AWS''s Relational Database Service (RDS)' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/aws-rds.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/databases/aws-rds +--- + +# Connecting to AWS's Relational Database Service (RDS) + +RDS offers several databases that Metabase officially supports, including PostgreSQL, MySQL, MariaDB, Oracle, and SQL server. + +Here's how to get connection information for databases on Amazon's RDS: + +1. Go to your AWS Management Console. + - Need help finding that? Visit `https://**My_AWS_Account_ID**.signin.aws.amazon.com/console`. Be sure to insert your own AWS Account ID, though! +2. Go to **Database** > **RDS** > **Instances**. +3. Select the database you want to connect to Metabase. +4. Get the information you'll need to connect Metabase to your RDS: + - **Hostname**. This is listed as the Endpoint parameter. + - **Port**. Find the port parameter under Security and Network. + - **Username**. Find this under Configuration Details. + - **Database Name**. Find this under Configuration Details. + - **Password**. Ask your database administrator for the password. diff --git a/_docs/doc-update-detection/databases/connections/bigquery.md b/_docs/doc-update-detection/databases/connections/bigquery.md new file mode 100644 index 000000000..8ec620659 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/bigquery.md @@ -0,0 +1,179 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'Google BigQuery' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/bigquery.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/databases/bigquery +--- + +# Google BigQuery + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +## Prerequisites + +You'll need to have a [Google Cloud Platform](https://cloud.google.com/) account with a [project](https://cloud.google.com/storage/docs/projects) you would like to use in Metabase. Consult the Google Cloud Platform documentation for how to [create and manage a project](https://cloud.google.com/resource-manager/docs/creating-managing-projects). This project should have a BigQuery dataset for Metabase to connect to. + +## Google Cloud Platform: creating a service account and JSON file + +You'll first need a [service account](https://cloud.google.com/iam/docs/service-account-overview) JSON file that Metabase can use to access your BigQuery dataset. Service accounts are intended for non-human users (such as applications like Metabase) to authenticate (who am I?) and authorize (what can I do?) their API calls. + +To create the service account JSON file, follow Google's documentation on [setting up a service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts) for your BigQuery dataset. Here's the basic flow: + +1. **Create service account**. From your Google Cloud Platform project console, open the main sidebar menu on the left, go to the **IAM & Admin** section, and select **Service account**. The console will list existing service accounts, if any. At the top of the screen, click on **+ CREATE SERVICE ACCOUNT**. + +2. **Fill out the service account details**. Name the service account, and add a description (the service account ID will populate once you add a name). Then click the **Create** button. + +3. **Grant the service account access to this project**. You'll need to add **roles** to the service account so that Metabase will have permission to view and run queries against your dataset. Make sure you add the following roles to the service account: + + - BigQuery Data Viewer + - BigQuery Metadata Viewer + - BigQuery Job User (distinct from BigQuery User) + +For more information on **roles** in BigQuery, see [Google Cloud Platform's documentation](https://cloud.google.com/bigquery/docs/access-control). + +4. **Create key**. Once you have assigned roles to the service account, click on the **Create Key** button, and select **JSON** for the **key type**. The JSON file will download to your computer. + +> **You can only download the key once**. If you delete the key, you'll need to create another service account with the same roles. + +## Connection and sync + +After connecting to a database, you'll see the "Connection and sync" section that displays the current connection status and options to manage your database connection. + +Here you can [sync the database schema and rescan field values](../sync-scan), and edit connection details. + +## Edit connection details + +You can edit these settings at any time. Just remember to save your changes. + +### Display name + +The display name for the database in the Metabase interface. + +### Project ID + +Each BigQuery dataset will have a **Project ID**. You can find this ID via the [Google Cloud Console](https://console.cloud.google.com/). If you're not sure where to find the **Project ID**, see Google's documentation on [getting information on datasets](https://cloud.google.com/bigquery/docs/dataset-metadata#getting_dataset_information). + +> When entering the **Project ID**, omit the Project ID prefix. For example, if your ID is `project_name:project_id`, only enter `project_id`. + +### Service account JSON file + +The JSON file contains the credentials your Metabase application will need to access BigQuery datasets, as defined by the **roles** you added to the service account. If you need to add additional **roles**, you have to create another service account, download the JSON file, and upload the file to Metabase. + +### Datasets + +You can specify which BigQuery datasets you want to sync and scan. Options are: + +- All +- Only these... +- All except... + +> A BigQuery dataset is similar to a schema. Make sure to enter your dataset names (like `marketing`), _not_ your table names (`marketing.campaigns`). + +Let's say you have three datasets: foo, bar, and baz. + +To sync all three datasets, select **Only these...** and enter: + +``` +foo,bar,baz +``` + +To sync datasets based on a string match, use the `*` wildcard: + +- To sync bar and baz, select **Only these...** and enter the string `b*`. +- To sync foo only, select **All except...** and enter the string `b*`. + +Note that only the `*` wildcard is supported; you can't use other special characters or regexes. + +### Use the Java Virtual Machine (JVM) timezone + +We suggest you leave this off unless you're doing manual [timezone](../../configuring-metabase/timezones) casting in many or most of your queries with this data. + +### Include User ID and query hash in queries + +This can be useful for [auditing](../../usage-and-performance-tools/usage-analytics) and debugging, but prevents BigQuery from caching results and may increase your costs. + +### Alternate hostname + +If you want to use a different hostname to connect to BigQuery. Format: `https://:`. If you're using a proxy service to connect to BigQuery (e.g. a privacy proxy that anonymizes PII), you should configure this field to the proxy hostname or IP. Remember to set the complete URI with protocol and port number. + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Connecting Metabase to Google Drive data sources + +You can connect Metabase to Google Drive data sources via BigQuery. There is some setup involved, but basically what you'll be doing is creating a dataset in BigQuery and adding an external table to that dataset that points to a Google Sheet. Useful for uploading CSVs to Google Sheets, and then analyzing and visualizing the data with Metabase. + +To connect to a data source stored in Google Drive (like a Google Sheet), first make sure you've completed the steps above, including: + +- creating a project in Google Cloud Platform, +- adding a BigQuery dataset, and +- creating a [service account](#google-cloud-platform-creating-a-service-account-and-json-file). + +### Share your Google Drive source with the service account + +While viewing your Drive file, (e.g., a Google Sheet with an uploaded CSV file), click the **Share** button in the top right. In the text box labeled **Add people or groups**, paste in the email of your service account, which you can find on the [Service Accounts page](https://console.cloud.google.com/projectselector2/iam-admin/serviceaccounts?supportedpurview=project) in the Google Cloud Console. + +That email address will look something like `service-account-name@your-project-name.iam.gserviceaccount.com`, with the your service account and project names filled in accordingly. + +Choose **Viewer** from the dropdown, uncheck the **Notify people** option, and click **Share**. + +### Create an external table in BigQuery that points to your Google Drive source + +If you don't already have a BigQuery dataset, [create one](https://cloud.google.com/bigquery/docs/datasets). + +Next, using the Google Cloud Console, [create an external table](https://cloud.google.com/bigquery/external-data-drive?hl=en#creating_and_querying_a_permanent_external_table) within your BigQuery dataset that points to your Google Sheet. + +Be sure to specify the correct **Drive URI** and file format. + +If you haven't already, [connect your Metabase to your BigQuery](#google-bigquery). + +Once you've completed these steps, you'll be able to ask questions and create dashboards in Metabase using a Google Drive source as your data. + +## Using Legacy SQL + +As of version 0.30.0, Metabase tells BigQuery to interpret SQL queries as [Standard SQL (GoogleSQL)](https://cloud.google.com/bigquery/docs/introduction-sql). If you prefer using [Legacy SQL](https://cloud.google.com/bigquery/docs/reference/legacy-sql) instead, you can tell Metabase to do so by including a `#legacySQL` directive at the beginning of your query, for example: + +```sql +#legacySQL +SELECT * +FROM [my_dataset.my_table] +``` + +## Troubleshooting + +If you're having trouble with your BigQuery connection, you can check out this [troubleshooting guide](../../troubleshooting-guide/bigquery-drive) that covers BigQuery issues, [this one](../../troubleshooting-guide/db-connection) on data warehouse connections, or visit [Metabase's discussion forum](https://discourse.metabase.com/search?q=bigquery) to see if someone has encountered and resolved a similar issue. + +## Model features + +There aren't (yet) any model features available for BigQuery. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/clickhouse.md b/_docs/doc-update-detection/databases/connections/clickhouse.md new file mode 100644 index 000000000..75fdf95be --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/clickhouse.md @@ -0,0 +1,112 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: ClickHouse +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/clickhouse.md' +description: 'Learn how to connect Metabase to your ClickHouse database, including connection settings, database selection, and SSL configuration.' +--- + +# ClickHouse + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +You can edit these settings at any time. Just remember to save your changes. + +## Connection and Sync + +After connecting to a database, you'll see the "Connection and sync" section that displays the current connection status and options to manage your database connection. + +Here you can [sync the database schema and rescan field values](../sync-scan), and edit connection details. + +## Edit connection details + +To access or modify your database connection settings, click the **Edit connection details** button. + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address (e.g., `98.137.149.56`) or its domain name (e.g., `name.database.com`). + +### Port + +The database port (e.g., `8123`). + +### Username + +The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of [privileges](../users-roles-privileges). + +### Password + +The password for the username that you use to connect to the database. + +### Databases + +Include all of the database you want to be able to query in Metabase. Separate databases with the space character, e.g., `db1 db2 db3`. + +### Scan all databases + +Scan all tables from all available ClickHouse databases except the system ones. + +### Use a secure connection (SSL) + +See [SSL certificates](../ssl-certificates). + +### Use an SSH-tunnel + +If a direct connection to your database isn't possible, you may want to use an SSH tunnel. See [SSH tunneling](../ssh-tunnel). + +### Disable system wide proxy settings + +System-wide proxy settings are disabled by default. You can disable them with this toggle. + +### ClickHouse settings (comma-separated) + +Here you can add a string to specify additional ClickHouse settings. Separate settings with a comma, like so: + +``` +allow_experimental_analyzer=1,max_result_rows=100 +``` + +### Max open HTTP connections in the JDBC driver (default: 100) + +You can limit the number of HTTP connections in the JDBC driver used to connect Metabase to ClickHouse. + +### Additional JDBC connection string options + +You can append options to the JDBC connection string. Separate options with `&`, like so: + +``` +connection_timeout=1000&socket_timeout=300000 +``` + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Model features + +There aren't (yet) any model features for ClickHouse. + +## Danger zone + +See [Danger zone](../danger-zone). diff --git a/_docs/doc-update-detection/databases/connections/databricks.md b/_docs/doc-update-detection/databases/connections/databricks.md new file mode 100644 index 000000000..86383db57 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/databricks.md @@ -0,0 +1,113 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: Databricks +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/databricks.md' +--- + +# Databricks + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. Then select **Databricks**. + +You can edit these settings at any time. Just remember to save your changes. + +## Edit connection details + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address, or its domain name (e.g., `xxxxxxxxxx.cloud.databricks.com` or `adb-xxxxx.azuredatabricks.net`). This is the value of your Databrick's compute resource's Server Hostname. + +See [Compute settings for the Databricks JDBC Driver](https://docs.databricks.com/en/integrations/jdbc/compute.html). + +### HTTP path + +This is the Databrick's compute resources HTTP Path value. This value is often a SQL warehouse endpoint in the format `/sql/1.0/endpoints/abcdef1234567890`. See [Connect to a SQL warehouse](https://docs.databricks.com/en/compute/sql-warehouse/index.html). + +Additionally, see [Compute settings for the Databricks JDBC Driver](https://docs.databricks.com/en/integrations/jdbc/compute.html). + +### Authentication + +There are two ways to authenticate with Databricks. You can use a personal access token (PAT) or a service principal using OAuth (OAuth M2M). + +The Databricks driver supports both options. Use the toggle to select the authentication method you want to use. + +#### Personal access token authentication +See [Personal Access Token (PAT)](https://docs.databricks.com/en/dev-tools/auth/pat.html). + +#### Authenticate access with a service principal using OAuth (OAuth M2M) + +See [Authenticate access with a service principal using OAuth](https://docs.databricks.com/en/dev-tools/auth/oauth-m2m.html). + +### Catalog +For now, you can only select one catalog. Metabase doesn't support multi-catalog connections. If you want to use more than one catalog in Metabase, you can set up multiple connections, each selecting a different catalog. + +You can't sync Databricks's legacy catalogs, however, including the `samples` or `hive_metastore` catalogs. + +### Schemas + +You can specify which schemas you want to sync and scan. Options are: + +- All +- Only these... +- All except... + +For the **Only these** and **All except** options, you can input a comma-separated list of values to tell Metabase which schemas you want to include (or exclude). For example: + +``` +foo,bar,baz +``` + +You can use the `*` wildcard to match multiple schemas. + +Let's say you have three schemas: foo, bar, and baz. + +- If you have **Only these...** set, and enter the string `b*`, you'll sync with bar and baz. +- If you have **All except...** set, and enter the string `b*`, you'll just sync foo. + +Note that only the `*` wildcard is supported; you can't use other special characters or regexes. + +### Additional JDBC connection string options + +You can append options to the connection string that Metabase uses to connect to your database. E.g., `IgnoreTransactions=0`. + +See [Compute settings for the Databricks JDBC Driver](https://docs.databricks.com/en/integrations/jdbc/compute.html). + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any summarizations or filters in the query builder. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Model features + +There aren't (yet) any model features available for Databricks. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/druid.md b/_docs/doc-update-detection/databases/connections/druid.md new file mode 100644 index 000000000..12e5fd253 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/druid.md @@ -0,0 +1,82 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: Druid +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/druid.md' +--- + +# Druid + +> Prefer the Druid JDBC connection. + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +## Edit connection details + +Fill out the fields for that database, and click **Save changes** at the bottom. You can edit these settings at any time. Just remember to save your changes. + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address, or its domain name (e.g., esc.mydatabase.com). + +### Broker node port + +The database port (e.g, 8082). + +### Use an SSH tunnel + +See our [guide to SSH tunneling](../ssh-tunnel). + +### Allow unfolding of JSON columns + +> Only available for the Druid JDBC connection. + +This enables unfolding of JSON columns into their component fields. + +See [JSON unfolding](../../data-modeling/json-unfolding). + +### Authentication + +> Only available for the Druid JDBC connection. + +Toggle on to enable basic authentication with a username and password. + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Model features + +There aren't (yet) any model features available for Druid. + +## Danger zone + +See [Danger Zone](../danger-zone). + +## Further reading + +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/mariadb.md b/_docs/doc-update-detection/databases/connections/mariadb.md new file mode 100644 index 000000000..fa402bf45 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/mariadb.md @@ -0,0 +1,112 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: MariaDB +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/mariadb.md' +--- + +# MariaDB + +> This page covers connecting to MariaDB as a _data warehouse_. For using MariaDB as Metabase's _application database_, see [Configuring the Metabase application database](../../installation-and-operation/configuring-application-database). + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +MariaDB shares a driver with MySQL, so select the **MySQL** driver. + +## Supported versions + +Metabase supports the oldest supported version of Maria DB through the latest stable version. See [MariaDB Server releases](https://mariadb.com/kb/en/mariadb-server-release-dates/). + +## Edit connection details + +You can edit these settings at any time. Just remember to save your changes. + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address, or its domain name (e.g., esc.mydatabase.com). + +### Port + +The database port. E.g., 3306. + +### Username + +The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of [privileges](../users-roles-privileges). + +### Password + +The password for the username that you use to connect to the database. + +### Use a secure connection (SSL) + +You can paste your server's SSL certification chain. + +### Use an SSH tunnel + +See our [guide to SSH tunneling](../ssh-tunnel). + +### Unfold JSON Columns + +JSON folding is not supported for MariaDB databases. + +### Additional JDBC connection string options + +You can append options to the connection string that Metabase uses to connect to your database. + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [summarize](../../questions/query-builder/summarizing-and-grouping)) or [filter](../../questions/query-builder/filters) selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +#### Database syncing + +If you've selected **Choose when syncs and scans happen** > **ON**, you'll be able to set: + +- The frequency of the [sync](../sync-scan#how-database-syncs-work): hourly (default) or daily. +- The time to run the sync, in the timezone of the server where your Metabase app is running. + +#### Scanning for filter values + +Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database. + +If you've selected **Choose when syncs and scans happen** > **ON**, you'll see the following options under **Scanning for filter values**: + +- **Regularly, on a schedule** allows you to run [scan queries](../sync-scan#how-database-scans-work) at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often. +- **Only when adding a new filter widget** is a great option if you want scan queries to run on demand. Turning this option **ON** means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question. +- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which never really have new values added. Use the [Re-scan field values](../sync-scan#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date. + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Syncing records that include JSON + +JSON schema inference doesn't work with MariaDB, due to implementation differences between MySQL and MariaDB. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [MySQL](./mysql) +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/mongodb.md b/_docs/doc-update-detection/databases/connections/mongodb.md new file mode 100644 index 000000000..02799aee8 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/mongodb.md @@ -0,0 +1,145 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: MongoDB +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/mongodb.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/databases/mongodb +--- + +# MongoDB + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +## Supported versions + +Metabase supports the oldest supported version of MongoDB through the latest stable version. See [MongoDB Software Lifecycle Schedules](https://www.mongodb.com/legal/support-policy/lifecycles). + +## Connecting to MongoDB + +There are two ways to connect to MongoDB: + +1. Using the [Metabase fields to input your connection details](#using-metabase-fields). +2. Pasting your [connection string](#using-a-connection-string). + +### Using Metabase fields + +The default way to connect to MongoDB is to fill out your connection details in the fields Metabase provides: + +- Host +- Database name +- Port +- Username +- Password +- Authentication Database (optional) +- Additional connection string options (optional) + +You'll also have the option to **Use a secure connection (SSL)**. Enable SSL and paste the contents of the server's SSL certificate chain in the input text box. This option is available for this method of connection only (i.e. you cannot include a certificate when connecting with a connection string). + +### Advanced settings for direct connection + +- **Use DNS SRV when connecting** Using this option requires that provided host is a FQDN. If connecting to an Atlas cluster, you might need to enable this option. If you don't know what this means, leave this disabled. + +### Using a connection string + +If you'd prefer to connect to MongoDB using a [connection string](https://docs.mongodb.com/manual/reference/connection-string/), click on **Paste a connection string**. The Metabase user interface will update with a field to paste your connection string. + +Metabase currently does NOT support the following connection string parameters: + +- `tlsCertificateKeyFile` +- `tlsCertificateKeyFilePassword` +- `tlsCAFile` + +If you need to use a certificate, connect via the [default method](#using-metabase-fields) and enable **Use a secure connection(SSL)**. + +### Settings common to both connection options + +- **Use an SSH tunnel**: Some database installations can only be accessed by connecting through an SSH bastion host. This option also provides an extra layer of security when a VPN is not available. Enabling this is usually slower than a direct connection. +- **Rerun queries for simple exploration**: When this is on, Metabase will automatically run queries when users do simple explorations with the Summarize and Filter buttons when viewing a table or chart. You can turn this off if querying this database is slow. This setting doesn't affect drill-throughs or SQL queries. +- **Choose when syncs and scans happen**: See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). +- **Periodically refingerprint tables**: This setting — disabled by default — enables Metabase to scan for additional field values during syncs allowing smarter behavior, like improved auto-binning on your bar charts. + +## Connecting to a MongoDB Atlas cluster + +### Whitelist IP addresses + +If you are using Metabase Cloud, you'll need to whitelist [Metabase Cloud IP addresses](/docs/latest/cloud/ip-addresses-to-whitelist) in your Atlas cluster. If you are using self-hosted Metabase, you'll need to whitelist the IP of your Metabase instance. + +1. Log into your [Atlas cluster](https://cloud.mongodb.com) +2. Go to **Network Access** +3. Add the IP addresses that your Metabase uses to connect. + +### Connect Metabase to your Atlas cluster + +> The connection string provided in Atlas "Connect" interface does not include the database. Metabase requires you to provide a database name when connecting, so you'll need to edit the connection string to add the database name. + +1. Log into your [Atlas account](https://cloud.mongodb.com) + +2. Select the cluster you want to connect to, and click **Connect**. + + ![Your cluster screengrab](../images/atlas-connect.png) + +3. Select **Drivers**. + +4. Copy the connection string from **Add your connection string into your application code** section. + + ![Connect screengrab](../images/connection-string.png) + +5. In Metabase, go to Admin -> Databases, and click the **Add database** button. +6. Select MongoDB from the dropdown, and enter a **Display name** for this database. +7. Click on **"Paste the connection string"** and paste your connection string. +8. Edit the connection string to include the name of the database after `/`: + + ``` + mongodb+srv://metabot:metapass@my-test-cluster.a5ej7.mongodb.net/DATABASE_NAME?retryWrites=true&w=majority&appName=my-test-cluster + ``` + +If you're using Metabase fields to input connection information for your Atlas cluster instead of using the connection string, you might need to turn on **Use DNS SRV when connecting**. + +See more information about [Advanced options](#settings-common-to-both-connection-options). + +## Configuring SSL via the command line + +You can enter a self-signed certificate via the Metabase UI (though not when using a connection string), or you can use the command line to add a self-signed certificate. + +``` +cp /usr/lib/jvm/default-jvm/jre/lib/security/cacerts ./cacerts.jks +keytool -import -alias cacert -storepass changeit -keystore cacerts.jks -file my-cert.pem +``` + +Then, start Metabase using the store: + +``` +java -Djavax.net.ssl.trustStore=cacerts.jks -Djavax.net.ssl.trustStorePassword=changeit -jar metabase.jar +``` + +Learn more about [configuring SSL with MongoDB](http://mongodb.github.io/mongo-java-driver/3.0/driver/reference/connecting/ssl/). + +## How Metabase syncs data in MongoDB + +Because MongoDB contains unstructured data, Metabase takes a different approach to syncing your database's metadata. To get a sense of the schema, Metabase will query the first and last 500 documents (most of the calculation is done in MongoDB). This sampling helps Metabase do things like differentiate datetime fields from string fields, and provide people with pre-populated filters. The reason Metabase only scans a sample of the documents is because scanning every document in every collection on every sync would put too much strain on your database. And while the sampling does a pretty good job keeping Metabase up to date, it can also mean that new fields can sometimes fall through the cracks, leading to visualization issues, or even fields failing to appear in your results. For more info, check out our [troubleshooting guide](../../troubleshooting-guide/db-connection). + +## General connectivity concerns + +- **Connect using `DNS SRV`**, which is the recommended method for newer Atlas clusters. +- **Have you checked your cluster host whitelist?** When testing a connection but seeing failure, have you tried setting the IP whitelist to `0.0.0.0/0`? Whitelisting this address allows connections from any IP addresses. If you know the IP address(es) or CIDR block of clients, use that instead. +- **Connect to the secondary server**. When connecting to a cluster, always use the `?readPreference=secondary` argument in the connection string, which allows Metabase to read from a secondary server instead of consuming resources from the primary server. + +## I added fields to my database but don't see them in Metabase + +Metabase may not sync all of your fields. Since any document in a MongoDB collection can contain any number of fields, the only way to get 100% coverage of all fields would be to scan every single document in every single collection. The reason Metabase doesn't do a full scan is because it would put too much strain on your database. + +Instead, Metabase gets a sample of the fields in a collection by scanning a sample of 1000 documents in each collection (the first 500 documents and the last 500 documents in each collection). + +If you're not seeing all of the fields show up for a collection in Metabase, one workaround is to include all possible keys in the first document of the collection, and give those keys null values. That way, Metabase will be able to recognize the correct schema for the entire collection. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +See our troubleshooting guide for [troubleshooting your connection](../../troubleshooting-guide/db-connection). diff --git a/_docs/doc-update-detection/databases/connections/mysql.md b/_docs/doc-update-detection/databases/connections/mysql.md new file mode 100644 index 000000000..6ae55ff37 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/mysql.md @@ -0,0 +1,200 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: MySQL +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/mysql.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/databases/mysql +--- + +# MySQL + +> This page covers connecting to MySQL as a _data warehouse_. For using MySQL as Metabase's _application database_, see [Configuring the Metabase application database](../../installation-and-operation/configuring-application-database). + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +## Supported versions + +Metabase supports the oldest supported version through the latest stable version. See [MySQL end-of-life dates](https://endoflife.software/applications/databases/mysql). + +## Edit connection details + +You can edit these settings at any time. Just remember to save your changes. + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address, or its domain name (e.g., esc.mydatabase.com). + +### Port + +The database port. E.g., 3306. + +### Username + +The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of [privileges](../users-roles-privileges). + +### Password + +The password for the username that you use to connect to the database. + +### Use a secure connection (SSL) + +You can paste your server's SSL certification chain. + +### Use an SSH tunnel + +See our [guide to SSH tunneling](../ssh-tunnel). + +### Unfold JSON Columns + +For MySQL databases, Metabase can unfold JSON columns into component fields to yield a table where each JSON key becomes a column. JSON unfolding is on by default, but you can turn off JSON unfolding if performance is slow. + +If you turn on JSON unfolding, you can also toggle the unfolding for individual columns in [table metadata](../../data-modeling/metadata-editing#unfold-json). + +### Additional JDBC connection string options + +You can append options to the connection string that Metabase uses to connect to your database. + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Connecting to MySQL 8+ servers + +Metabase uses the MariaDB connector to connect to MySQL servers. The MariaDB connector lacks support for MySQL 8's default authentication plugin. In order to connect, you'll need to change the plugin used by the Metabase user: + +``` +mysql_native_password`: `ALTER USER 'metabase'@'%' IDENTIFIED WITH mysql_native_password BY 'thepassword'; +``` + +### Unable to log in with correct credentials + +**How to detect this:** Metabase fails to connect to your MySQL server with the error message "Looks like the username or password is incorrect", but you're sure that the username and password is correct. You may have created the MySQL user with an allowed host other than the host you're connecting from. + +For example, if the MySQL server is running in a Docker container, and your `metabase` user was created with `CREATE USER 'metabase'@'localhost' IDENTIFIED BY 'thepassword';`, the `localhost` will be resolved to the Docker container, and not the host machine, causing access to be denied. + +You can identify this issue by looking in the Metabase server logs for the error message: + +``` +Access denied for user 'metabase'@'172.17.0.1' (using password: YES). +``` + +Note the host name `172.17.0.1` (in this case a Docker network IP address), and `using password: YES` at the end. + +You'll see the same error message when attempting to connect to the MySQL server with the command-line client: `mysql -h 127.0.0.1 -u metabase -p`. + +**How to fix this:** Recreate the MySQL user with the correct host name: + +```sql +CREATE USER 'metabase'@'172.17.0.1' IDENTIFIED BY 'thepassword'; +``` + +Otherwise, if necessary, a wildcard may be used for the host name: + +```sql +CREATE USER 'metabase'@'%' IDENTIFIED BY 'thepassword'; +``` + +That user's permissions will need to be set: + +```sql +GRANT SELECT ON targetdb.* TO 'metabase'@'172.17.0.1'; +FLUSH PRIVILEGES; +``` + +Remember to drop the old user: + +```sql +DROP USER 'metabase'@'localhost'; +``` + +If you can't connect to the database, but the user, host, and password are correct, try adding `trustServerCertificate=true` to the additional JDBC options. This option will tell the Metabase driver to trust the server certificate even though it lacks a root certificate, and it should establish a secure connection. + +## Syncing records that include JSON + +**Metabase will infer the JSON "schema" based on the keys in the first five hundred rows of a table.** MySQL JSON fields lack schema, so Metabase can't rely on table metadata to define which keys a JSON field has. To work around the lack of schema, Metabase will get the first five hundred records and parse the JSON in those records to infer the JSON's "schema". The reason Metabase limits itself to five hundred records is so that syncing metadata doesn't put unnecessary strain on your database. + +The problem is that, if the keys in the JSON vary record to record, the first five hundred rows may not capture all the keys used by JSON objects in that JSON field. To get Metabase to infer all the JSON keys, you'll need to add the additional keys to the JSON objects in the first five hundred rows. + +## Raising a MySQL Docker container of MySQL 8+ + +If you are spinning up a new MySQL container, and: + +- you want Metabase to connect to the container without having to manually create the user or change the authentication mechanism, +- or you're facing a `RSA public key is not available client side (option serverRsaPublicKeyFile not set)` error, + +Use the `['--default-authentication-plugin=mysql_native_password']` modifiers when you run the container, like so: + +- a simple docker run: `docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=xxxxxx mysql:8.xx.xx --default-authentication-plugin=mysql_native_password` + +- or in docker-compose: + +```yml +mysql: + image: mysql:8.xx.xx + container_name: mysql + hostname: mysql + ports: + - 3306:3306 + environment: + - "MYSQL_ROOT_PASSWORD=xxxxxx" + - "MYSQL_USER=metabase" + - "MYSQL_PASSWORD=xxxxxx" + - "MYSQL_DATABASE=metabase" + volumes: + - $PWD/mysql:/var/lib/mysql + command: ["--default-authentication-plugin=mysql_native_password"] +``` + +## Limitations with Vitess-based databases + +- When querying Vitess databases (like Planetscale), you should add a `LIMIT` clause inside each subquery. + + The reason: typically, Metabase applies limits (e.g., 2000 or 10000 rows) to the final query results. But due to a known bug in Vitess, Vitess might apply these limits to subqueries, which can lead to unexpected results (for example, not all rows of results will be displayed within Metabase). The workaround is to add limits to each of your subqueries. + +- You may want to check in with the vendor that's hosting the platform, as Vitess can run into issues returning metadata from the information schema. Metabase needs this metadata to populate its application database; if Metabase can't get that metadata, fields may not appear (or appear empty). + +## Model features + +Choose whether to enable features related to [Metabase models](../../data-modeling/models). These features will often require that the database user account, the one you use to connect to your database, has both read and write privileges. + +### Model actions + +Turn this setting on to allow [actions](../../actions/introduction) from models created from this data to be run. Actions are able to read, write, and possibly delete data. Your database user will need write permissions. + +### Model persistence + +We'll create tables with model data and refresh them on a schedule you define. To enable [model persistence](../../data-modeling/model-persistence), you need to grant this connection's credentials read and write permissions on a schema Metabase provides. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [MariaDB](./mariadb) +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/oracle.md b/_docs/doc-update-detection/databases/connections/oracle.md new file mode 100644 index 000000000..3e761d916 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/oracle.md @@ -0,0 +1,145 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: Oracle +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/oracle.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/databases/oracle +--- + +# Oracle + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +## Supported versions + +Metabase supports the oldest supported version through the latest stable version. See [Oracle's Release Schedule of Current Database Releases](https://support.oracle.com/knowledge/Oracle%20Database%20Products/742060_1.html). + +## Edit connection details + +You can edit these settings at any time. Just remember to save your changes. + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address, or its domain name (e.g., esc.mydatabase.com). + +### Port + +The database port. E.g., 1521. + +### Oracle system ID (SID) + +Usually something like ORCL or XE. Optional if using service name. + +### Oracle service name + +Optional TNS alias. + +### Username + +The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of [privileges](../users-roles-privileges). + +### Password + +The password for the username that you use to connect to the database. + +### Use a secure connection (SSL) + +You can use both client and server authentication (known as mutual authentication). + +### Connecting to Oracle Cloud Autonomous Database + +If you've configured your database to require mutual TLS (mTLS), you'll need a [wallet](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/connect-download-wallet.html#GUID-DED75E69-C303-409D-9128-5E10ADD47A35). To download your wallet: + +1. Go to your Oracle Autonomous Database. +2. Go to the database's details. +3. Click on **DB connection**. +4. Download the wallet. +5. Create a password for the keyfile. +6. Copy the `keystore.jks` file to wherever you store your Metabase configuration data. +7. Use `JAVA_OPTS` to let Metabase know about the keystore's location and password (for more info on keystores, see the next section). +8. In Metabase, on the data connection page, enter your `host`, `port`, and `service_name`. You can find these values in the `tsnnames.ora` file. + +#### Client authentication with a keystore + +To configure the server (the Oracle server) to authenticate the identity of the client (Metabase), you need to +configure a keystore file that includes the client's private key. + +You'll import the client's private key into the keystore (rather than a root CA into a truststore file). Add the following JVM options for Metabase: + +``` +-Djavax.net.ssl.keyStore=/path/to/keystore.jks +-Djavax.net.ssl.keyStoreType=JKS \ +-Djavax.net.ssl.keyStorePassword= +``` + +You can define these with the `JAVA_OPTS` environment variable, like so: + +```sh +JAVA_OPTS: "-Djavax.net.ssl.keyStore=/scripts/keystore.jks -Djavax.net.ssl.keyStoreType=JKS -Djavax.net.ssl.keyStorePassword=" +``` + +With this done, the Oracle server will authenticate Metabase using the private key when Metabase tries to connect over SSL. + +#### Server authentication with a truststore + +To configure the client (Metabase) to authenticate the identity of the server (the Oracle server), you may need to +configure a truststore file that includes the server's root CA, so that the JVM running Metabase trusts its +certificate chain. Refer to the +[Oracle documentation](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html) on using `keytool` to manage key and truststore files, importing certificates, etc. + +For more information on setting up a truststore for AWS RDS Oracle instances, see the +[instructions provided by Amazon](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.Oracle.Options.SSL.html#Appendix.Oracle.Options.SSL.JDBC). + +If you need to connect to other databases using SSL, instead of creating a new truststore, you'll probably want to add the RDS CA to your existing truststore file (likely called `cacerts`). + +## Supported Oracle database and Oracle driver versions + +- **Driver version**: the minimum Oracle driver version should be 19c, regardless of which Java version or Oracle database version you have. +- **Database version**: the minimum database version should be version 19c, as Oracle [no longer supports database versions before 19](https://endoflife.date/oracle-database). + +## Downloading the Oracle JDBC Driver JAR + +You can download a JDBC driver from [Oracle's JDBC driver downloads page](https://www.oracle.com/technetwork/database/application-development/jdbc/downloads/index.html). + +We recommend using the `ojdbc8.jar` JAR. + +## Adding the Oracle JDBC Driver JAR to the Metabase plugins directory + +In your Metabase directory (the directory where you keep and run your metabase.jar), create a directory called `plugins` (if it doesn't already exist. + +Move the JAR you just downloaded (`ojdbc8.jar`) into the plugins directory, and restart Metabase. Metabase will automatically make the Oracle driver available when it starts back up. + +### When running from a JAR + +By default, the plugins directory is called `plugins`, and lives in the same directory as the Metabase JAR. + +For example, if you're running Metabase from a directory called `/app/`, you should move the Oracle JDBC driver JAR to `/app/plugins/`: + +```txt +# example directory structure for running Metabase with Oracle support +/app/metabase.jar +/app/plugins/ojdbc8.jar +``` + +### When running from Docker + +The process for adding plugins when running via Docker is similar, but you'll need to mount the `plugins` directory. Refer to instructions [here](../../installation-and-operation/running-metabase-on-docker#adding-external-dependencies-or-plugins) for more details. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/postgresql.md b/_docs/doc-update-detection/databases/connections/postgresql.md new file mode 100644 index 000000000..60f549065 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/postgresql.md @@ -0,0 +1,204 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: PostgreSQL +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/postgresql.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/databases/postgresql +--- + +# PostgreSQL + +> This page covers connecting to PostgreSQL as a _data warehouse_. For using PostgreSQL as Metabase's _application database_, see [Configuring the Metabase application database](../../installation-and-operation/configuring-application-database). + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +Fill out the fields for that database, and click **Save changes** at the bottom. + +## Supported versions + +Metabase supports the oldest supported version of PostgreSQL through the latest stable version. See [PostgreSQL versions](https://www.postgresql.org/support/versioning/). + +## Connection and sync + +After connecting to a database, you'll see the "Connection and sync" section that displays the current connection status and options to manage your database connection. + +Here you can [sync the database schema and rescan field values](../sync-scan), and edit connection details. + +## Edit connection details + +You can edit these settings at any time. Just remember to save your changes. + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address, or its domain name (e.g., esc.mydatabase.com). + +### Port + +The database port. E.g., 5432. + +### Database name + +The name of the database you're connecting to. + +### Username + +The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of [privileges](../users-roles-privileges). + +### Password + +The password for the username that you use to connect to the database. + +### Use an authentication provider + +{% include plans-blockquote.html feature="Authenticating with a provider" %} + +Instead of a password, you can authenticate with a supported provider. + +Only for self-hosted Pro and Enterprise plans. + +#### Azure Managed Identity + +To use Azure Managed Identity, you'll need to input your [client ID](https://learn.microsoft.com/en-us/previous-versions/azure/postgresql/single-server/how-to-connect-with-managed-identity#retrieving-the-access-token-from-azure-instance-metadata-service). + +#### Oauth + +To use Oauth as a provider, you'll need to input your: + +- Auth token URL +- Auth token request headers (a JSON map) + +### Schemas + +You can specify which schemas you want to sync and scan. Options are: + +- All +- Only these... +- All except... + +For the **Only these** and **All except** options, you can input a comma-separated list of values to tell Metabase which schemas you want to include (or exclude). For example: + +``` +foo,bar,baz +``` + +You can use the `*` wildcard to match multiple schemas. + +Let's say you have three schemas: foo, bar, and baz. + +- If you have **Only these...** set, and enter the string `b*`, you'll sync with bar and baz. +- If you have **All except...** set, and enter the string `b*`, you'll just sync foo. + +Note that only the `*` wildcard is supported; you can't use other special characters or regexes. + +### Use a secure connection (SSL) + +Metabase automatically tries to connect to databases with SSL first, then without if that doesn't work. If it's possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we highly recommend keeping SSL turned on to keep your data secure. + +#### SSL Mode + +PostgreSQL databases support different levels of security with their connections, with different levels of overhead. + +SSL Mode options include: + +- allow +- prefer +- require +- verify-ca +- verify-full + +See the PostgreSQL docs for a table about the different [SSL Modes](https://jdbc.postgresql.org/documentation/ssl/#configuring-the-client), and select the option that works for you. + +#### SSL root certificate (PEM) + +If you set the SSL Mode to either "verify-ca" or "verify-full", you'll need to specify a root certificate (PEM). You have the option of using a **Local file path** or an **Uploaded file path**. If you're on Metabase Cloud, you'll need to select **Uploaded file path** and upload your certificate. + +#### Authenticate client certificate + +Toggle on to bring up client certificate options. + +#### SSL Client Certificate (PEM) + +You have the option of using a **Local file path** or an **Uploaded file path**. If you're on Metabase Cloud, you'll need to select **Uploaded file path** and upload your certificate. + +#### SSL Client Key (PKCS-8/DER) + +Again, you have the option of using a **Local file path** or an **Uploaded file path**. If you're on Metabase Cloud, you'll need to select **Uploaded file path** and upload your certificate. You'll also need to input your **SSL Client Key Password**. + +The private key must be PKCS8 and stored in DER format. + +If you instead have a PEM SSL client key, you can convert that key to the PKCS-8/DER format using [openssl](https://www.openssl.org/). The command would look something like: + +``` +openssl pkcs8 -topk8 -inform PEM -outform DER -in client-key.pem -out client-key.der -nocrypt +``` + +Note: if you're using GCP and you managed to issue client certificates, everything will be given in PEM format, you only need to transform the client-key.pem into a client-key.der for the "SSL Client Key" + +### Use an SSH tunnel + +See our [guide to SSH tunneling](../ssh-tunnel). + +### Unfold JSON Columns + +For PostgreSQL databases, Metabase can unfold JSON columns into component fields to yield a table where each JSON key becomes a column. JSON unfolding is on by default, but you can turn off JSON unfolding if performance is slow. + +If you turn on JSON unfolding, you can also toggle the unfolding for individual columns in [table metadata](../../data-modeling/metadata-editing#unfold-json). + +### Additional JDBC connection string options + +You can append options to the connection string that Metabase uses to connect to your database. Use the format: + +``` +options=-c%20key=value +``` + +PostgreSQL connection URIs expect [percent-encoding](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding) for whitespaces and symbols. + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Model features + +Choose whether to enable features related to [Metabase models](../../data-modeling/models). These features will often require that the database user account, the one you use to connect to your database, has both read and write privileges. + +### Model actions + +Turn this setting on to allow [actions](../../actions/introduction) from models created from this data to be run. Actions are able to read, write, and possibly delete data. Your database user will need write permissions. + +### Model persistence + +We'll create tables with model data and refresh them on a schedule you define. To enable [model persistence](../../data-modeling/model-persistence), you need to grant this connection's credentials read and write permissions on a schema Metabase provides. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/presto.md b/_docs/doc-update-detection/databases/connections/presto.md new file mode 100644 index 000000000..09c1cb009 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/presto.md @@ -0,0 +1,108 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: Presto +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/presto.md' +--- + +# Presto + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +Fill out the fields for that database, and click **Save changes** at the bottom. + +## Edit connection details + +You can edit these settings at any time. Just remember to save your changes. + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address, or its domain name (e.g., esc.mydatabase.com). + +### Port + +The database port. E.g., 8080. + +### Catalog + +Presto catalogs contain schemas and reference data sources via a connector. + +### Schema (optional) + +Only add tables to Metabase that come from a specific schema. + +### Username + +The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of [privileges](../users-roles-privileges). + +### Password + +The password for the username that you use to connect to the database. + +### Use a secure connection (SSL) + +Metabase automatically tries to connect to databases with SSL first, then without if that doesn't work. If it's possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we highly recommend keeping SSL turned on to keep your data secure. + +### Use SSL certificate? + +Metabase supports both keystores and truststores. + +#### Keystore + +You can specify a local file path, or upload a keystore. You'll also need to input your keystore password. + +#### Truststore + +You can specify a local file path, or upload a truststore. You'll also need to input your truststore password. + +### Authenticate with Kerberos + +Kerberos settings include: + +- Kerberos principal (e.g., `service/instance@REALM`) +- Kerberos coordinator service (e.g., `presto`) +- You can use a canonical hostname. +- Kerberos credential cache file (e.g., `/tmp/kerbo-credential-cache`) +- Kerberos keytab file (e.g., `/path/to/kerberos.keytab`) +- Kerberos configuration file (e.g., `/etc/krb5.conf`) +- Presto coordinator Kerberos service principal pattern (e.g., `${SERVICE}@${HOST}.${SERVICE}` + +### Additional JDBC connection string options + +You can append options to the connection string that Metabase uses to connect to your database. + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/redshift.md b/_docs/doc-update-detection/databases/connections/redshift.md new file mode 100644 index 000000000..e2ee3de82 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/redshift.md @@ -0,0 +1,122 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'Amazon Redshift' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/redshift.md' +description: 'Connect Metabase to Amazon Redshift data warehouses to run queries and create dashboards.' +redirect_from: + - /docs/doc-update-detection/administration-guide/databases/redshift +--- + +# Amazon Redshift + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +## Connection and sync + +After connecting to a database, you'll see the "Connection and sync" section that displays the current connection status and options to manage your database connection. + +Here you can [sync the database schema and rescan field values](../sync-scan), and edit connection details. + +## Edit connection details + +To access or modify your database connection settings, click the **Edit connection details** button. + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address, or its domain name (e.g., esc.mydatabase.com). + +### Port + +The database port. E.g., 3306. + +### Database name + +The name of the database you want to connect to. + +### Schemas + +Here you can specify which schemas you want to sync and scan. Options are: + +- All +- Only these... +- All except... + +For the **Only these** and **All except** options, you can input a comma-separated list of values to tell Metabase which schemas you want to include (or exclude). For example: + +``` +foo,bar,baz +``` + +You can use the `*` wildcard to match multiple schemas. + +Let's say you have three schemas: foo, bar, and baz. + +- If you have **Only these...** set, and enter the string `b*`, you'll sync with bar and baz. +- If you have **All except...** set, and enter the string `b*`, you'll just sync foo. + +Note that only the `*` wildcard is supported; you can't use other special characters or regexes. + +### Username + +> In order for sync and scan to work, make sure this database user account has access to the `information_schema`. + +The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of [privileges](../users-roles-privileges). + +### Password + +The password for the username that you use to connect to the database. + +### Use an SSH tunnel + +See our [guide to SSH tunneling](../ssh-tunnel). + +### Additional JDBC connection string options + +You can append options to the connection string that Metabase uses to connect to your database. + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Model features + +Choose whether to enable features related to Metabase models. These will often require a write connection. + +### Model persistence + +You can enable model persistence to allow Metabase to create tables with model data and refresh them on a schedule. This requires write permissions to a designated schema. + +Check out [Model persistence](../../data-modeling/model-persistence). + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/snowflake.md b/_docs/doc-update-detection/databases/connections/snowflake.md new file mode 100644 index 000000000..95b9841fc --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/snowflake.md @@ -0,0 +1,149 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: Snowflake +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/snowflake.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/databases/snowflake +--- + +# Snowflake + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +You can edit these settings at any time. Just remember to save your changes. + +## Display name + +The display name for the database in the Metabase interface. + +## Account or hostname + +You have the option of using an account name or hostname. Your hostname is your database's IP address or its domain name (e.g., database.example.com). + +If your URL includes your database's region, you can connect using an account name, otherwise connect using a hostname. + +### AWS + +Connect with an account name. + +Enter your Account identifier with the region that your Snowflake cluster is running on. E.g., `xxxxxxxxx.us-east-3.aws`. For example, if you're running Snowflake on AWS and your account URL is `https://az12345.ca-central-1.snowflakecomputing.com`: + +- ``: `az12345.ca-central-1`. +- ``: `aws`. + +You'd enter `az12345.ca-central-1.aws` as the account name in Metabase. + +Not all regions require the cloud platform identifier. If you're in `us-west-2`, you would enter `az12345` as the account name. For the requirements per region, see [the official Snowflake's documentation](https://docs.snowflake.com/en/user-guide/admin-account-identifier.html#non-vps-account-locator-formats-by-cloud-platform-and-region). + +### app.snowflake.com + +Connect with a host name. + +You can get your host name by going to Admin > Accounts. The Account name will be under Accounts. Click on the account you want to use, and click on the link icon to copy the host URL: that's your host name. In the image below, Metabot is discreetly covering sensitive info. The "Copy account URL" link on the right is what you're looking for: + +![Snowflake copy account URL](../images/snowflake-copy-account-url.png) + +Learn more about [Account Identifiers in Snowflake](https://docs.snowflake.com/en/user-guide/admin-account-identifier). + +## Username + +The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of [privileges](../users-roles-privileges). + +On your app.snowflake.com account page, you can find Users and roles under Admin > Users & Roles. + +## Password + +The password for the username that you use to connect to the database. + +## RSA private key (PEM) + +Not required. You have the option of using a **Local file path** or an **Uploaded file path**. If you're on Metabase Cloud, you'll need to select **Uploaded file path** and upload your certificate. + +## Warehouse + +Snowflake warehouse. If the user lacks a default warehouse, you'll need to enter the warehouse to connect to. + +On app.snowflake.com, you can find warehouses under Admin > Warehouses. + +## Database name (case sensitive) + +The name of the database you want to connect to in Snowflake. On app.snowflake.com you can find databases under Data > Databases. + +## Schemas (optional) + +You can specify which schemas you want to sync and scan. If no schema is passed, then all schema available to that user and role will be listed as folders in Metabase. + +Schema options include: + +- All +- Only these... +- All except... + +For the **Only these** and **All except** options, you can input a comma-separated list of values to tell Metabase which schemas you want to include (or exclude). For example: + +``` +FOO,BAR,BAZ +``` + +You can use the `*` wildcard to match multiple schemas. + +Let's say you have three schemas: FOO, BAR, and BAZ. + +- If you have **Only these...** set, and enter the string `B*`, you'll sync with bar and baz. +- If you have **All except...** set, and enter the string `B*`, you'll just sync foo. + +Note that only the `*` wildcard is supported; you can't use other special characters or regexes. + +## Role (optional) + +Specify a role to override the database user's default role. For example, if the database user `METABASE` has the roles: + +- Default role `APPLICATION`. +- Additional role `ANALYTICS`. + +You can enter `ANALYTICS` in the Role field to ensure that the `METABASE` user connects to Snowflake using the `ANALYTICS` role by default. + +## Use an SSH tunnel + +See our [guide to SSH tunneling](../ssh-tunnel). + +## Additional JDBC connection string options + +Some databases allow you to append options to the connection string that Metabase uses to connect to your database. + +## Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +## Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Model features + +There aren't (yet) any model features available for Snowflake. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/sparksql.md b/_docs/doc-update-detection/databases/connections/sparksql.md new file mode 100644 index 000000000..1f61d776b --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/sparksql.md @@ -0,0 +1,91 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: SparkSQL +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/sparksql.md' +--- + +# SparkSQL + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +## Settings + +You can edit these settings at any time. Just remember to save your changes. + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address, or its domain name (e.g., esc.mydatabase.com). + +### Port + +The database port. E.g., 10000 + +### Username + +The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of [privileges](../users-roles-privileges). + +### Password + +The password for the username that you use to connect to the database. + +### Use an SSH tunnel + +See our [guide to SSH tunneling](../ssh-tunnel). + +### Additional JDBC connection string options + +You can append options to the connection string that Metabase uses to connect to your database. + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when Metabase syncs and scans + +Turn this option **ON** to manage the queries that Metabase uses to stay up to date with your database. For more information, see [Syncing and scanning databases](../sync-scan). + +#### Database syncing + +If you've selected **Choose when syncs and scans happen** > **ON**, you'll be able to set: + +- The frequency of the [sync](../sync-scan#how-database-syncs-work): hourly (default) or daily. +- The time to run the sync, in the timezone of the server where your Metabase app is running. + +#### Scanning for filter values + +Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database. + +If you've selected **Choose when syncs and scans happen** > **ON**, you'll see the following options under **Scanning for filter values**: + +- **Regularly, on a schedule** allows you to run [scan queries](../sync-scan#how-database-scans-work) at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often. +- **Only when adding a new filter widget** is a great option if you want scan queries to run on demand. Turning this option **ON** means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question. +- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which never really have new values added. Use the [Re-scan field values now](../sync-scan#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date. + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/sql-server.md b/_docs/doc-update-detection/databases/connections/sql-server.md new file mode 100644 index 000000000..d27fa6e8a --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/sql-server.md @@ -0,0 +1,112 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'SQL Server' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/sql-server.md' +--- + +# SQL Server + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +## Supported versions + +Metabase supports the oldest supported version of SQL Server through the latest stable version. See [SQL Server end of support options](https://learn.microsoft.com/en-us/sql/sql-server/end-of-support/sql-server-end-of-support-overview). + +## Settings + +You can edit these settings at any time. Just remember to save your changes. + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address, or its domain name (e.g., esc.mydatabase.com). + +### Port + +The database port. E.g., 1433. To use Dynamic Ports, leave this field empty. + +### Database name + +The name of the database you're connecting to. + +### Database instance name + +If you're running multiple databases on the same host, you can include the instance name here. + +### Username + +The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of [privileges](../users-roles-privileges). + +### Password + +The password for the username that you use to connect to the database. + +### Use a secure connection (SSL) + +Metabase automatically tries to connect to databases with SSL first, then without if that doesn't work. If it's possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we highly recommend keeping SSL turned on to keep your data secure. + +### Use an SSH tunnel + +See our [guide to SSH tunneling](../ssh-tunnel). + +### Additional JDBC connection string options + +You can append options to the connection string that Metabase uses to connect to your database. + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +#### Database syncing + +If you've selected **Choose when syncs and scans happen** > **ON**, you'll be able to set: + +- The frequency of the [sync](../sync-scan#how-database-syncs-work): hourly (default) or daily. +- The time to run the sync, in the timezone of the server where your Metabase app is running. + +### Scanning for filter values + +Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database. + +If you've selected **Choose when syncs and scans happen** > **ON**, you'll see the following options under **Scanning for filter values**: + +- **Regularly, on a schedule** allows you to run [scan queries](../sync-scan#how-database-scans-work) at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often. +- **Only when adding a new filter widget** is a great option if you want scan queries to run on demand. Turning this option **ON** means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question. +- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which never really have new values added. Use the [Re-scan field values](../sync-scan#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date. + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Connecting to Azure SQL + +To connect to Azure SQL, you'll need to set the port to 1433. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [Microsoft JDBC Driver for SQL Server support matrix](https://learn.microsoft.com/en-us/sql/connect/jdbc/microsoft-jdbc-driver-for-sql-server-support-matrix) +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/sqlite.md b/_docs/doc-update-detection/databases/connections/sqlite.md new file mode 100644 index 000000000..47a610990 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/sqlite.md @@ -0,0 +1,75 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: SQLite +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/sqlite.md' +--- + +# SQLite + +> SQLite isn't available for [Metabase Cloud](/cloud/). + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +Fill out the fields for that database, and click **Save changes** at the bottom. + +## Settings + +You can edit these settings at any time. Just remember to save your changes. + +### Display name + +The display name for the database in the Metabase interface. + +### Filename + +The location of the SQLite database (the absolute path). + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when Metabase syncs and scans + +Turn this option **ON** to manage the queries that Metabase uses to stay up to date with your database. For more information, see [Syncing and scanning databases](../sync-scan). + +#### Database syncing + +If you've selected **Choose when syncs and scans happen** > **ON**, you'll be able to set: + +- The frequency of the [sync](../sync-scan#how-database-syncs-work): hourly (default) or daily. +- The time to run the sync, in the timezone of the server where your Metabase app is running. + +### Scanning for filter values + +Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database. + +If you've selected **Choose when syncs and scans happen** > **ON**, you'll see the following options under **Scanning for filter values**: + +- **Regularly, on a schedule** allows you to run [scan queries](../sync-scan#how-database-scans-work) at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often. +- **Only when adding a new filter widget** is a great option if you want scan queries to run on demand. Turning this option **ON** means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question. +- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which never really have new values added. Use the [Re-scan field values](../sync-scan#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date. + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Danger zone + +See [Danger zone](../danger-zone). + +## Further reading + +- [Managing databases](../../databases/connecting) +- [Metadata editing](../../data-modeling/metadata-editing) +- [Models](../../data-modeling/models) +- [Setting data access permissions](../../permissions/data) diff --git a/_docs/doc-update-detection/databases/connections/starburst.md b/_docs/doc-update-detection/databases/connections/starburst.md new file mode 100644 index 000000000..0305684aa --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/starburst.md @@ -0,0 +1,102 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: Starburst +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/starburst.md' +description: 'Learn how to connect Metabase to your Starburst or Trino database, including connection settings, SSL configuration, and database sync options.' +--- + +# Starburst + +> This driver also works for connections to a Trino database. + +To add a database connection, click on the **gear** icon in the top right, and navigate to **Admin settings** > **Databases** > **Add a database**. + +You can edit these settings at any time. Just remember to save your changes. + +## Connection and Sync + +After connecting to a database, you'll see the "Connection and sync" section that displays the current connection status and options to manage your database connection. + +Here you can [sync the database schema and rescan field values](../sync-scan), and edit connection details. + +## Edit connection details + +To access or modify your database connection settings, click the **Edit connection details** button. + +### Display name + +The display name for the database in the Metabase interface. + +### Host + +Your database's IP address (e.g., `98.137.149.56`) or its domain name (e.g., `name.database.com`). + +### Port + +The database port (e.g., `8080`). + +### Catalog + +Starburt catalogs contain schemas and reference data sources via a connector. + +### Schema (optional) + +Only add tables that come from a specific schema. + +### Username + +The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of [privileges](../users-roles-privileges). + +### Password + +The password for the username that you use to connect to the database. + +### Use a secure connection (SSL) + +See [SSL certificates](../ssl-certificates). + +### Role (optional) + +Specify a role to override the database user's default role. + +### Optimize prepared statements + +Requires Starburst Galaxy, Starburst Enterprise (version 420-e or higher), or Trino (version 418 or higher). + +### Additional JDBC connection string options + +You can append options to the JDBC connection string. Separate options with `&`, like so: + +``` +connection_timeout=1000&socket_timeout=300000 +``` + +### Re-run queries for simple explorations + +Turn this option **OFF** if people want to click **Run** (the play button) before applying any [Summarize](../../questions/query-builder/summarizing-and-grouping) or filter selections. + +By default, Metabase will execute a query as soon as you choose an grouping option from the **Summarize** menu or a filter condition from the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). If your database is slow, you may want to disable re-running to avoid loading data on each click. + +### Choose when syncs and scans happen + +See [syncs and scans](../sync-scan#choose-when-syncs-and-scans-happen). + +### Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +Turn this option **ON** to scan a sample of values every time Metabase runs a [sync](../sync-scan#how-database-syncs-work). + +A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option **OFF**, Metabase will only fingerprint your columns once during setup. + +## Model features + +There aren't (yet) any model features for ClickHouse. + +## Danger zone + +See [Danger zone](../danger-zone). diff --git a/_docs/doc-update-detection/databases/connections/vertica.md b/_docs/doc-update-detection/databases/connections/vertica.md new file mode 100644 index 000000000..aeeae60e9 --- /dev/null +++ b/_docs/doc-update-detection/databases/connections/vertica.md @@ -0,0 +1,56 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'Working with Vertica in Metabase' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/connections/vertica.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/databases/vertica +--- + +# Working with Vertica in Metabase + +Starting in v0.20.0, Metabase provides a driver for connecting to Vertica databases. Under the hood, Metabase uses Vertica's JDBC driver; +due to licensing restrictions, we can't include it as part of Metabase. Luckily, downloading it yourself and making it available to Metabase +is straightforward and only takes a few minutes. + +## Downloading the Vertica JDBC Driver JAR + +You can download the JDBC driver from [Vertica's JDBC driver downloads page](https://my.vertica.com/download/vertica/client-drivers/). +Head to this page, log in to your account, accept the license agreement, and download `vertica-jdbc-8.0.0-0.jar` (for Vertica DB version 8.0) +or whatever driver version most closely matches the version of Vertica you're running. + +It's very important to make sure you use the correct version of the JDBC driver; version +8.0 of the driver won't work with Vertica version 7.2; version 7.2 of the driver won't work with Vertica version 7.1, and so forth. If in doubt, +consult Vertica's documentation to find the correct version of the JDBC driver for your version of Vertica. + +## Adding the Vertica JDBC Driver JAR to the Metabase Plugins Directory + +Metabase will automatically make the Vertica driver available if it finds the Vertica JDBC driver JAR in the Metabase plugins directory when it starts up. +All you need to do is create the directory, move the JAR you just downloaded into it, and restart Metabase. + +### When running from a JAR + +By default, the plugins directory is called `plugins`, and lives in the same directory as the Metabase JAR. + +For example, if you're running Metabase from a directory called `/app/`, you should move the Vertica JDBC driver JAR to `/app/plugins/`: + +```txt +# example directory structure for running Metabase with Vertica support +/app/metabase.jar +/app/plugins/vertica-jdbc-8.0.0-0.jar +``` + +### When running from Docker + +The process for adding plugins when running via Docker is similar, but you'll need to mount the `plugins` directory. Refer to instructions [here](../../installation-and-operation/running-metabase-on-docker#adding-external-dependencies-or-plugins) for more details. + +## Model features + +There aren't (yet) any model features for Vertica. + +## Danger zone + +See [Danger zone](../danger-zone). diff --git a/_docs/doc-update-detection/databases/danger-zone.md b/_docs/doc-update-detection/databases/danger-zone.md new file mode 100644 index 000000000..fcc3c9b50 --- /dev/null +++ b/_docs/doc-update-detection/databases/danger-zone.md @@ -0,0 +1,36 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'Danger zone' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/danger-zone.md' +description: 'The Danger Zone section of database connections is where you can discard field values or remove database connections and all of their related content.' +--- + +# Danger Zone + +The Danger zone section of the database connection is the destructive section. Here you can discard field values for that database, or remove the database entirely. + +But since of course you're making [backups of your Metabase application database](../installation-and-operation/backing-up-metabase-application-data), it's not _that_ destructive. But these changes are permanent in Metabase. The only way to get your stuff back is if you restore your Metabase application database from a backup. If you're on [Metabase Cloud](/cloud/), backups are handled for you. + +To access the Danger Zone section for a database connection: + +1. Click on the **gear** icon in the top right of Metabase. +2. Go to **Admin settings** > **Databases**. +3. Find the database you want to modify and click on it. +4. Scroll down to the bottom of the database's settings page to find the "Danger Zone" section. + +## Discard saved field values + +This option allows you to clear all saved field values that were collected during [syncs and fingerprinting](./sync-scan). This will remove the cached information about your database's fields, but won't affect your actual database data or connection settings. + +## Remove this database + +> If you’re trying to migrate from a development DB to a production one, you don’t need to do this. You can just +> edit your connection details. + +This will delete the database _connection_ (not your database and its data). But deleting the connection will also delete all of the questions, models, metrics, segments. You'll have to check a bunch of boxes to even do this to make you know what you're doing. + +This action is irreversible in Metabase. If you accidentally delete a database connection, the only way to get your stuff back is to restore your Metabase from the last [backup of your application database](../installation-and-operation/backing-up-metabase-application-data). diff --git a/_docs/doc-update-detection/databases/encrypting-details-at-rest.md b/_docs/doc-update-detection/databases/encrypting-details-at-rest.md new file mode 100644 index 000000000..6606332b8 --- /dev/null +++ b/_docs/doc-update-detection/databases/encrypting-details-at-rest.md @@ -0,0 +1,66 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'Encrypting your database connection' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/encrypting-details-at-rest.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/encrypting-database-details-at-rest +--- + +# Encrypting your database connection + +Metabase stores connection information for the various databases you add in the [Metabase application database](/glossary/application_database). To prevent bad actors from being able to access these details if they were to gain access to the application DB, Metabase can automatically encrypt them with AES256 + SHA512 when they are saved, and decrypt them on-the-fly whenever they are needed. + +## Creating an encryption key + +1. Generate a secret key that is at least 16 characters (longer is even better!). We recommend using a secure random key generator, such as `openssl`. + > You cannot decrypt connection details without this key. If you lose (or change) the key, you'll have to reset all of the connection details that have been encrypted with that key in the Admin Panel. +2. Set your secret key as the environment variable `MB_ENCRYPTION_SECRET_KEY`. On self-hosted [Pro and Enterprise plans](/pricing/) plans, you can set also set this using the [config file](../configuring-metabase/config-file). + +### Example commands for creating and adding a key + +1. You can use `openssl` to generate a cryptographically-secure, randomly-generated 32-character key. + ``` + openssl rand -base64 32 + ``` +2. Copy the key to your clipboard. It should look something like this: + ``` + IYqrSi5QDthvFWe4/WdAxhnra5DZC3RKx3ZSrOJDKsM= + ``` +3. Set the key as an environment variable and start Metabase as usual. + ``` + MB_ENCRYPTION_SECRET_KEY="IYqrSi5QDthvFWe4/WdAxhnra5DZC3RKx3ZSrOJDKsM=" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar + ``` + +Once you set the `MB_ENCRYPTION_SECRET_KEY` value, Metabase will automatically encrypt and store the connection details for each new database that you add. To encrypt existing connections, see the next section. + +## Encrypting an existing connection + +If you added databases before setting the `MB_ENCRYPTION_SECRET_KEY` value, you can encrypt the connection details by going to each one of those databases in **Admin settings** > **Databases** and clicking on the **Save** button. Existing databases with unencrypted details will continue to work normally. + +## Rotating an encryption key + +1. We recommend that you [backup](../installation-and-operation/backing-up-metabase-application-data) your data before doing a key rotation. +2. Stop running your Metabase app. +3. Run the CLI command `rotate-encryption-key`. + - Set the current encryption key as `MB_ENCRYPTION_SECRET_KEY`. + - Set the new encryption key as a parameter. + +### Example command for rotating a key + +``` +MB_ENCRYPTION_SECRET_KEY=your-current-key java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar rotate-encryption-key new-key +``` + +## Disabling an encryption key + +To disable an encryption key, follow the steps to [rotate an encryption key](#rotating-an-encryption-key), but use an empty string (`""`) as the new key. + +### Example command for disabling a key + +``` +MB_ENCRYPTION_SECRET_KEY="your-current-key" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar rotate-encryption-key "" +``` diff --git a/_docs/doc-update-detection/databases/images/atlas-connect.png b/_docs/doc-update-detection/databases/images/atlas-connect.png new file mode 100644 index 000000000..34cc366d7 Binary files /dev/null and b/_docs/doc-update-detection/databases/images/atlas-connect.png differ diff --git a/_docs/doc-update-detection/databases/images/connection-string.png b/_docs/doc-update-detection/databases/images/connection-string.png new file mode 100644 index 000000000..ff8b72ec6 Binary files /dev/null and b/_docs/doc-update-detection/databases/images/connection-string.png differ diff --git a/_docs/doc-update-detection/databases/images/snowflake-copy-account-url.png b/_docs/doc-update-detection/databases/images/snowflake-copy-account-url.png new file mode 100644 index 000000000..f77a9bdc4 Binary files /dev/null and b/_docs/doc-update-detection/databases/images/snowflake-copy-account-url.png differ diff --git a/_docs/doc-update-detection/databases/images/upload-icon.png b/_docs/doc-update-detection/databases/images/upload-icon.png new file mode 100644 index 000000000..671f9367a Binary files /dev/null and b/_docs/doc-update-detection/databases/images/upload-icon.png differ diff --git a/_docs/doc-update-detection/databases/images/upload-to-collection.png b/_docs/doc-update-detection/databases/images/upload-to-collection.png new file mode 100644 index 000000000..b09e7882b Binary files /dev/null and b/_docs/doc-update-detection/databases/images/upload-to-collection.png differ diff --git a/_docs/doc-update-detection/databases/ssh-tunnel.md b/_docs/doc-update-detection/databases/ssh-tunnel.md new file mode 100644 index 000000000..186b9a6cc --- /dev/null +++ b/_docs/doc-update-detection/databases/ssh-tunnel.md @@ -0,0 +1,94 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'SSH tunneling' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/ssh-tunnel.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/ssh-tunnel-for-database-connections +--- + +# SSH tunneling + +Metabase can connect to some databases by first establishing a connection to a server in between Metabase and a data warehouse, then connecting to the data warehouse using that connection as a bridge. This makes connecting to some data warehouses possible in situations that would otherwise prevent the use of Metabase. + +## When to use SSH tunneling + +In general, there are two basic use cases for an SSH tunnel: + +- When a direct connection is impossible. +- When a direct connection is forbidden due to a security policy. + +Sometimes when a data warehouse is inside an enterprise environment, direct connections are blocked by security devices such as firewalls and intrusion prevention systems. Bastion hosts offer the option to first connect to a computer on the edge of the protected network, then, from that bastion host computer, establish a second connection to the data warehouse within the internal network, essentially patching these two connections together. Using the SSH tunneling feature, Metabase can automate this process. + +> [Metabase Cloud](/cloud/) does not currently support VPN connections to databases. To connect to databases in private networks, you can instead use SSH tunneling. + +## How to use SSH tunneling + +When connecting though a bastion host: + +- Answer yes to the "Use an SSH-tunnel for database connections" parameter. +- Enter the hostname for the data warehouse as it is seen from inside the network in the `Host` parameter. +- Enter the data warehouse port as seen from inside the network into the `Port` parameter. +- Enter the external name of the bastion host as seen from the outside of the network (or wherever you are) into the `SSH tunnel host` parameter. +- Enter the SSH port as seen from outside the network into the `SSH tunnel port` parameter. This is usually 22, regardless of which data warehouse you are connecting to. + +For authentication, you have two options: + +- **Using a username and password:** + + - In the `SSH tunnel username` and `SSH tunnel password` fields, enter the username and password you use to log in to the bastion host. + +- **Using SSH key (PKI authentication):** + + - Select SSH Key for the `SSH authentication` option. + - Paste the contents of your SSH private key into the `SSH private key` field. + - If your key has a passphrase, enter it into the `Passphrase for the SSH private key` field. + +If you're unable to connect test your SSH credentials by connecting to the SSH server/Bastion Host using ssh directly: + +``` +ssh @ -p +``` + +Another common case where direct connections are impossible is when connecting to a data warehouse that is only accessible locally and does not allow remote connections. In this case you will be opening an SSH connection to the data warehouse, then from there connecting back to the same computer. + +- Answer yes to the "Use an SSH-tunnel for database connections" parameter. +- Enter `localhost` in the `Host` parameter. This is the name the server. +- Enter the same value in the `Port` parameter that you would use if you where sitting directly at the data warehouse host system. +- Enter the external name of the data warehouse, as seen from the outside of the network (or wherever you are) into the `SSH tunnel host` parameter. +- Enter the SSH port as seen from outside the network into the `SSH tunnel port` parameter. This is usually 22, regardless of which data warehouse you are connecting to. +- Choose your authentication method as described above (username and password or SSH key). + +If you have problems connecting, verify the SSH host port and password by connecting manually using ssh or PuTTY on older windows systems. + +## Disadvantages of indirect connections + +While using an SSH tunnel makes it possible to use a data warehouse that is otherwise inaccessible, it's almost always preferable to use a direct connection when possible. + +There are several inherent limitations to connecting through a tunnel: + +- If the enclosing SSH connection is closed because you put your computer to sleep or change networks, all established connections will be closed as well. This can cause delays resuming connections after suspending your laptop. +- It's almost always slower. The connection has to go through an additional computer. +- Opening new SSH connections takes longer. +- Multiple operations over the same SSH tunnel can block each other. This can increase latency. +- The number of connections through a bastion host is often limited by organizational policy. +- Some organizations have IT security policies forbidding using SSH tunnels to bypass security perimeters. + +## Running SSH directly + +The SSH tunneling feature in Metabase exists as a convenient wrapper around SSH, and automates the common cases of connecting through a tunnel. It also makes connections possible with systems that don't give shell access. Metabase uses a built-in SSH client that doesn't depend on the installed system's SSH client. This allows connections from systems where you can't run SSH manually. It also means that Metabase can't take advantage of authentication services provided by the system, such as Windows Domain Authentication or Kerberos Authentication. + +If you need to connect using a method not enabled by Metabase, you can often accomplish this by running SSH directly: + +``` +ssh -Nf -L input-port:internal-server-name:port-on-server username@bastion-host.domain.com +``` + +This allows you to use the full array of features included in SSH. If you find yourself doing this often, please let us know so we can see about making your process more convenient through Metabase. + +## Further reading + +- [Adding and managing databases](./connecting). diff --git a/_docs/doc-update-detection/databases/ssl-certificates.md b/_docs/doc-update-detection/databases/ssl-certificates.md new file mode 100644 index 000000000..0ddd294af --- /dev/null +++ b/_docs/doc-update-detection/databases/ssl-certificates.md @@ -0,0 +1,102 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'SSL certificate' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/ssl-certificates.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/secure-database-connections-with-ssl-certificates +--- + +# SSL certificate + +If you'd like to connect your Metabase Cloud or self-hosted instance to a database, you can secure the connection using Secure Socket Layer (SSL) encryption with a certificate. + +Why you'd want to do this: + +- You're using Metabase Cloud and want to ensure the identity of the data warehouse you're connecting to (e.g., PostgreSQL, MySQL). +- You're self-hosting Metabase and want to ensure the identity of a data warehouse hosted by an external provider. You can also use this method to ensure you're using the strictest connection parameters when connecting to your application database. + +If you're using Metabase Cloud, the application database is handled for you, so you'd only need to secure connections to data warehouses that you add to your Metabase. + +## Prerequisites + +A database that allows a JDBC connection, as you'll need to use a connection string to specify the certificate you want to use. + +## Step 1: Download the root certificate from your provider + +If you're running Metabase via a Docker container, you should already have the certificates for AWS and Azure. + +You'll find the certificates in the `/app/certs/` directory in Metabase's Docker image: + +- AWS RDS: `/app/certs/rds-combined-ca-bundle.pem` +- Azure certificate: `/app/certs/DigiCertGlobalRootG2.crt.pem` + +If you need a different certificate, you can build your own Docker image. Visit your external provider's page for your database and find a link to download the root certificate for connecting to your database. + +## Step 2: Save the certificate + +**Self-hosted** + +Save the downloaded certificate in the same directory where you keep your metabase.jar file. Technically you can store the certificate wherever, but keeping it in the same directory as your metabase.jar file is a best practice. You'll specify the certificate's path in your connection string. + +**Metabase Cloud** + +You'll need to complete [Step 3: Add your database](#step-3-add-your-database) first. + +Once you've done that, you can go to **Admin** > **Databases** and select your database. Find the section named **SSL Client Certificate** and click **Select a file** to upload your downloaded certificate. + +## Step 3: Add your database + +For example, let's say you want to secure a connection to a PostgreSQL database. Follow the instructions in the app to add the database. For more on setting up a database connection, check out our docs for [adding a database](./connecting). + +## Step 4: Toggle on the "Use a secure connection (SSL)" option + +If your database supports a JDBC connection, Metabase will provide you with a field to input additional parameters to your connection string. Metabase will use parameters in the connection string to establish a secure connection. + +## Step 5: Add additional connection string options + +You'll need to specify the location of the certificate on the server that's running Metabase. + +For example, when connecting to a PostgreSQL database, you'll need to add two parameters: + +- `sslmode`. You can see the full list of options in [PostgreSQL's documentation](https://jdbc.postgresql.org/documentation/ssl/#configuring-the-client). We recommend you use `verify-full`; it's the most secure, and overhead is minimal. +- `sslrootcert`. Here you'll specify the file path for the certificate. + +You'll add an ampersand (`&`) to separate each parameter. For example, In the **Add additional connection string options** field, you'd add something like: + +``` +sslmode=verify-full&sslrootcert=/path/to/certificate.pem +``` + +Replace `/path/to/certifcate.pem` with the full path for the certificate you downloaded from your provider. + +You can learn more about [SSL support for PostgreSQL](https://www.postgresql.org/docs/current/libpq-ssl.html). + +## Securing connection to application database using environment variables + +If you're self-hosting Metabase, you can secure the connection to your application database using [environment variables](../configuring-metabase/environment-variables). + +The environment variable to use is [`MB_DB_CONNECTION_URI`](../configuring-metabase/environment-variables#mb_db_connection_uri). + +You'll need to include the full connection string here, including the db host, port, db name and user info, as well as the additional connection parameters to include the certificate. For example, + +``` +jdbc:postgresql://db.example.com:port/mydb?user=dbuser&password=dbpassword&ssl=true&sslmode=verify-full&sslrootcert=/path/to/certificate.pem +``` + +Both can be provided to support mutual authentication scenarios. + +## Truststores and keystores + +With some databases, like PostgreSQL and Oracle, you can secure connections using truststores and keystores. + +### Truststores + +If a truststore is provided to verify credentials, the client (your Metabase) can authenticate the server (the database) and ensure its identity is what's expected. + +### Keystores + +If a keystore is used to provide credentials, then the server (the database server) can request the client (your Metabase) authenticate itself using that keystore. Keystores are used less frequently, and in some cases it's impossible to use a keystore (Amazon's RDS forbids keystores, for example). But you may want to use a keystore if you're hosting on prem. diff --git a/_docs/doc-update-detection/databases/start.md b/_docs/doc-update-detection/databases/start.md new file mode 100644 index 000000000..ef2bfd20f --- /dev/null +++ b/_docs/doc-update-detection/databases/start.md @@ -0,0 +1,39 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: Databases +title: 'Databases overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/start.md' +--- + +# Databases overview + +## [Adding and managing databases](./connecting) + +Connect to and manage your databases. + +## [Database users, roles, and privileges](./users-roles-privileges) + +Bundling your privileges into roles based on use cases makes it easier to manage privileges in the future. + +## [Syncing and scanning databases](./sync-scan) + +Metabase runs different types of queries to stay up to date with your database. + +## [Encrypting your database connection](./encrypting-details-at-rest) + +Learn how to encrypt your database connection credentials at rest. + +## [SSH tunneling](./ssh-tunnel) + +Metabase can connect to some databases by first establishing a connection to a server in between Metabase and a data warehouse, then connecting to the data warehouse using that connection as a bridge. + +## [SSL certificate](./ssl-certificates) + +You can connect your Metabase Cloud or self-hosted instance to a database using Secure Socket Layer (SSL) encryption with a certificate. + +## [Uploading data](./uploads) + +You can set Metabase up so you can upload CSV files to a database. diff --git a/_docs/doc-update-detection/databases/sync-scan.md b/_docs/doc-update-detection/databases/sync-scan.md new file mode 100644 index 000000000..547486aa4 --- /dev/null +++ b/_docs/doc-update-detection/databases/sync-scan.md @@ -0,0 +1,173 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'Syncing and scanning databases' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/sync-scan.md' +--- + +# Syncing and scanning databases + +Metabase periodically runs different types of queries to stay up to date with your database's metadata. Knowing stuff about your data helps Metabase do things like display the right chart for the results automatically, and populate dropdown menus in filter widgets. + +There are a couple of things Metabase does: + +- [Syncs](#how-database-syncs-work) get updated schemas to display in the [Data Browser](/learn/metabase-basics/querying-and-dashboards/data-browser). +- [Scans](#how-database-scans-work) take samples of column values to populate filter dropdown menus and suggest helpful visualizations. Metabase doesn't store _complete_ tables from your database. +- [Fingerprinting](#how-database-fingerprinting-works) takes an additional sample of column values to help with smart behavior, such as auto-binning for bar charts. + +## Initial sync, scan, and fingerprinting + +When Metabase first connects to your database, Metabase performs a [sync](#how-database-syncs-work) to determine the metadata of the columns in your tables and automatically assign each column a [semantic type](../data-modeling/field-types). + +You can follow the progress of these queries from **Admin** > **Troubleshooting** > **Logs**. + +Once the queries are done running, you can view and edit the synced metadata from **Admin settings** > **Table Metadata**. For more info, see [editing metadata](../data-modeling/metadata-editing). + +### Choose when syncs and scans happen + +By default, Metabase does a lightweight hourly sync and an intensive daily scan of field values. If you have a large database, you might want to choose when syncs and scans happen: + +### Database syncing + +If you've selected **Choose when syncs and scans happen** > **ON**, you'll be able to set: + +- The frequency of the [sync](#how-database-syncs-work): hourly (default) or daily. +- The time to run the sync, in the timezone of the server where your Metabase app is running. + +### Scanning for filter values + +Metabase can scan and cache the values present in a field so it can display things like checkbox filters in dashboards and questions. Metabase will only scan fields that people are actually using in your Metabase. So if people are using a filter widget on a dashboard, Metabase will scan and cache values from that field to include in dropdown menus. If people stop using the filter widget for a couple of weeks, Metabase will stop scanning and caching those values. + +If you've selected **Choose when syncs and scans happen** > **ON**, you'll see the following options under **Scanning for filter values**: + +- **Regularly, on a schedule** allows you to run [scan queries](#how-database-scans-work) at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often. +- **Only when adding a new filter widget** is a great option if you want scan queries to run on demand. Turning this option **ON** means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question. +- **Never, I'll do this manually if I need to** is an option for databases that are either prohibitively large, or which never really have new values added. Use the [Re-scan field values](#manually-scanning-column-values) button to run a manual scan and bring your filter values up to date. + +## Manually syncing tables and columns + +1. Go to **Admin settings** > **Databases** > your database. +2. Click **Sync database schema**. + +## Manually scanning column values + +To scan values from all the columns in a table: + +1. Go to **Admin settings** > **Table Metadata** > your database. +2. Select the table that you want to bring up to date with your database. +3. Click the **gear icon** at the top of the page. +4. Click **Re-scan this table**. + +To scan values from a specific column: + +1. Go to **Admin settings** > **Table Metadata** > your database. +2. Select the table. +3. Find the column you want bring up to date with your database. +4. Click the **gear icon** in the panel for that column. +5. Click **Re-scan this field**. + +## Clearing cached values for a table or field + +To clear the [scanned field values for a table](#syncing-and-scanning-databases): + +1. Go to **Admin settings** > **Table Metadata**. +2. Select the database and table. +3. Click the **gear icon** in the upper right. +4. Click **Discard cached field values**. + +You can also tell Metabase to forget the cached values for individual fields by clicking the **gear** icon on a field and clicking on **Discard cached field values**. + +## Disabling syncing and scanning for specific tables + +To prevent Metabase from running syncs and scans against a specific table, change the [table visibility](../data-modeling/metadata-editing#table-visibility) to **Hidden**: + +1. Go to **Admin settings** > **Table Metadata** > your database. +2. Hover over the table name in the sidebar. +3. Click the **eye** icon. + +> Hiding a table will also prevent it from showing up in the [query builder](../questions/query-builder/editor) and [data reference](../exploration-and-organization/data-model-reference). People can still query hidden tables from the [SQL editor](../questions/native-editor/writing-sql). + +## Syncing and scanning using the API + +Metabase syncs and scans regularly, but if the database administrator has just changed the database schema, or if a lot of data is added automatically at specific times, you may want to write a script that uses the [Metabase API](/learn/metabase-basics/administration/administration-and-operation/metabase-api) to force a sync or scan. [Our API](../api) provides two ways to initiate a sync or scan of a database: + +1. Using a session token: the `/api/database/:id/sync_schema` or `api/database/:id/rescan_values` endpoints. These endpoints do the same things as going to the database in the Admin Panel and choosing **Sync database schema** or **Re-scan field values** respectively. To use these endpoints, you have to authenticate with a user ID and pass a session token in the header of your request. +2. Using an API key: `/api/notify/db/:id`. We created this endpoint so that people could notify their Metabase to sync after an [ETL operation](/learn/grow-your-data-skills/data-landscape/etl-landscape) finishes. To use this endpoint, you must pass an API key by defining the `MB_API_KEY` environment variable. + +## How database syncs work + +A Metabase **sync** is a query that gets a list of updated table and view names, column names, and column data types from your database: + +```sql +SELECT + TRUE +FROM + "your_schema"."your_table_or_view" +WHERE + 1 <> 1 +LIMIT 0 +``` + +This query runs against your database during setup, and again every hour by default. This scanning query is fast with most relational databases, but can be slower with MongoDB and some [community-built database drivers](../developers-guide/community-drivers). Syncing can't be turned off completely, otherwise Metabase wouldn't work. + +## How database scans work + +A Metabase **scan** is a query that caches the column _values_ for filter dropdowns by looking at the first 1,000 distinct records from each table, in ascending order: + +```sql +SELECT + "your_table_or_view"."column" AS "column" +FROM + "your_schema"."your_table_or_view" +GROUP BY + "your_table_or_view"."column" +ORDER BY + "your_table_or_view"."column" ASC +LIMIT 1000 +``` + +For each record, Metabase only stores the first 100 kilobytes of text, so if you have data with 1,000 characters each (like addresses), and your column has more than 100 unique addresses, Metabase will only cache the first 100 values from the scan query. + +Cached column values are displayed in filter dropdown menus. If people type in the filter search box for values that aren't in the first 1,000 distinct records or 100kB of text, Metabase will run a query against your database to look for those values on the fly. + +A scan is more intensive than a sync query, so it only runs once during setup, and again once a day by default. If you [disable scans](#scanning-for-filter-values) entirely, you'll need to bring things up to date by running [manual scans](#manually-scanning-column-values). + +To reduce the number of tables and fields Metabase needs to scan in order to stay current with your connected database, Metabase will only scan values for fields that someone has queried in the last fourteen days. + +## Periodically refingerprint tables + +> Periodic refingerprinting will increase the load on your database. + +By default, Metabase only runs [fingerprinting](#how-database-fingerprinting-works) queries when you first connect your database. + +Turn this setting on if you want Metabase to use larger samples of column values when making suggestions in the UI: + +1. Go to **Admin** > **Databases** > your database. +2. Click on **Edit connection details**. +2. Expand **Show advanced options**. +3. Turn on **Periodically refingerprint tables**. + +## How database fingerprinting works + +The fingerprinting query looks at the first 10,000 rows from a given table or view in your database: + +```sql +SELECT + * +FROM + "your_schema"."your_table_or_view" +LIMIT 10000 +``` + +Metabase uses the results of this query to provide better suggestions in the Metabase UI (such as filter dropdowns and auto-binning). +To avoid putting strain on your database, Metabase only runs fingerprinting queries the [first time](#initial-sync-scan-and-fingerprinting) you set up a database connection. To change this default, you can turn ON [Periodically refingerprint tables](#periodically-refingerprint-tables). + +## Further reading + +Metabase doesn't do any caching or rate limiting during the sync and scan process. If your data appears to be missing or out of date, check out: + +- [Can't see tables](../troubleshooting-guide/cant-see-tables). +- [Data in Metabase doesn't match my database](../troubleshooting-guide/sync-fingerprint-scan). diff --git a/_docs/doc-update-detection/databases/uploads.md b/_docs/doc-update-detection/databases/uploads.md new file mode 100644 index 000000000..f2d82ddfd --- /dev/null +++ b/_docs/doc-update-detection/databases/uploads.md @@ -0,0 +1,169 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'Setting up data uploads' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/uploads.md' +--- + +# Setting up data uploads + +This page covers how admins can set up data uploads so people can upload CSVs to your Metabase. For _how_ to upload data once this is set up, check out [Uploading data](../exploration-and-organization/uploads). + +![Upload CSV data to a collection in Metabase](./images/upload-to-collection.png) + +Uploading CSV data is best suited for ad hoc analysis of spreadsheet data. If you have a lot of data, or will need to update or add to that data regularly, we recommend setting up a way to load that data into a database directly, then connecting Metabase to that database. + +## Managing upload settings + +To manage upload settings, admins can hit cmd/ctrl + K and search for "Settings - Uploads", or click on the **gear** icon in the upper right and click through **Admin settings** > **Settings** > **Uploads**. + +## Databases that support uploads + +- [PostgreSQL](../databases/connections/postgresql) +- [MySQL](../databases/connections/mysql) +- [Redshift](../databases/connections/redshift) +- [ClickHouse](../databases/connections/clickhouse) + +## Setting up uploads + +There are a few things admins need to do to support CSV uploads: + +- [Connect to a database using a database user account with write access](#connect-to-a-database-using-a-database-user-account-with-write-access). This way Metabase will be able to store the uploaded data somewhere. +- [Select the database and schema you want to store the uploaded data in](#select-the-database-and-schema-that-you-want-to-store-the-data-in). +- [(Optional) Specify a prefix for Metabase to prepend to the uploaded tables](#specify-a-prefix-for-metabase-to-prepend-to-the-uploaded-tables). +- [Add people to a group with view data and create query access to the upload schema database](#add-people-to-a-group-with-data-access-to-the-upload-schema). + +## Connect to a database using a database user account with write access + +To upload data to Metabase, an admin will need to connect your Metabase to a database that supports uploads using a database user account that has write access to that database. + +You can also upload data to the Sample Database included with Metabase (an H2 database), though we don't recommend using the Sample Database for any data that you want to keep around. + +For more, check out: + +- [Adding and managing databases](./connecting) +- [Database users, roles, and privileges](./users-roles-privileges#privileges-to-enable-uploads) + +## Select the database and schema that you want to store the data in + +If Metabase is connected to a database using a database user account with write access, Admins can enable uploads by: + +- Clicking on the **gear** icon in the upper right on the home page and navigating to **Admin settings** > **Settings** > **Uploads**. +- Selecting the database Metabase should use to store the data. + +When people upload a CSV to a collection, Metabase will: + +- Create a table to store that data in the database and schema that the Admin selected to store uploads. +- Create a [model](../data-modeling/models) that wraps the uploaded table, and save that model to the collection the person uploaded the CSV data to. + +## Specify a prefix for Metabase to prepend to the uploaded tables + +Admins can optionally specify a string of text to add in front of the table that Metabase creates to store the uploaded data. + +## Add people to a group with data access to the upload schema + +In order to upload CSVs, a person must be in a group with **View data** access of "Can view" and **Create queries** of Query builder access or higher to the schema you've selected to store your uploaded data. See [groups](../people-and-groups/managing) and [data permissions](../permissions/data). + +## Primary key auto-generation + +When you upload a CSV, Metabase will create an a unique primary key column, called `_mb_row_id`, as the first (left-most) column of the uploaded CSV table. This `_mb_row_id` column will contain automatically generated integers. Metabase will also ignore any columns in the upload that have a name that will be in the database with the same name as the auto-generated primary key column (e.g., `_MB row-ID` in the CSV will be `_mb_row_id` or `_MB_ROW_ID` in the database). + +If you don't want this autogenerated ID column, you can always remove the column from the model Metabase created. Visit the model, click on the info **i** icon, then **Model details**. From the model details page, click the **Edit definition** button. In the Data section of the query builder, click on the down arrow next to the table, deselect the added ID column, and save your changes. + +## Data type errors + +Metabase will try to guess what the data type is for each column, but if some entries are not like the others, Metabase may not guess the type correctly. For example, if you have a column that starts with integers like 100, 130, 140, then later on a float 105.5, Metabase may reject the upload. To fix this, you'll need to use spreadsheet software to adjust the formatting so that all the integers are formatted as floats (e.g., 100.00, 130.00, 140.00 and so on) before uploading. + +## File size limit + +CSV files cannot exceed 50 MB in size. + +> While Metabase limits uploads to 50 MB, the server you use to run your Metabase may impose a lower limit. For example, the default client upload limit for [NGINX is 1 MB](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). So you may need to change your server settings to allow uploads up to 50 MB. People on Metabase Cloud don't have to worry about this. + +If you have a file larger than 50 MB, the workaround here is to split the data into multiple files and [append those files to an existing model](../exploration-and-organization/uploads#appending-to-a-model-created-by-an-upload). Each file that you upload to Metabase must have a header row (the names of the columns), so if you're splitting one file into multiple files, you'll need to add header rows to each file. + +## Date formats + +For now, Metabase only recognizes dates and datetimes from strings in uploaded CSVs with the following formats: + +### Dates + +Represents the year, month, and day without time information. + +**Format**: `yyyy-MM-dd` + +**Example**: `2023-01-01` + +### Datetimes + +Represents the year, month, day, hour. Minutes, seconds, and fractional seconds are optional. + +**Format**: `yyyy-MM-ddTHH:mm:ss.SSS`. The "T" separator could also be a space (" "). + +**Examples**: + +- `2023-01-01 00` +- `2023-01-01 00:00:00.000` +- `2023-01-01T00:00:00.000` +- `2023-01-01 00:00:00.0000000` + +### Datetimes with offsets + +Represents the datetime with an offset from Coordinated Universal Time (UTC). Minutes and seconds in the offset are optional. + +**Formats**: + +Datetime formats: + +- `yyyy-MM-ddTHH:mm`. +- `yyyy-MM-ddTHH:mm:ss`. +- `yyyy-MM-ddTHH:mm:ss.SSS` (and any number of S's). + +The "T" separator could also be a space (" "). + +Offsets: + +- `Z` (for UTC) +- `+HH` or `-HH` +- `+HH:mm` or `-HH:mm` +- `+HH:mm:ss` or `-HH:mm:ss` + +**Examples**: + +- `2023-01-01 00:00:00+00:00:00` +- `2023-01-01T00:00:00+00:00:00` + +## Deleting models and tables created by uploads + +### Deleting models created by uploads + +{% include plans-blockquote.html feature="Deleting uploaded tables" %} + +You can move a model to Trash by clicking on the three dots in the upper right and selecting **Move to Trash**. + +For deleting models completely, see [Deleting items permanently](../exploration-and-organization/delete-and-restore). + +### Deleting tables created by uploads + +{% include plans-blockquote.html feature="Deleting uploaded tables" %} + +To delete tables created by uploads, go to **Admin settings** > **Settings** > **Uploads**. + +Under **Manage uploads**, Metabase will list the tables underlying the models. + +When you delete the table, Metabase will give you the option to **Also send all models and questions based on this table to the trash**. + +## Note on uploading data to a MySQL database + +For speeding up uploads to a MySQL database, we recommend that you set a `local_infile` to `ON`. You'll need to set this `local_infile` in MySQL, not Metabase. The command-line format is `--local-infile=ON`. + +If `local_infile` is disabled (set to `OFF`), Metabase will automatically fall back to uploading CSVs in a much slower way. + +For more context, check out: + +- [Non-LOCAL Versus LOCAL Operation](https://dev.mysql.com/doc/refman/8.0/en/load-data.html#load-data-local) +- [Reference docs for the local_infile variable](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_local_infile) +- [Security Considerations for LOAD LOCAL DATA](https://dev.mysql.com/doc/refman/8.0/en/load-data-local-security.html) diff --git a/_docs/doc-update-detection/databases/users-roles-privileges.md b/_docs/doc-update-detection/databases/users-roles-privileges.md new file mode 100644 index 000000000..f2e31c2a4 --- /dev/null +++ b/_docs/doc-update-detection/databases/users-roles-privileges.md @@ -0,0 +1,218 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Databases +title: 'Database users, roles, and privileges' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/databases/users-roles-privileges.md' +--- + +# Database users, roles, and privileges + +We recommend creating a `metabase` database user with the following database roles: + +- [`analytics` for read access](#minimum-database-privileges) to any schemas or tables used for analysis. +- Optional [`metabase_actions` for write access](#privileges-to-enable-actions) to tables used for Metabase actions. +- Optional [`metabase_model_persistence` for write access](#privileges-to-enable-model-persistence) to the schema used for Metabase model persistence. + +Bundling your privileges into roles based on use cases makes it easier to manage privileges in the future (especially in [multi-tenant situations](#multi-tenant-permissions)). For example, you could: + +- Use the same `analytics` role for other BI tools in your [data stack](/learn/grow-your-data-skills/data-fundamentals/data-landscape) that need read-only access to the analytics tables in your database. +- Revoke the write access for `metabase_model_persistence` without affecting the write access for `metabase_actions`. + +## Minimum database privileges + +In order to view and query your tables in Metabase, you'll have to give Metabase's database user: + +- `CONNECT` to your database. +- `SELECT` privileges to any schemas or tables that you want to use in Metabase. + +To organize these privileges (and make maintenance easier down the line): + +- Create a database role called `analytics`. +- Create a database user called `metabase`. +- Add `metabase` to the `analytics` role. +- Add privileges to the `analytics` role. + +For example, if you're using a Postgres database, you'd log in as an admin and run the SQL statements: + +```sql +-- Create a role named "analytics". +CREATE ROLE analytics WITH LOGIN; + +-- Add the CONNECT privilege to the role. +GRANT CONNECT ON DATABASE "your_database" TO analytics; + +-- Create a database user named "metabase". +CREATE USER metabase WITH PASSWORD "your_password"; + +-- Give the role to the metabase user. +GRANT analytics TO metabase; + +-- Add query privileges to the role (options 1-4): + +-- Option 1: Uncomment the line below to let users with the analytics role query ALL DATA (In Postgres 14 or higher. See [Predefined Roles](https://www.postgresql.org/docs/current/predefined-roles.html#PREDEFINED-ROLES)). +-- GRANT pg_read_all_data TO analytics; + +-- Option 2: Uncomment the line below to let users with the analytics role query anything in the DATABASE. +-- GRANT USAGE ON DATABASE "your_schema" TO analytics; +-- GRANT SELECT ON DATABASE "your_schema" TO analytics; + +-- Option 3: Uncomment the line below to let users with the analytics role query anything in a specific SCHEMA. +-- GRANT USAGE ON SCHEMA "your_schema" TO analytics; +-- GRANT SELECT ON ALL TABLES IN SCHEMA "your_schema" TO analytics; + +-- Option 4: Uncomment the line below to let users with the analytics role query anything in a specific TABLE. +-- GRANT USAGE ON SCHEMA "your_schema" TO analytics; +-- GRANT SELECT ON "your_table" IN SCHEMA "your_schema" TO analytics; +``` + +Depending on how you use Metabase, you can also additonally grant: + +- `TEMPORARY` privileges to create temp tables. +- `EXECUTE` privileges to use stored procedures or user-defined functions. + +Remember that when you grant privileges to a role, all users with that role will get those privileges. + +## Grant all database privileges + +If you don't want to structure your database privileges yet: + +- Create a `metabase` database user. +- Give `metabase` all privileges to the database. + +```sql +-- Create a database user named "metabase". +CREATE USER metabase WITH PASSWORD "your_password"; + +-- Give the user read and write privileges to anything in the database. +GRANT ALL PRIVILEGES ON "database" TO metabase; +``` + +This is a good option if you're connecting to a local database for development or testing. + +## Privileges to enable actions + +[Actions](../actions/introduction) let Metabase write back to specific tables in your database. + +In addition to the [minimum database privileges](#minimum-database-privileges), you'll need to grant write access to any tables used with actions: + +- Create a new role called `metabase_actions`. +- Give the role `INSERT`, `UPDATE`, and `DELETE` privileges to any tables used with Metabase actions. +- Give the `metabase_actions` role to the `metabase` user. + +```sql +-- Create a role to bundle database privileges for Metabase actions. +CREATE ROLE metabase_actions WITH LOGIN; + +-- Grant write privileges to the TABLE used with Metabase actions. +GRANT INSERT, UPDATE, DELETE ON "your_table" IN SCHEMA "your_schema" TO metabase_actions; + +-- Grant role to the metabase user. +GRANT metabase_actions TO metabase; +``` + +## Privileges to enable model persistence + +[Model persistence](../data-modeling/model-persistence) lets Metabase save query results to a specific schema in your database. Metabase's database user will need the `CREATE` privilege to set up the dedicated schema for model caching, as well as write access (`INSERT`, `UPDATE`, `DELETE`) to that schema. + +In addition to the [minimum database privileges](#minimum-database-privileges): + +- Create a new role called `metabase_model_persistence`. +- Give the role `CREATE` access to the database. +- Give the role `INSERT`, `UPDATE`, and `DELETE` privileges to the schema used for model persistence. +- Give the `metabase_model_persistence` role to the `metabase` user. + +```sql +-- Create a role to bundle database privileges for Metabase model persistence. +CREATE ROLE metabase_model_persistence WITH LOGIN; + +-- If you don't want to give CREATE access to your database, +-- add the schema manually before enabling modeling persistence. +GRANT CREATE ON "database" TO metabase_model_persistence; + +-- Grant write privileges to the SCHEMA used for model persistence. +GRANT USAGE ON "your_schema" TO metabase_model_persistence; +GRANT INSERT, UPDATE, DELETE ON "your_model's_table" IN SCHEMA "your_schema" TO metabase_model_persistence; + +-- Grant role to the metabase user. +GRANT metabase_model_persistence TO metabase; +``` + +## Privileges to enable uploads + +You can [upload CSVs](../databases/uploads) to supported databases. Metabase's database user should have write access (`INSERT`, `UPDATE`, `DELETE`) to the schema where you want to store the uploads. + +You'll first need to create a schema to store uploads (or use an existing schema) and tell Metabase that you want to [use that schema to store uploads](./uploads#select-the-database-and-schema-that-you-want-to-store-the-data-in). + +In addition to the [minimum database privileges](#minimum-database-privileges): + +- Create a new role called `metabase_uploads`. +- Give the role `INSERT`, `UPDATE`, and `DELETE` privileges to the schema where you want to store uploads. +- Give the `metabase_uploads` role to the `metabase` user. + +```sql +-- Create a role to bundle database privileges for uploads. +CREATE ROLE metabase_uploads WITH LOGIN; + +-- Grant write privileges to the SCHEMA used for uploads. +GRANT USAGE ON "your_schema" TO metabase_uploads; +GRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA "your_schema" TO metabase_uploads; + +-- Grant role to the metabase user. +GRANT metabase_uploads TO metabase; +``` + +## Multi-tenant permissions + +If you're setting up multi-tenant permissions for customers who need SQL access, you can [create one database connection per customer](/learn/metabase-basics/administration/permissions/multi-tenant-permissions#granting-customers-native-sql-access-to-their-schema). That means each customer will connect to the database using their own database user. + +Let's say you have customers named Tangerine and Lemon: + +- Create new database users `metabase_tangerine` and `metabase_lemon`. +- Create a `customer_facing_analytics` role with the `CONNECT` privilege. +- Create roles to bundle privileges specific to each customer's use case. For example: + - `tangerine_queries` to bundle read privileges for people to query and create stored procedures against the Tangerine schema. + - `lemon_queries` to bundle read privileges for people to query tables in the Lemon schema. + - `lemon_actions` to bundle the write privileges needed to create [actions](#privileges-to-enable-actions) on a Lemonade table in the Lemon schema. +- Add each user to their respective roles. + +```sql +-- Create one database user per customer. +CREATE USER metabase_tangerine WITH PASSWORD "orange"; +CREATE USER metabase_lemon WITH PASSWORD "yellow"; + +-- Create a role to bundle privileges for all customers. +CREATE ROLE customer_facing_analytics; +GRANT CONNECT ON DATABASE "citrus" TO customer_facing_analytics; +GRANT customer_facing_analytics TO metabase_tangerine, metabase_lemon; + +-- Create a role to bundle analytics read access for customer Tangerine. +CREATE ROLE tangerine_queries; +GRANT USAGE ON SCHEMA "tangerine" TO tangerine_queries; +GRANT SELECT, EXECUTE ON ALL TABLES IN SCHEMA "tangerine" TO tangerine_queries; +GRANT tangerine_queries TO metabase_tangerine; + +-- Create a role to bundle analytics read access for customer Lemon. +CREATE ROLE lemon_queries; +GRANT USAGE ON SCHEMA "lemon" TO lemon_queries; +GRANT SELECT ON ALL TABLES IN SCHEMA "lemon" TO lemon_queries; +GRANT lemon_queries TO metabase_lemon; + +-- Create a role to bundle privileges to Metabase actions for customer Lemon. +CREATE ROLE lemon_actions; +GRANT INSERT, UPDATE, DELETE ON TABLE "lemonade" IN SCHEMA "lemon" TO lemon_actions; +GRANT lemon_actions TO metabase_lemon; +``` + +We recommend bundling privileges into roles based on use cases per customer. That way, you can reuse common privileges across customers while still being able to grant or revoke granular privileges per customer. For example: + +- If customer Tangerine needs to query the Tangerine schema from another analytics tool, you can use the `tangerine_queries` role when setting up that tool. +- If customer Lemon decides that they don't want to use Metabase actions anymore (but they still want to ask questions), you can simply revoke or drop the `lemon_actions` role. + +## Further reading + +- [Permissions strategies](/learn/metabase-basics/administration/permissions/strategy) +- [Permissions introduction](../permissions/introduction) +- [People overview](../people-and-groups/start) diff --git a/_docs/doc-update-detection/developers-guide/api-changelog.md b/_docs/doc-update-detection/developers-guide/api-changelog.md new file mode 100644 index 000000000..847a74f3c --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/api-changelog.md @@ -0,0 +1,121 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'API changelog' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/api-changelog.md' +--- + +# Breaking changes to the API interface + +## Metabase 0.54.0 + +- The alert system has been migrated from the legacy pulse infrastructure to the new notification system. This migration includes the following changes: + + - The majority of `/api/alert` endpoints have been removed in favor of the new `/api/notification` endpoints. For backward compatibility, these endpoints will remain available until the next release: + - `GET /api/alert` + - `GET /api/alert/:id` + - `DELETE /api/alert/:id/subscription` + + - Developers should migrate to using the `/api/notification` endpoints. For reference: + - An overview of the new notification system can be found at `src/metabase/notification/README.md` + - Notification API documentation at `{{YOUR_URL}}/api/docs/#tag/apinotification` + - Interactive API documentation available at `/api/docs` endpoint + +## Metabase 0.53.0 + +- `POST /api/card/:card-id/query/:export-format` + + Previously, request parameters (parameters, pivot-results?, and format-rows?) could be sent via query parameters or + as application/x-www-form-urlencoded form content. In Metabase 0.53.0, parameters must be sent as either: + + - application/x-www-form-urlencoded form content + - JSON-encoded in the request body + + Sending parameters as query parameters in the URL is no longer supported. + +## Metabase 0.52.0 + +- `POST /api/user/:id/send_invite` has been removed. +- `GET /:id/fields` now includes the Table ID. + +- APIs under `/api/pulse` and `/api/alert` will be removed in a future version as we're tranitioning to a new architecture. + +## Metabase 0.51.0 + +- `GET /api/dashboard/:id/query_metadata` + + New endpoint that combines responses for `/api/field/:id`, `/api/database/:id`, and `/api/table/:id/query_metadata`. + This should drastically cut down on the required number of requests to display a card. + +- `GET /api/card/:id/query_metadata` + + New endpoint that combines responses for `/api/field/:id`, `/api/database/:id`, and `/api/table/:id/query_metadata`. + This should drastically cut down on the required number of requests to display a dashboard. + +- `/api/legacy-metric` + + The `/api/legacy-metric` endpoints have been removed. + +- `POST /api/session/pulse/unsubscribe` and `POST /api/session/pulse/unsubscribe/undo` have been moved to `POST /api/pulse/unsubscribe` and `POST /api/pulse/unsubscribe/undo` respectively. + +## Metabase 0.50.0 + +- `GET /api/collection/tree` and `GET /api/collection/:id/items` + These API endpoints will always return official collections first, before other items in the collection. + +- `PUT /api/dashboard/:id`, `PUT /api/card/:id`, and `PUT /api/collection/:id` + + When setting `archived` to `true`, the Dashboard, Card, or Collection will be automatically moved to the Trash + collection, a special collection that holds all archived items. + + When setting `archived` to `false`, you may optionally also provide a `collection_id` (for Dashboards or Cards) or a + `parent_id` (for Collections). In this case, the entity will be re-parented to the specified Collection when it is + moved from the Trash. If a new `collection_id` or `parent_id` is not provided, the entity will be moved back to its + original location if possible. If this is not possible (for example, the original location is also in the Trash) an + error will occur. + +- `/api/metric` + + The `/api/metric` endpoints has been renamed to `/api/legacy-metric` to reflect that fact it will not be used for the new version of metrics. The new version uses the `/api/card` endpoints. + +- `GET /api/permissions/graph` and `PUT /api/permissions/graph` + + The `data` key has been removed from the permissions graph. The `data` key has been replaced with two new keys: `view-data` and `create-queries`. + Valid permission values for `view-data` are `unrestricted`, `blocked`, `sandboxed` or `restricted`. Valid permission values + for `create-queries` are `query-builder-and-native`, `query-builder`, and `no`. + + If you're scripting permissions, you'll need to update your scripts to reflect these breaking changes to the `/api/permissions/graph` endpoints. For more about the new data permissions of View data and Create queries, see our docs on [data permissions](../permissions/data). And here's a page that [talks about the change (and why we did it)](../permissions/no-self-service-deprecation). + +- `GET /api/transform/:db-id/:schema/:transform-name`, which hasn't been used internally by Metabase for ages, has + been removed. + +- `POST /api/user/:id/send_invite` is deprecated and will be removed in the next version. + +## Metabase 0.49.5 + +NOTE: These endpoint changes were added in 0.49.3, and a bug in `GET /api/embed/card/:token/query/:export-format` was fixed in 0.49.5. + +- `POST /api/card/:card-id/query/:export-format` +- `POST /api/:dashboard-id/dashcard/:dashcard-id/card/:card-id/query/:export-format` +- `POST /api/dataset/:export-format` +- `GET /api/embed/card/:token/query/:export-format` +- `GET /api/embed/dashboard/:token/dashcard/:dashcard-id/card/:card-id/:export-format` + + The above endpoints now accept the `format_rows` query parameter. It is an optional boolean parameter that will default to `true` if not included in the request. + When `format_rows` is `true`, the export will have formatting applied such that the values match what they appear as in the app. + When `format_rows` is `false`, formatting is not applied and exports will behave as they did prior to 0.49.0. + + The value of `format_rows` has no effect when exporting xlsx files. + +## Metabase 0.49.0 + +- `POST /api/card` and `PUT /api/card/:id` + + The `dataset` key is deprecated and will be removed in a future version, most likely 50. In its place we have added a new key: `type` which is equivalent in that it distinguishes Models from Questions. `type="model"` is equivalent to `dataset=true` and `type="question"` is equivalent to `dataset=false`. + +- all endpoints that return data (e.g. exports in JSON, XLSX, CSV, endpoints that end in "/query") + + Starting from v49, we respond to the API calls with values formatted according to the instance localization options diff --git a/_docs/doc-update-detection/developers-guide/build.md b/_docs/doc-update-detection/developers-guide/build.md new file mode 100644 index 000000000..32f3705ef --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/build.md @@ -0,0 +1,178 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Building Metabase' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/build.md' +--- + +# Building Metabase + +This doc will show you how you can build and run Metabase on your own computer so you can play around with it or test features in development. You can also run development branches of Metabase [using a pre-built Docker image](dev-branch-docker). + +## Install the prerequisites + +If you're using macOS, you'll want to install Xcode Command Line Tools first, by running: + +``` +xcode-select --install +``` + +To complete any build of the Metabase code, you'll need to install the following. + +1. [Clojure (https://clojure.org)](https://clojure.org/guides/getting_started) - install the latest release by following the guide depending on your OS + +2. [Java Development Kit JDK (https://adoptopenjdk.net/releases.html)](https://adoptopenjdk.net/releases.html) - you need to install JDK 11 ([more info on Java versions](../installation-and-operation/running-the-metabase-jar-file)) + +3. [Node.js (http://nodejs.org/)](http://nodejs.org/) - latest LTS release + +4. [Yarn package manager for Node.js](https://yarnpkg.com/) - latest release of version 1.x - you can install it in any OS by running: + +``` +npm install --global yarn +``` + +On a most recent stable Ubuntu/Debian, all the tools above, with the exception of Clojure, can be installed by using: + +``` +sudo apt install openjdk-11-jdk nodejs && sudo npm install --global yarn +``` + +If you have multiple JDK versions installed in your machine, be sure to switch your JDK before building with: + +``` +sudo update-alternatives --config java +``` + +Then select Java 21 in the menu. + +### Running on M1 Apple computers + +If you are developing on newer Apple M1 computers, please note that the current NodeJS LTS has native support for arm architecture. However, make sure you have Rosetta 2 installed before you attempt to build the frontend: + +``` +/usr/sbin/softwareupdate --install-rosetta (root permission not required) +``` + +or + +``` +/usr/sbin/softwareupdate --install-rosetta --agree-to-license (root permission required) +``` + +### If you're running Windows, use WSL + +If you are developing on Windows, you should run Ubuntu on Windows Subsystem for Linux (WSL) and follow instructions for Ubuntu/Linux. + +### Developing with VS Code in a remote container + +Alternatively, without the need to explicitly install the above dependencies, follow the guide [on using Visual Studio Code](visual-studio-code) and its remote container support. + +## Clone the Metabase repo + +Once you've installed all the build tools, you'll need to clone the [Metabase repository](https://github.com/metabase/metabase) from GitHub. + +1. Create a `workspace` folder (you can name it that or whatever you want), which will store the Metabase code files. + +2. Open up your terminal app, and navigate to your workspace folder with: + +``` +cd ~/workspace +``` + +{:start="3"} 3. Run the following command to “clone” Metabase into this folder, using the URL of the Metabase repository on GitHub: + +``` +git clone https://github.com/metabase/metabase +``` + +## Choose the branch you want to run, and run it + +This is the part that you’ll use over and over. + +The “official” branch of Metabase is called `master`, and other feature development branches get merged into it when they’re approved. So if you want to try out a feature before then, you’ll need to know the name of that branch so you can switch over to it. Here’s what to do: + +{:start="4"} 4. Open up your terminal app + +5. Navigate to where you're storing the Metabase code. If you followed this guide exactly, you'd get there by entering this command: + + ``` + cd ~/workspace/metabase + ``` + +6. "Pull” down the latest code by running: + + ``` + git pull + ``` + + You should do this every time to make sure that you have all the latest Metabase branches and code on your computer. It’s also how you’ll get updates on a feature branch someone make changes to it. + +7. Find the name of the branch you want to run by going to the “pull request” page for that feature on GitHub and copying the branch name from there. Here’s [an example PR page](https://github.com/metabase/metabase/pull/19138), with the branch name + `fix-native-dataset-drill-popover`. + +8. Switch to, or “check out,” that branch by running: + + ``` + git checkout + ``` + + If we wanted to switch to the branch in the previous step, we'd run: + + ``` + git checkout fix-native-dataset-drill-popover + ``` + + When you want to switch back to `master`, run: + + ``` + git checkout master + ``` + +## Run Metabase + +{:start="9"} 9. Now we’ll start up the backend server of Metabase with: + +``` +clojure -M:run +``` + +When it’s done, you should see a message that says something like “Metabase initialization complete.” Keep this tab in your terminal app running, otherwise it’ll stop Metabase. + +10. Open up another tab or window of your terminal app, and then “build” the frontend (all the UI) with this command: + +``` +yarn build-hot +``` + +If you're having trouble with this step, make sure you are using the LTS version of [Node.js (http://nodejs.org/)](http://nodejs.org/). + +{:start="11"} 11. In your web browser of choice, navigate to `http://localhost:3000`, where you should see Metabase! + +This is the local “server” on your computer, and 3000 is the “port” that Metabase is running on. You can have multiple different apps running on different ports on your own computer. Note that if you share any URLs with others that begin with `localhost`, they won’t be able to access them because your computer by default isn’t open up to the whole world, for security. + +To switch to a different branch or back to `master`, open up another Terminal tab, and repeat steps 6, 7, and 8. If Metabase wasn’t already running, you'll need to complete steps 9 and 10 again too. If it was already running, the frontend will automatically rebuild itself. You can check its progress by switching to that tab in your Terminal — it usually takes something like 15 seconds, but will depend on your hardware. + +## Shutting down Metabase + +If you want to make Metabase stop running, you can either quit your terminal program, or go to the tab with the backend running and hit `Ctrl+C` to stop the backend. Most of the time you don’t have to do this to switch branches, but there are some cases where the change or feature you’re trying to see is a change with the backend, and you may need to stop the backend with `Ctrl+C` and then restart it by completing step 9 again. + +## Building the Metabase Uberjar + +The entire Metabase application is compiled and assembled into a single .jar file which can run on any modern JVM. There is a script which will execute all steps in the process and output the final artifact for you. You can pass the environment variable MB_EDITION before running the build script to choose the version that you want to build. If you don't provide a value, the default is `oss` which will build the Community Edition. + + ./bin/build.sh + +After running the build script simply look in `target/uberjar` for the output .jar file and you are ready to go. + +### Build a Metabase Uberjar in a containerized environment + +If you want to build Metabase without installing Clojure, Java, and Node.js on your host machine, you can build the Uberjar inside a container by running: + +``` +DOCKER_BUILDKIT=1 docker build --output container-output/ . +``` + +Make sure that your Docker Daemon is running before executing the command. After running the command, you'll find the Metabase JAR file at `./container-output/app/metabase.jar`. diff --git a/_docs/doc-update-detection/developers-guide/clojure.md b/_docs/doc-update-detection/developers-guide/clojure.md new file mode 100644 index 000000000..f82931498 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/clojure.md @@ -0,0 +1,15 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Working with Clojure' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/clojure.md' +--- + +# Working with Clojure + +Check out [Clojure for the Brave and True](https://www.braveclojure.com/clojure-for-the-brave-and-true/). It's free online. + +If you don't feel like reading a whole book, [Mark Volkmann's Clojure tutorial](https://mvolkmann.github.io/clojure/article.html) is another good starting point. diff --git a/_docs/doc-update-detection/developers-guide/code-reviews.md b/_docs/doc-update-detection/developers-guide/code-reviews.md new file mode 100644 index 000000000..6cc11f9e1 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/code-reviews.md @@ -0,0 +1,81 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Code reviews' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/code-reviews.md' +redirect_from: + - /docs/doc-update-detection/code-reviews +--- + +# Code reviews + +The overall goal of a code review is to serve as a safety net for other people on our team and help them write better code, not to judge them or their code. When in doubt, assume that they have good intentions and BE NICE. + +## Goals + +- Catch bugs +- Catch non-obvious consequences of an approach - will this PR make future code harder to secure or more buggy. +- For situations where things were coded without being discussed, a code review serves as a sanity check to make sure a correct approach is being taken +- Point out implications of the PR for parts of Metabase that a PR doesn’t touch +- Point out places where a good approach or style was used. Code reviews are not a hatefest. Unless a PR is completely horrific there should be an equal number of good and bad points brought up. + +## Mindset giving a code review + +Your primary goal as a reviewer is to serve as a safety net and keep bad code from being merged. The definition of “bad” is highly subjective, context dependent and will change with product time and maturity. + +When you find clear mistakes, take the time to note why you think they are mistakes. + +If you see places where you don’t agree with an approach, speak up. However, also take the time to understand why the author made a certain choice. You should assume that the author made a good decision based on what they knew in the moment. You probably have a different set of knowledge and see different outcomes. Dig into these. They might see things you don’t and vice versa. + +Look for tricks, techniques, or idioms you can steal. Your teammates are smart folks. Chances are they have tricks that you can learn from. Make a point of letting them know. + +## Mindset getting a code review + +The reviewer is doing you a Solid. They are there to help you do the best work you can. The best of the best have coaches, editors and mentors. Your code reviewers should help you in the same way. In situations where they are more experienced, this can be direct mentoring. In situations where they are more junior, they have a fresh pair of eyes that might get you to question deeply held assumptions. + +When a reviewer disagrees with an approach you took, seek to understand why. They might know things or see consequences you didn’t. While they might not have thought as deeply on the specific subject of the PR as you, they likewise probably are thinking about the impacts of the PR on areas you might not be paying attention to. + +If someone slaps a strong :-1: on your PR, be especially patient. Dig into why they think the PR is flawed. Approach the conversation with an intent of making the PR better, not defending your approach. You get no points for being a better debater, but you do get points for shipping better code and a better product, no matter where the inspiration or ideas came from. + +## Process + +- Every PR of significant complexity needs to be :+1:’d by at least one other engineer on the team (or @salsakran) to merge +- Add people you think should review your PR to the PR’s assignees. The reviewer can remove themselves once they have reviewed it, or decided they aren’t an appropriate reviewer +- Code that impacts other engineer’s work should be reviewed by those engineers +- A :+1: is the default “I’m ok with this" +- A :+0: (I made that up) is “I’m not thrilled with this, but other people saying “+1” means it can be merged +- A :-1: is a hard veto. This should be used sparingly in run of the mill PRs, and only for things that are missing tests, flagrant violations of a style guide, or break assumptions another part of the code base depends on. +- If you cut a major branch without discussing design, or talking through implications with other engineers whose work might be impacted, you should expect a :-1:, and not be hung up on reworking controversial sections. +- Any PR that has a :-1: CANNOT be merged until it is resolved. +- The owner of the PR and the person casting a :-1: should resolve the differences in approach. +- If there's an impasse, @salsakran casts a tie-breaking vote. Impasses should be rare. + +Note that these :+1:, :+0:, and :-1:’s should be explicitly stated in a comment, and not a reaction on the main description of the PR on github. A change from :-1: to :+1: should also be stated explicitly on a comment. + +## Timing + +- PRs for high priority issues should be code reviewed as soon as they are available. +- PRs for issues in a milestone can wait a few days. +- If there are no :+1:'s on a PR, it is the responsibility of the PR creator to follow up with others and get their code reviewed. To re-iterate, a PR needs to be :+1:’d to be merged, and if it has not been reviewed, it is on the opener of the PR to round up a reviewer. +- If there's a :-1: + no clear resolution, both the creator of the PR and the :-1: voter should plan on spending an hour over the next day or two to discuss the issue, and plan on how to resolve it. +- In the event of no movement on a PR with a :-1: after a week, @salsakran will chime in. + +## How to improve the quality of the code review + +For a summary of research on code reviews, check out [How code review works (and doesn't) in the real world](https://www.youtube.com/watch?v=_SJL7vepQvU). + +### What PR authors can do to get a better review + +- Guide reviewers by commenting on the important sections of the code. +- If you need someone's expertise/opinion, tag that person. +- Enhance PR descriptions by using [Notes and Warnings](https://github.com/github-community/community/discussions/16925) - these can be effective tools if you want a certain piece of information to stand out. + +### What PR reviewers can do to give a better review + +- Pay close attention to test files. Be aware of our tendency to assign lower significance to the test files and put a conscious effort to review them thoroughly. +- Start with the file most important to the change, not the first file presented in an alphabetical order in the PR. +- If you feel like you're lacking the context, ask the author for more details/better description. +- Unless the change is trivial, check out that branch and give Metabase a spin locally with the changes included. Make sure everything works as expected. diff --git a/_docs/doc-update-detection/developers-guide/community-drivers.md b/_docs/doc-update-detection/developers-guide/community-drivers.md new file mode 100644 index 000000000..d7f763637 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/community-drivers.md @@ -0,0 +1,59 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Community drivers' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/community-drivers.md' +redirect_from: + - /docs/doc-update-detection/developers-guide-drivers + - /docs/doc-update-detection/developers-guide/partner-and-community-drivers +--- + +# Community drivers + +> Community drivers are not supported on [Metabase Cloud](/cloud/). + +In addition to our [Officially supported drivers](../databases/connecting#connecting-to-supported-databases), many people build and maintain drivers for database integrations. + +## How to use a Community driver + +To use a Community driver on a self-hosted Metabase: + +1. Download the latest jar file from the driver's repository (see the repo's Releases section for the JAR files). +2. Copy the JAR file into the plugins directory in your Metabase directory (the directory where you run the Metabase JAR). + +You can change the location of the plugins directory by setting the environment variable `MB_PLUGINS_DIR`. + +## Community drivers + +> You install these drivers at your own risk. The plugins run as part of your Metabase and will have access to anything your Metabase does. And since we can’t vet for them, we don’t make them available on [Metabase Cloud](/cloud/). + +Anyone can build a community driver. These are the currently known third-party database drivers for Metabase. + +| Database | GitHub Stars | Last release (_if available_) | +| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| [CSV](https://github.com/Markenson/csv-metabase-driver) | ![GitHub stars](https://img.shields.io/github/stars/Markenson/csv-metabase-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/Markenson/csv-metabase-driver) | +| [Databend](https://github.com/databendcloud/metabase-databend-driver) | ![GitHub stars](https://img.shields.io/github/stars/databendcloud/metabase-databend-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/databendcloud/metabase-databend-driver) | +| [DB2](https://github.com/damienchambe/metabase-db2-driver) | ![GitHub stars](https://img.shields.io/github/stars/damienchambe/metabase-db2-driver) | ![Github (Pre-)Release Date](https://img.shields.io/github/release-date-pre/damienchambe/metabase-db2-driver) | +| [Dremio](https://github.com/Baoqi/metabase-dremio-driver) | ![GitHub stars](https://img.shields.io/github/stars/Baoqi/metabase-dremio-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/Baoqi/metabase-dremio-driver) | +| [DuckDB](https://github.com/MotherDuck-Open-Source/metabase_duckdb_driver) | ![GitHub stars](https://img.shields.io/github/stars/MotherDuck-Open-Source/metabase_duckdb_driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/MotherDuck-Open-Source/metabase_duckdb_driver) | +| [Firebolt](https://github.com/firebolt-db/metabase-firebolt-driver) | ![GitHub stars](https://img.shields.io/github/stars/firebolt-db/metabase-firebolt-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/firebolt-db/metabase-firebolt-driver) | +| [Firebird](https://github.com/evosec/metabase-firebird-driver) | ![GitHub stars](https://img.shields.io/github/stars/evosec/metabase-firebird-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/evosec/metabase-firebird-driver) | +| [GreptimeDB](https://github.com/greptimeteam/greptimedb-metabase-driver) | ![GitHub stars](https://img.shields.io/github/stars/greptimeteam/greptimedb-metabase-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/greptimeteam/greptimedb-metabase-driver) | +| [Hydra](https://www.hydra.so/blog-posts/2022-09-28-metabase-and-hydra) | Hydra connections use the official [Postgres driver](../databases/connections/postgresql). | Not applicable. | +| [Impala](https://github.com/brenoae/metabase-impala-driver) | ![GitHub stars](https://img.shields.io/github/stars/brenoae/metabase-impala-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/brenoae/metabase-impala-driver) | +| [Materialize](https://github.com/MaterializeInc/metabase-materialize-driver) | ![GitHub stars](https://img.shields.io/github/stars/MaterializeInc/metabase-materialize-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/MaterializeInc/metabase-materialize-driver) | +| [Neo4j](https://github.com/StronkMan/metabase-neo4j-driver) | ![GitHub stars](https://img.shields.io/github/stars/StronkMan/metabase-neo4j-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/StronkMan/metabase-neo4j-driver) | +| [Netsuite SuiteAnalytics Connect](https://github.com/ericcj/metabase-netsuite-driver) | ![GitHub stars](https://img.shields.io/github/stars/ericcj/metabase-netsuite-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/ericcj/metabase-netsuite-driver) | +| [Peaka](https://github.com/peakacom/metabase-driver) | ![GitHub stars](https://img.shields.io/github/stars/peakacom/metabase-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/peakacom/metabase-driver) | +| [Teradata](https://github.com/swisscom-bigdata/metabase-teradata-driver) | ![GitHub stars](https://img.shields.io/github/stars/swisscom-bigdata/metabase-teradata-driver) | ![GitHub (Pre-)Release Date](https://img.shields.io/github/release-date-pre/swisscom-bigdata/metabase-teradata-driver) | + +If you don't see a driver for your database, try looking in the comments of the [issue related to the database](https://github.com/metabase/metabase/labels/Database%2F). You might also find more drivers by searching on GitHub for "Metabase driver". + +If you're having problems installing or using a community driver, your best bet is to contact the author of the driver. + +## Write your own driver + +Check out [Guide to writing a Metabase driver](./drivers/start). diff --git a/_docs/doc-update-detection/developers-guide/dev-branch-docker.md b/_docs/doc-update-detection/developers-guide/dev-branch-docker.md new file mode 100644 index 000000000..b0b401e13 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/dev-branch-docker.md @@ -0,0 +1,63 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'How to run a development branch of Metabase using Docker' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/dev-branch-docker.md' +--- + +# How to run a development branch of Metabase using Docker + +If you want to run a branch of Metabase that's currently in development, the easiest way to get started is to use a pre-built Docker image. You can also [compile Metabase yourself](build). + +If you're looking to download and run the latest official open source version of Metabase, check the [operations guide](../installation-and-operation/installing-metabase). + +## Installing Docker + +The only thing you’ll need to get started is Docker itself. + +- [Install Docker Desktop](https://www.docker.com/products/docker-desktop) + +OR + +- If you like to install things via Homebrew: + +```bash +brew install --cask docker +``` + +Once Docker is installed, you’re ready to go. + +## Run a development branch to test or verify features + +[See here](https://hub.docker.com/r/metabase/metabase-dev/tags) for a list of development branches that you can run via Docker. + +1. Open your terminal app of choice. + +2. Copy and paste this command, switching out `` for the name of the branch you’d like to test: + +```bash +docker run --platform linux/amd64 -d -p 3000:3000 --name metabase-dev metabase/metabase-dev: +``` + +3. In your browser, navigate to `http://localhost:3000`, where you should see Metabase. It may take a minute or two to start up depending on your computer. + +**Note**: This will always start Metabase with a fresh database. + +## Pull and run the latest changes + +Run: + +``` +docker pull metabase/metabase-enterprise-head:latest +``` + +Then: + +``` +docker run --platform linux/amd64 -d -p 3000:3000 --name metabase metabase/metabase-enterprise-head:latest +``` + +The “latest” tag is not automatically upgraded on your local machine, so the above commands ensure that you’re pulling the latest changes. diff --git a/_docs/doc-update-detection/developers-guide/devenv.md b/_docs/doc-update-detection/developers-guide/devenv.md new file mode 100644 index 000000000..2781930a0 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/devenv.md @@ -0,0 +1,404 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Development environment' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/devenv.md' +--- + +# Development environment + +The Metabase application has two basic components: + +1. A backend written in Clojure which contains a REST API as well as all the relevant code for talking to databases and processing queries. +2. A frontend written as a Javascript single-page application which provides the web UI. + +Both components are built and assembled together into a single JAR file. In the directory where you run the JAR, you can create a JAR file (if Metabase hasn't already created it) and add drivers in there (the drivers are also JARs). + +## Quick start + +To spin up a development environment, run: + +``` +yarn dev +``` + +This runs both the [frontend](#frontend) and [backend](#backend). Alternatively, you can run them separately in two terminal sessions below. + +### Frontend + +Metabase depends on third-party libraries to run, so you'll need to keep those up to date. The Clojure CLI will automatically fetch the dependencies when needed. With JavaScript dependencies, however, you'll need to kick off the installation process manually. + +```sh +# javascript dependencies +$ yarn +``` + +Start the frontend build process with + +``` +yarn build-hot +``` + +See [Frontend development](#frontend-development). + +### Backend + +Run your backend development server with + +``` +clojure -M:run + +``` + +See [backend development](#backend-development). + +## Frontend development + +We use these technologies for our FE build process to allow us to use modules, es6 syntax, and css variables. + +- webpack +- babel +- cssnext + +Frontend tasks are executed using `yarn`. All available tasks can be found in `package.json` under _scripts_. + +To build the frontend client without watching for changes, you can use: + +```sh +$ yarn build +``` + +If you're working on the frontend directly, you'll most likely want to reload changes on save, and in the case of React components, do so while maintaining state. To start a build with hot reloading, use: + +```sh +$ yarn build-hot +``` + +Note that at this time if you change CSS variables, those changes will only be picked up when a build is restarted. + +There is also an option to reload changes on save without hot reloading if you prefer that. + +```sh +$ yarn build-watch +``` + +Some systems may have trouble detecting changes to frontend files. You can enable filesystem polling by uncommenting the `watchOptions` clause in `webpack.config.js`. If you do this it may be worth making git ignore changes to webpack config, using `git update-index --assume-unchanged webpack.config.js` + +We exclude ESLint loader in dev mode for seven times quicker initial builds by default. You can enable it by exporting an environment variable: + +```sh +$ USE_ESLINT=true yarn build-hot +``` + +### Frontend testing + +Run all unit and Cypress end-to-end tests with + +``` +yarn test +``` + +Cypress tests and some unit tests are located in `frontend/test` directory. New unit test files are added next to the files they test. + +### Frontend debugging + +By default, we use a simple source mapping option that is optimized for speed. + +If you run into issues with breakpoints, especially inside jsx, please set env variable `BETTER_SOURCE_MAPS` to true before you run the server. + +Example: + +``` +BETTER_SOURCE_MAPS=true yarn dev +``` + +### Cypress end-to-end tests + +End-to-end tests simulate realistic sequences of user interactions. Read more about how we approach [end-to-end testing with Cypress](./e2e-tests). + +Cypress end-to-end tests use an enforced file naming convention `.cy.spec.js` to separate them from unit tests. + +### Jest unit tests + +Unit tests are focused around isolated parts of business logic. + +Unit tests use an enforced file naming convention `.unit.spec.js` to separate them from end-to-end tests. + +``` +yarn test-unit # Run all tests at once +yarn test-unit-watch # Watch for file changes +``` + +## Backend development + +Clojure REPL is the main development tool for the backend. There are some directions below on how to setup your REPL for easier development. + +And of course your Jetty development server is available via + +``` +clojure -M:run +``` + +You can also start a REPL another way (e.g., through your editor) and then call: + +``` +(do (dev) (start!)) +``` + +To start the server (at `localhost:3000`). This will also set up or migrate your application database. To actually +use Metabase, don't forget to start the frontend as well (e.g. with `yarn build-hot`). + +### The application database + +By default, Metabase uses H2 for its application database, but we recommend using Postgres. This is configured with +several properties that can be set as environment variables or in a `deps.edn`. One approach is: + +``` +;; ~/.clojure/deps.edn + +{:aliases + {:user + {:jvm-opts + ["-Dmb.db.host=localhost" + "-Dmb.db.type=postgres" + "-Dmb.db.user=" + "-Dmb.db.dbname=" + "-Dmb.db.pass="]}}} +``` + +You could also pass a full conection string in as the `mb.db.connection.uri`: + +``` +"-Dmb.db.connection.uri=postgres://:@localhost:5432/" +``` + +Besides using environment variables, there is the option to interface with the configuration library [environ](https://github.com/weavejester/environ) directly. + +This approach requires creating a `.lein-env` file within your project directory: + +``` +{:mb-db-type "postgres" + :mb-db-host "localhost" + :mb-db-user "" + :mb-db-dbname "" + :mb-db-pass ""} +``` + +Despite the name, this file works fine with `deps.edn` projects. An advantage of this approach versus the global `deps.edn` approach is that it is scoped to this project only. + +Only use this for development, it is not supported for production use. There is already entry in `.gitignore` to prevent you accidentally committing this file. + +### Building drivers + +Most of the drivers Metabase uses to connect to external data warehouse databases are separate projects under the +`modules/` subdirectory. When running Metabase via `clojure`, you'll need to build these drivers in order to have access +to them. You can build drivers as follows: + +``` +# Build the 'mongo' driver +./bin/build-driver.sh mongo +``` + +(or) + +``` +# Build all drivers +./bin/build-drivers.sh +``` + +### Including driver source paths for development or other tasks + +For development when running various Clojure tasks you can add the `drivers` and `drivers-dev` aliases to merge the +drivers' dependencies and source paths into the Metabase project: + +``` +# Install dependencies, including for drivers +clojure -P -X:dev:ci:drivers:drivers-dev +``` + +### Running unit tests + +Run unit tests with + +``` +# OSS tests only +clojure -X:dev:test + +# OSS + EE tests +clojure -X:dev:ee:ee-dev:test +``` + +or a specific test (or test namespace) with + +``` +# run tests in only one namespace (pass in a symbol) +clojure -X:dev:test :only metabase.session.api-test + +# run one specific test (pass in a qualified symbol) +clojure -X:dev:test :only metabase.session.api-test/my-test + +# run tests in one specific folder (test/metabase/util in this example) +# pass arg in double-quotes so Clojure CLI interprets it as a string; +# our test runner treats strings as directories +clojure -X:dev:test :only '"test/metabase/util"' +``` + +As in any clojure.test project, you can also run unit tests from the REPL. Some examples of useful ways to run tests are: + +```clojure +;; run a single test with clojure.test +some-ns=> (clojure.test/run-test metabase.util-test/add-period-test) + +Testing metabase.util-test + +Ran 1 tests containing 4 assertions. +0 failures, 0 errors. +{:test 1, :pass 4, :fail 0, :error 0, :type :summary} + +;; run all tests in the namespace +some-ns=> (clojure.test/run-tests 'metabase.util-test) + +Testing metabase.util-test +{:result true, :num-tests 100, :seed 1696600311261, :time-elapsed-ms 45, :test-var "pick-first-test"} + +Ran 33 tests containing 195 assertions. +0 failures, 0 errors. +{:test 33, :pass 195, :fail 0, :error 0, :type :summary} + +;; run tests for a set of namespaces related to a feature you are working on (eg pulses) +some-ns=> (let [namespaces '[metabase.pulse.markdown-test metabase.pulse.parameters-test]] + (apply require namespaces) ;; make sure the test namespaces are loaded + (apply clojure.test/run-tests namespaces)) + +Testing metabase.pulse.markdown-test + +Testing metabase.pulse.parameters-test + +Ran 5 tests containing 147 assertions. +0 failures, 0 errors. +{:test 5, :pass 147, :fail 0, :error 0, :type :summary} + +;; but we also have a lovely test runner with lots of cool options +some-ns=> (metabase.test-runner/find-and-run-tests-repl {:namespace-pattern ".*pulse.*"}) +Running tests with options {:mode :repl, :namespace-pattern ".*pulse.*", :exclude-directories ["classes" "dev" "enterprise/backend/src" "local" "resources" "resources-ee" "src" "target" "test_config" "test_resources"], :test-warn-time 3000} +Excluding directory "dev/src" +Excluding directory "local/src" +Looking for test namespaces in directory test +Finding tests took 1.6 s. +Excluding directory "test_resources" +Excluding directory "enterprise/backend/src" +Looking for test namespaces in directory enterprise/backend/test +Excluding directory "src" +Excluding directory "resources" +Running 159 tests +... + +;; you can even specify a directory if you're working on a subfeature like that +some-ns=> (metabase.test-runner/find-and-run-tests-repl {:only "test/metabase/pulse/"}) +Running tests with options {:mode :repl, :namespace-pattern #"^metabase.*", :exclude-directories ["classes" "dev" "enterprise/backend/src" "local" "resources" "resources-ee" "src" "target" "test_config" "test_resources"], :test-warn-time 3000, :only "test/metabase/pulse/"} +Running tests in "test/metabase/pulse/" +Looking for test namespaces in directory test/metabase/pulse +Finding tests took 37.0 ms. +Running 65 tests +... + +``` + +#### Testing drivers + +By default, the tests only run against the `h2` driver. You can specify which drivers to run tests against with the env var `DRIVERS`: + +``` +DRIVERS=h2,postgres,mysql,mongo clojure -X:dev:drivers:drivers-dev:test +``` + +Some drivers require additional environment variables when testing since they are impossible to run locally (such as +Redshift and Bigquery). The tests will fail on launch and let you know what parameters to supply if needed. + +If running tests from the REPL, you can call something like: + +``` +(mt/set-test-drivers! #{:postgres :mysql :h2}) +``` + +Most drivers need to be able to load some data (a few use static datasets) and all drivers need to be able to connect to an instance of that database. You can find out what is needed in each's drivers test data namespace which follows that pattern `metabase.test.data.`. + +There should be an implementation of a multimethod tx/dbdef->connection-details which must produce a way to connect to a database. You can see what is required. + +Here's the one for postgres in `metabase.test.data.postgres`: + +```clojure +(defmethod tx/dbdef->connection-details :postgres + [_ context {:keys [database-name]}] + (merge + {:host (tx/db-test-env-var-or-throw :postgresql :host "localhost") + :port (tx/db-test-env-var-or-throw :postgresql :port 5432) + :timezone :America/Los_Angeles} + (when-let [user (tx/db-test-env-var :postgresql :user)] + {:user user}) + (when-let [password (tx/db-test-env-var :postgresql :password)] + {:password password}) + (when (= context :db) + {:db database-name}))) +``` + +You can see that this looks in the environment for: + +- host (defaults to "localhost") +- port (defaults to 5432) +- user +- password + +The function names indicate if they throw or not (although in this instance the ones that would throw are also supplied default values). + +The `(tx/db-test-env-var :postgresql :password)` will look in the env/env map for `:mb-postgresql-test-password` which will be set by the environmental variable `MB_POSTGRESQL_TEST_PASSWORD`. + +```clojure +some-ns=> (take 10 (keys environ.core/env)) +(:mb-redshift-test-password + :java-class-path + :path + :mb-athena-test-s3-staging-dir + :iterm-profile + :mb-snowflake-test-warehouse + :mb-bigquery-cloud-sdk-test-service-account-json + :tmpdir + :mb-oracle-test-service-name + :sun-management-compiler) +``` + +### Running the linters + +`clj-kondo` must be [installed separately](https://github.com/clj-kondo/clj-kondo/blob/master/doc/install.md). + +``` +# Run Eastwood +clojure -X:dev:ee:ee-dev:drivers:drivers-dev:eastwood + +# Run the namespace checker +clojure -X:dev:ee:ee-dev:drivers:drivers-dev:test:namespace-checker + +# Run clj-kondo +./bin/kondo.sh + +# Lint the migrations file (if you've written a database migration): +./bin/lint-migrations-file.sh +``` + +## Continuous integration + +All frontend and backend linters and tests can be executed with + +```sh +$ yarn ci +``` + +It is also possible to execute front-end and back-end checks separately + +```sh +$ yarn ci-frontend +$ yarn ci-backend +``` diff --git a/_docs/doc-update-detection/developers-guide/docs.md b/_docs/doc-update-detection/developers-guide/docs.md new file mode 100644 index 000000000..29de778d7 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/docs.md @@ -0,0 +1,49 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Developing Metabase documentation' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/docs.md' +--- + +# Developing Metabase documentation + +Notes on writing docs for Metabase. + +## Linting markdown links + +You can check for broken links in the [docs](../) directory by running: + +``` +yarn run docs-lint-links +``` + +This command uses [Markdown link check](https://github.com/tcort/markdown-link-check) to vet links in all of the markdown files in the [docs](../) directory. We recommend writing the command's output to a file. E.links., + +``` +touch ~/links-to-fix.txt && yarn run docs-lint-links > ~/links-to-fix.txt +``` + +Alternatively, if you just want to check the in-product links to make sure they link to actual documents: + +``` +yarn run lint-docs-links +``` + +You can view both commands in the [package.json](https://github.com/metabase/metabase/blob/master/package.json) file under `scripts`. + +## Updating API docs + +To update an API endpoint description, you'll need to edit the comment in the [source code for that endpoint](https://github.com/metabase/metabase/tree/master/src/metabase/api). + +To bring your changes into `docs/latest/api-documentation`, you'll need to open a separate PR. Check out a new branch from the current release branch, and run: + +``` +clojure -M:ee:run api-documentation +``` + +## Style guide + +Ancient [style guide]() that needs an update. diff --git a/_docs/doc-update-detection/developers-guide/driver-changelog.md b/_docs/doc-update-detection/developers-guide/driver-changelog.md new file mode 100644 index 000000000..01f119d41 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/driver-changelog.md @@ -0,0 +1,838 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Driver interface changelog' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/driver-changelog.md' +--- + +# Driver Interface Changelog + +## Metabase 0.55.0 + +- Added a feature `:expression-literals` for drivers that support expressions consisting of a single string, number, or boolean literal value. + +## Metabase 0.54.0 + +- Added the multi-method `allowed-promotions` that allows driver control over which column type promotions are supported for uploads. + +- Added the multi-method `alter-table-columns!`, like `alter-columns!` but accepts additional kw-arg opts. + Existing implementations of `alter-columns!` will be used by default. + +- `alter-columns!` is now marked as deprecated. Drivers + should seek to implement the new `alter-table-columns!` method. + +- The multimethod `metabase.driver.sql-jdbc.sync.interface/alter-table-columns-sql` has been added, like `alter-columns-sql` but accepts additional kw-arg opts. Existing implementations of `alter-columns-sql` will be used by default. + +- `metabase.driver.sql-jdbc.sync.interface/alter-columns-sql` is now marked as deprecated. Drivers should seek to implement the new `alter-table-columns-sql` method. + +- Added a feature `:test/arrays` and multimethod `native-array-query` to enable the testing of array types for + databases that support them. + +- Added a feature `:expressions/text` for drivers that support casting to text + +- Added a feature `:expressions/date` for drivers that support casting text to date + +- Added a feature `:expressions/integer` for drivers that support casting text to integer + +- Added a feature `:distinct-where` for drivers that support the `distinct-where` function. + +- Added a feature `:split-part` for drivers that support the `split-part` function. + +## Metabase 0.53.0 + +- Added the multimethod `bad-connection-details` to allow mocking bad connection parameters for tests. + +- Added `driver/dynamic-database-types-lookup` and its `:postgres` implementation. The method generates map + of `database_type` to `base_type`, for dynamic types, ie. those which are not covered + by `sql-jdbc.sync/database-type->base-type`. Its original purpose was to enable mapping of user defined enums in + postgres to appropriate base type in results metadata. + +## Metabase 0.52.12 + +- Added the multimethod `metabase.driver/db-details-to-test-and-migrate`. This can be used to cleanup and migrate ambiguous connection details from previous versions. + +## Metabase 0.52.0 + +- The Docker image for Metabase 0.52.0 now uses Java 21 instead of Java 11. Please make sure to test your driver + against Java 21 and make sure it works as expected. + + We have found several of our own drivers that run into issues with the security changes introduced in newer JVMs; as + such, we're currently setting the JVM flag + + ``` + --add-opens java.base/java.nio=ALL-UNNAMED + ``` + + when running Metabase to disable some of these new security checks. If your tests run into issues with Java 21 + without the flag set, try running with it set -- this might fix the problems. + +## Metabase 0.51.4 + +- Another driver feature has been added: `describe-indexes`. If a driver opts-in to supporting this feature, The + multimethod `metabase.driver/describe-indexes` must be implemented, as a replacement for + `metabase.driver/describe-table-indexes`. + +- The multimethod `metabase.driver.sql-jdbc.sync.describe-table/describe-indexes-sql` has been added. The method needs + to be implemented if the driver supports `describe-indexes` and you want to use the default JDBC implementation of + `metabase.driver/describe-indexes`. + +## Metabase 0.51.0 + +- New optional method `metabase.driver/query-result-metadata` has been added for efficiently calculating metadata for + queries without actually running them. `:sql-jdbc` has been given a default implementation; drivers not based on + this that can determine result metadata without actually running queries should add their implementations as well + for better performance when saving Questions. Refer to the method docstring for more information and where to find + an example implementation. + +- Prior to 0.51.0, to generate SQL queries with inline parameters, Metabase would generate a parameterized SQL string, + then attempt to parse the SQL replace and replace `?` placeholders with inline values from the driver method + `metabase.driver.sql.util.unprepare/unprepare-value`. In 0.51.0+, Metabase instead generates these queries using + Honey SQL 2's `:inline` option, eliminating the need to parse and replace `?` placeholders. As such, the + `metabase.driver.sql.util.unprepare` namespace has been deprecated; you should remove all usages of it in your driver. + +- The `metabase.driver.sql.util.unprepare/unprepare-value` method has been replaced by the new method + `metabase.driver.sql.query-processor/inline-value`. The signatures of these two functions are the same, and you + should be able to simply change the all of your `unprepare-value` implementations to `inline-value` instead. See + [PR #45008](https://github.com/metabase/metabase/pull/45008) for examples of this change. + + For the time being, implementations of `unprepare-value` are used as implementations of `inline-value` + automatically, but `unprepare-value` is slated for removal in 0.54.0. + +- `metabase.driver.sql.query-processor/format-honeysql` is now a multimethod, mainly so you can bind + `*compile-with-inline-parameters*` if you need to always compile without parameterization. + +- The dynamic variable `metabase.driver/*compile-with-inline-parameters*` (default `false`) has been added; drivers + that can generate parameterized queries should look at its value in their implementation of + `metabase.driver/mbql->native` and adjust their output accordingly. For `:sql-jdbc`-based drivers that support + parameterization, this is handled in the shared `metabase.driver.sql.query-processor` code, so you shouldn't need + to adjust anything here. For `:sql` drivers that do not support JDBC-style parameterized queries you can implement + `format-honeysql` and bind `*compile-with-inline-parameters*` as discussed above. See the `:athena` driver for an + example of how to do this. + +- `metabase.driver.sql.util.unprepare/unprepare`, which took a parameterized SQL string and de-parameterized or + "unprepared" it, has been removed. Instead, if you need a query with parameters spliced directly into the SQL, + bind `metabase.driver/*compile-with-inline-parameters*` as discussed above. + +- Similarly, the driver method `metabase.driver/splice-parameters-into-native-query` has been marked deprecated, and + the default implementation will throw an Exception if called. Rework code that generates parameterized queries and + then calls `unprepare` or `splice-parameters-into-native-query` with code that generates queries with inlined + parameters in the first place as discussed above. Tests can use + `metabase.query-processor.compile/compile-with-inline-parameters` if needed. + +- `metabase.query-processor.compile/compile-and-splice-parameters` has been removed; replace usages with + `metabase.query-processor.compile/compile-with-inline-parameters`. + +- The three-arity of `metabase.driver.sql.query-processor/format-honeysql` (which had an additional parameter for + Honey SQL version) has been removed; replace all usages with the two-arity version. Honey SQL 2 has been the only + supported version since Metabase 0.49.0. + +- The `:skip-drop-db?` option sometimes passed to methods for loading and destroying test data is no longer passed, + you can remove code that checks for it. Test data code is now better about avoiding unneeded/redundant calls to + `metabase.test.data.interface/create-db!`, so test data loading code should not need to call `DROP DATABASE IF EXISTS` before loading test data. + +- Test data loading for JDBC-based databases has been overhauled somewhat. The multimethod + `metabase.test.data.sql-jdbc.load-data/load-data!` and helper functions for it have been removed in favor of several + new simpler to compose and understand multimethods. + +- `metabase.test.data.sql-jdbc.load-data/row-xform` is a transducer applied to each row when loading test data. The + default implementation is `identity`, but you can use `metabase.test.data.sql-jdbc.load-data/add-ids-xform` to add + IDs to each row (this replaces the removed `metabase.test.data.sql-jdbc.load-data/load-data-add-ids` function) and + `metabase.test.data.sql-jdbc.load-data/maybe-add-ids-xform` (which replaces + `metabase.test.data.sql-jdbc.load-data/load-data-maybe-add-ids!` and + `metabase.test.data.sql-jdbc.load-data/load-data-maybe-add-ids-chunked!`). + +- `metabase.test.data.sql-jdbc.load-data/chunk-size` is used to control the number of rows that should be loaded in + each batch. The default is `200`, but you can implement this method and return `nil` to load data all at once + regardless of the number of rows. `metabase.test.data.sql-jdbc.load-data/*chunk-size*`, + `metabase.test.data.sql-jdbc.load-data/load-data-chunked`, + `metabase.test.data.sql-jdbc.load-data/load-data-all-at-once!`, + `metabase.test.data.sql-jdbc.load-data/load-data-chunked!`, and other similar functions are no longer needed and + have been removed. + +- `metabase.test.data.sql-jdbc.load-data/chunk-xform` is a transducer applied to each chunk of rows (dependent on + `chunk-size`) or the entire group of rows if `chunk-size` is `nil`. The default is `identity`. It can be used to + implement special behavior for each chunk, for example writing the chunk to a CSV file to load separately in the + `metabase.test.data.sql-jdbc.load-data/do-insert!` method. See the `metabase.test.data.vertica` for an example of + this. + +- Connections are now created once and reused for much of test data loading. The second argument to + `metabase.test.data.sql-jdbc.load-data/do-insert!` is now a `java.sql.Connection` instead of a `clojure.java.jdbc` + spec. + +- Similarly, `metabase.test.data.sql-jdbc.execute/execute-sql!` and helper functions like + `metabase.test.data.sql-jdbc.execute/sequentially-execute-sql!` are now called with a `java.sql.Connection` + instead of both a `DatabaseDefinition` and either `:server` or `:db` _context_; the appropriate connection type is + created automatically and passed in in the calling code. Update your method implementations and usages + accordingly. + +- Added method `metabase.test.data.interface/dataset-already-loaded?` to check if a test dataset has already been + loaded. JDBC-based drivers have a default implementation that checks whether we can connect to the database; you + may need to override this for drivers that don't actually physically create new databases in tests. You can check + whether your JDBC-based driver works correctly using the default implementation by running the test + `metabase.test.data.sql-jdbc-test/dataset-already-loaded?-test`. + +- `metabase.test.data.sql.ddl/insert-rows-ddl-statements` has been renamed to + `metabase.test.data.sql.ddl/insert-rows-dml-statements`, since `INSERT` is DML, not DDL. Please update your method + implementations accordingly. + +- The `:foreign-keys` driver feature has been removed. `:metadata/keys-constraints` should be used for drivers that + support foreign key relationships reporting during sync. Implicit joins now depend on the `:left-join` feature + instead. The default value is true for `:sql` based drivers. All join features are now enabled for `:sql` based + drivers by default. Previously, those depended on the `:foreign-keys` feature. If your driver supports `:left-join`, + the test for remapping and implicit joins will be now executed. + +- The`:parameterized-sql` driver feature has been added to distinguish drivers that don't support parametrized SQL in + tests. Currently, this is disabled only for `:sparksql`. + +- The test methods `metabase.test.data.interface/supports-time-type?` and + `metabase.test.data.interface/supports-timestamptz-type?` have been removed and replaced by the features + `:test/time-type` and `:test/timestamptz-type` respectively. If you implemented these methods, replace + implementations with implementations of `metabase.driver/database-supports?` for your driver and the equivalent + feature keyword instead. + +- Drivers that use `metabase.driver.sql.query-processor/->honeysql` can implement + `:metabase.driver.sql.query-processor/nfc-path` to include the nfc-path in the field identifier. So that record-like + fields can be referenced with `..`. See `bigquery-cloud-sdk` for an example. Defaults to `nil` to indicate that the path should not be part of the identifier. + +- `:test/dynamic-dataset-loading` feature has been added. It enables drivers to bail out of tests that require + creation of new, not pre-loaded, dataset during test run time. + +- The `:temporal/requires-default-unit` feature has been added. It should be false for most drivers, but it's necessary + for a few (like the old, pre-JDBC Druid driver) to find all temporal field refs and put a `:temporal-unit :default` on them. + That default setting was previously done for all drivers, but it introduced some downstream issues, so now only those + drivers which need it can set the feature. + +## Metabase 0.50.17 + +- Added method `metabase.driver/incorporate-auth-provider-details` for driver specific behavior required to + incorporate response of an auth-provider into the DB details. In most cases this means setting the :password + and/or :username based on the auth-provider and its response. + +## Metabase 0.50.16 + +- `:type/fingerprinting-unsupported` has been added in the `metabase.types` namespace. Similar to + `:type/field-values-unsupported` for field values scanning, it is used to determine whether a specific field + should have its fingerprint computed or not. At the time of writing that logic is performed in + `metabase.sync.analyze.fingerprint/fields-to-fingerprint-base-clause`. + +- `:type/Large` has been also been added in the `metabase.types` namespace. It can be used by driver authors to + signal that a specific field contains large enough values to skip fingerprinting or field values scanning. It + can be used for other purposes as well in the future. Examples include Oracle CLOB or Postgres JSON columns. + +## Metabase 0.50.0 + +- The Metabase `metabase.mbql.*` namespaces have been moved to `metabase.legacy-mbql.*`. You probably didn't need to + use these namespaces in your driver, but if you did, please update them. + +- The multimethod `metabase.driver/truncate!` has been added. This method is used to delete a table's rows in the most + efficient way possible. This is currently only required for drivers that support the `:uploads` feature, and has + a default implementation for JDBC-based drivers. + +- New feature `:window-functions/cumulative` has been added. Drivers that implement this method are expected to + implement the cumulative sum (`:cum-sum`) and cumulative count (`:cum-count`) aggregation clauses in their native + query language. For non-SQL drivers (drivers not based on our `:sql` or `:sql-jdbc` drivers), this feature flag is + set to `false` by default; the old (broken) post-processing implementations of cumulative aggregations will continue + to be used. (See issues [#13634](https://github.com/metabase/metabase/issues/13634) and + [#15118](https://github.com/metabase/metabase/issues/15118) for more information on why the old implementation is + broken.) + + Non-SQL drivers should be updated to implement cumulative aggregations natively if possible. + + The SQL implementation uses `OVER (...)` expressions. It will automatically move `GROUP BY` expressions like + `date_trunc()` into a `SUBSELECT` so fussy databases like BigQuery can reference plain column identifiers. The + actual SQL generated will look something like + + ```sql + SELECT + created_at_month, + sum(sum(total) OVER (ORDER BY created_at_month ROWS UNBOUNDED PRECEDING) AS cumulative_sum + FROM ( + SELECT + date_trunc('month', created_at) AS created_at_month, + total + FROM + my_table + ) source + GROUP BY + created_at_month + ORDER BY + created_at_month + ``` + + Non-SQL drivers can use + `metabase.query-processor.util.transformations.nest-breakouts/nest-breakouts-in-stages-with-window-aggregation` + if they want to leverage the same query transformation. See the default `:sql` implementation of + `metabase.driver.sql.query-processor/preprocess` for an example of using this transformation when needed. + + You can run the new tests in `metabase.query-processor-test.cumulative-aggregation-test` to verify that your driver + implementation is working correctly. + +- `metabase.driver.common/class->base-type` no longer supports Joda Time classes. They have been deprecated since 2019. + +- New feature `:window-functions/offset` has been added to signify that a driver supports the new MBQL `:offset` + clause (equivalent of SQL `lead` and `lag` functions). This is enabled by default for `:sql` and `:sql-jdbc`-based + drivers. Other drivers should add an implementation for this clause and enable the feature flag. + +- `:type/field-values-unsupported` was added in `metabase.types` namespace. It is used in field values computation + logic, to determine whether a specific field should have its field values computed or not. At the time of writing + that is performed in `metabase.models.field-values/field-should-have-field-values?`. Deriving from it, driver + developers have a way to out of field values computation for fields that are incompatible with the query used for + computation. Example could be Druid's `COMPLEX` database type fields. See the `:druid-jdbc` implementation + of `sql-jdbc.sync/database-type->base-type` in the `metabase.driver.druid-jdbc` and derivations in the + `metabase.types` namespace for an example. + +- New feature `:metadata/key-constraints` has been added to signify that a driver support defining and enforcing foreign + key constraints at the schema level. This is a different, stronger condition than `:foreign-keys`. Some databases + (Presto, Athena, etc.) support _querying_ over foreign key relationships (`:foreign-keys`) but do not track or enforce + those relationships in the schema. Defaults to `true` in `:sql` and `:sql-jdbc` drivers; set to `false` in the + first-party SparkSQL, Presto and Athena drivers. + +- New feature `:connection/multiple-databases` has been added to indicate whether a _connection_ to this driver + corresponds to multiple databases or just one. The default is `false`, where a connection specifies a single database. + This is the common case for classic relational DBs like Postgres, and some cloud databases. In contrast, a driver like + Athena sets this to `true` because it connects to an S3 bucket and treats each file within it as a database. + +- New feature `:identifiers-with-spaces` has been added to indicate where a driver supports identifiers like table or + column names that contains a space character. Defaults to `false`. + +- New feature `:uuid-type` has been added to indicate that this database is able to distinguish and filter against UUIDs. + Only a few database support native UUID types. The default is `false`. + +## Metabase 0.49.22 + +- A new optional method `metabase.driver.sql/json-field-length` has been added. It should be implemented for all + drivers that derive from `:sql` and support the `:nested-field-columns` feature. If implemented, Metabase will skip + querying large JSON values during the "sync-fields" step that could otherwise slow down the inference of nested + field columns and cause Metabase to run out of heap space. + +## Metabase 0.49.9 + +- Another driver feature has been added: `upload-with-auto-pk`. It only affects drivers that support `uploads`, and + is optional to support. Drivers support this feature by default, and can choose not to support it if there is no way + to create a table with an auto-incrementing integer column. The driver can override the default using + `driver/database-supports?`. + +## Metabase 0.49.1 + +- Another driver feature has been added: `describe-fields`. If a driver opts-in to supporting this feature, The + multimethod `metabase.driver/describe-fields` must be implemented, as a replacement for + `metabase.driver/describe-table`. + +- The multimethod `metabase.driver.sql-jdbc.sync.describe-table/describe-fields-sql` has been added. The method needs + to be implemented if the driver supports `describe-fields` and you want to use the default JDBC implementation of + `metabase.driver/describe-fields`. + +## Metabase 0.49.0 + +- The multimethod `metabase.driver/describe-table-fks` has been deprecated in favor of `metabase.driver/describe-fks`. + `metabase.driver/describe-table-fks` will be removed in 0.52.0. + +- The multimethod `metabase.driver/describe-fks` has been added. The method needs to be implemented if the database + supports the `:foreign-keys` and `:describe-fks` features. It replaces the `metabase.driver/describe-table-fks` + method, which is now deprecated. + +- The multimethod `metabase.driver.sql-jdbc.sync.describe-table/describe-fks-sql` has been added. The method needs + to be implemented if you want to use the default JDBC implementation of `metabase.driver/describe-fks`. + +- The multimethod `metabase.driver/alter-columns!` has been added. This method is used to alter a table's columns in the + database. This is currently only required for drivers that support the `:uploads` feature, and has a default + implementation for JDBC-based drivers. + +- The multimethod `metabase.driver.sql-jdbc.sync.interface/alter-columns-sql` has been added. The method + allows you to customize the query used by the default JDBC implementation of `metabase.driver/alter-columns!`. + +- The multimethod `metabase.driver.sql-jdbc.sync.interface/current-user-table-privileges` has been added. + JDBC-based drivers can implement this to improve the performance of the default SQL JDBC implementation of + `metabase.driver/describe-database`. It needs to be implemented if the database supports the `:table-privileges` + feature and the driver is JDBC-based. + +- The multimethod `metabase.driver/create-table!` can take an additional optional map with an optional key `primary-key`. + `metabase.driver/upload-type->database-type` must also be changed, so that if + `:metabase.upload/auto-incrementing-int-pk` is provided as the `upload-type` argument, the function should return a + type without the primary-key constraint included. See PR [#22166](https://github.com/metabase/metabase/pull/37505/) + for more information. These changes only need to be implemented if the database supports the `:uploads` feature. + +- The multimethod `metabase.driver/create-auto-pk-with-append-csv?` has been added. The method only needs to be + implemented if the database supported the `:uploads` feature in 47 or earlier, and should return true if so. + +- The multimethod `metabase.driver/add-columns!` has been added. This method is used to add columns to a table in the + database. It only needs to be implemented if the database supported the `:uploads` feature in 47 or earlier. + +- A new driver method has been added `metabase.driver/describe-table-indexes` along with a new feature `:index-info`. + This method is used to get a set of column names that are indexed or are the first columns in a composite index. + +- `metabase.util.honeysql-extensions`, deprecated in 0.46.0, has been removed. SQL-based drivers using Honey SQL 1 + are no longer supported. See 0.46.0 notes for more information. + `metabase.driver.sql.query-processor/honey-sql-version` is now deprecated and no longer called. All drivers are + assumed to use Honey SQL 2. + +- The method `metabase.driver.sql.parameters.substitution/align-temporal-unit-with-param-type` is now deprecated. + Use `metabase.driver.sql.parameters.substitution/align-temporal-unit-with-param-type-and-value` instead, + which has access to `value` and therefore provides more flexibility for choosing the right conversion unit. + +## Metabase 0.48.0 + +- The MBQL schema in `metabase.mbql.schema` now uses [Malli](https://github.com/metosin/malli) instead of + [Schema](https://github.com/plumatic/schema). If you were using this namespace in combination with Schema, you'll + want to update your code to use Malli instead. + +- Another driver feature has been added: `:table-privileges`. This feature signals whether we can store + the table-level privileges for the database on database sync. + +- The multimethod `metabase.driver/current-user-table-privileges` has been added. This method is used to get + the set of privileges the database connection's current user has. It needs to be implemented if the database + supports the `:table-privileges` feature. + +- The following functions in `metabase.query-processor.store` (`qp.store`) are now deprecated + + - `qp.store/database` + - `qp.store/table` + - `qp.store/field` + + Update usages of the to the corresponding functions in `metabase.lib.metadata` (`lib.metadata`): + + ```clj + (qp.store/database) => (lib.metadata/database (qp.store/metadata-provider)) + (qp.store/table table-id) => (lib.metadata/table (qp.store/metadata-provider) table-id) + (qp.store/field field-id) => (lib.metadata/field (qp.store/metadata-provider) field-id) + ``` + + Note that the new methods return keys as `kebab-case` rather than `snake_case`. + +- Similarly, drivers should NOT access the application database directly (via `toucan` functions or otherwise); use + `lib.metadata` functions instead. This access may be blocked in a future release. + +- SQL drivers that implement `metabase.driver.sql.query-processor/->honeysql` for + `metabase.models.table/Table`/`:model/Table` should be updated to implement it for `:metadata/table` instead. As + with the changes above, the main difference is that the new metadata maps use `kebab-case` keys rather than + `snake_case` keys. + +* `metabase.driver.sql.query-processor/cast-field-if-needed` now expects a `kebab-case`d field as returned by + `lib.metadata/field`. + +- `metabase.query-processor.store/fetch-and-store-database!`, + `metabase.query-processor.store/fetch-and-store-tables!`, and + `metabase.query-processor.store/fetch-and-store-fields!` have been removed. Things are now fetched automatically as + needed and these calls are no longer necessary. + +- `metabase.models.field/json-field?` has been removed, use `metabase.lib.field/json-field?` instead. Note that the + new function takes a Field as returned by `lib.metadata/field`, i.e. a `kebab-case` map. + +- Tests should try to avoid using any of the `with-temp` helpers or application database objects; instead, use the + metadata functions above and and the helper _metadata providers_ in `metabase.lib`, `metabase.lib.test-util`, and + `metabase.query-processor.test-util` for mocking them, such as `mock-metadata-provider`, + `metabase-provider-with-cards-for-queries`, `remap-metadata-provider`, and `merged-mock-metadata-provider`. + +- `metabase.query-processor.util.add-alias-info/field-reference` is now deprecated. If your driver implemented it, + implement `metabase.query-processor.util.add-alias-info/field-reference-mlv2` instead. The only difference between + the two is that the latter is passed Field metadata with `kebab-case` keys while the former is passed legacy + metadata with `snake_case` keys. + +- `metabase.driver/current-db-time`, deprecated in 0.34, and related methods and helper functions, have been removed. + Implement `metabase.driver/db-default-timezone` instead. + +- `metabase.driver.sql-jdbc.sync.interface/db-default-timezone`, a helper for writing + `metabase.driver/db-default-timezone` implementations for JDBC-based drivers, has been deprecated, and will be + removed in 0.51.0 or later. You can easily implement `metabase.driver/db-default-timezone` directly, and use + `metabase.driver.sql-jdbc.execute/do-with-connection-with-options` to get a `java.sql.Connection` for a Database. + +- Added a new multimethod `metabase.driver.sql.parameters.substitution/align-temporal-unit-with-param-type`, which returns + a suitable temporal unit conversion keyword for `field`, `param-type` and the given driver. The resulting keyword + will be used to call the corresponding `metabase.driver.sql.query-processor/date` implementation to convert the `field`. + Returns `nil` if the conversion is not necessary for this `field` and `param-type` combination. + +- The multimethod `metabase.driver.sql-jdbc.execute/inject-remark` has been added. It allows JDBC-based drivers to + override the default behavior of how SQL query remarks are added to queries (prepending them as a comment). + +- The arity of multimethod `metabase.driver.sql-jdbc.sync.interface/fallback-metadata-query` has been updated from 3 to 4, + it now takes an additional `db` argument. The new function arguments are: `[driver db-name-or-nil schema table]`. + +## Metabase 0.47.0 + +- A new driver feature has been added: `:schemas`. This feature signals whether the database organizes tables in + schemas (also known as namespaces) or not. Most databases have schemas so this feature is on by default. + An implementation of the multimethod `metabase.driver/database-supports?` for `:schemas` is required only if the + database doesn't store tables in schemas. + +- Another driver feature has been added: `:uploads`. The `:uploads` feature signals whether the database supports + uploading CSV files to tables in the database. To support the uploads feature, implement the following new + multimethods: `metabase.driver/create-table!` (creates a table), `metabase.driver/drop-table!` (drops + a table), and `metabase.driver/insert-into!` (inserts values into a table). + +- The multimethod `metabase.driver/syncable-schemas` has been added. This method is used to list schemas to upload + CSVs to, and it should include all schemas that can be synced. Currently it only needs to be implemented + if the database has schema, and the database supports the `:uploads` feature. + +- The multimethod `metabase.driver/supports?` has been deprecated in favor of `metabase.driver/database-supports?`. + The existing default implementation of `database-supports?` currently calls `supports?`, but it will be removed in + 0.50.0. + +- `metabase.driver.sql-jdbc.execute/connection-with-timezone` has been marked deprecated and is scheduled for removal + in Metabase 0.50.0. The new method `metabase.driver.sql-jdbc.execute/do-with-connection-with-options` replaces it. + Migration to the new method is straightforward. See PR [#22166](https://github.com/metabase/metabase/pull/22166) for + more information. You should use `metabase.driver.sql-jdbc.execute/do-with-connection-with-options` instead of + `clojure.java.jdbc/with-db-connection` or `clojure.java.jdbc/get-connection` going forward. + +- The multimethods `set-role!`, `set-role-statement`, and `default-database-role` have been added. These methods are + used to enable connection impersonation, which is a new feature added in 0.47.0. Connection impersonation allows users + to be assigned to specific database roles which are set before any queries are executed, so that access to tables can + be restricted at the database level instead of (or in conjunction with) Metabase's built-in permissions system. + +- The multimethod `metabase.driver.sql-jdbc.sync.describe-table/get-table-pks` is changed to return a vector instea + of a set. + +- The function `metabase.query-processor.timezone/report-timezone-id-if-supported` has been updated to take an additional + `database` argument for the arity which previously had one argument. This function might be used in the implementation + of a driver's multimethods. + +- `metabase.driver/prettify-native-form` was added to enable driver developers use native form formatting + specific to their driver. For details see the PR [#34991](https://github.com/metabase/metabase/pull/34991). + +## Metabase 0.46.0 + +- The process for building a driver has changed slightly in Metabase 0.46.0. Your build command should now look + something like this: + + ```sh + # Example for building the driver with bash or similar + + # switch to the local checkout of the Metabase repo + cd /path/to/metabase/repo + + # get absolute path to the driver project directory + DRIVER_PATH=`readlink -f ~/sudoku-driver` + + # Build driver. See explanation in sample Sudoku driver README + clojure \ + -Sdeps "{:aliases {:sudoku {:extra-deps {com.metabase/sudoku-driver {:local/root \"$DRIVER_PATH\"}}}}}" \ + -X:build:sudoku \ + build-drivers.build-driver/build-driver! \ + "{:driver :sudoku, :project-dir \"$DRIVER_PATH\", :target-dir \"$DRIVER_PATH/target\"}" + ``` + + Take a look at our [build instructions for the sample Sudoku + driver](https://github.com/metabase/sudoku-driver#build-it-updated-for-build-script-changes-in-metabase-0460) + for an explanation of the command. + + Note that while this command itself is quite a lot to type, you no longer need to specify a `:build` alias in your + driver's `deps.edn` file. + + Please upvote https://ask.clojure.org/index.php/7843/allow-specifying-aliases-coordinates-that-point-projects , + which will allow us to simplify the driver build command in the future. + +- The multimethod `metabase.driver/table-rows-sample` has been added. This method is used in situations where Metabase + needs a limited sample from a table, like when fingerprinting. The default implementation defined in the + `metabase.db.metadata-queries` namespace runs an MBQL query using the regular query processor to produce the sample + rows. This is good enough in most cases, so this multimethod should not be implemented unless really + necessary. Currently, the only case when a special implementation is used is for BigQuery, which does not respect + limit clauses. + +- The multimethod `metabase.driver.sql.query-processor/datetime-diff` has been added. This method is used by + implementations of `->honeysql` for the `:datetime-diff` clause. It is recommended to implement this if you want to + use the default SQL implementation of `->honeysql` for the `:datetime-diff`, which includes validation of argument + types across all units. + +- The multimethod `metabase.query-processor.util.add-alias-info/field-reference` has been added. This method is used + to produce a reference to a field by the `add-alias-info` middleware. (Note that this middleware is optional, + currently it is only used by the SQL and MongoDB drivers.) The default implementation returns the name of the field + instance. It should be overridden if just the name is not a valid a valid reference. For example, MongoDB supports + nested documents and references to nested fields should contain the whole path. See the namespace + `metabase.driver.mongo.query-processor` for an alternative implementation. + +- The multimethod `metabase.driver.sql-jdbc.sync.interface/syncable-schemas` (aliased as + `metabase.driver.sql-jdbc.sync/syncable-schemas`), which was deprecated in 0.43.0, has been removed. Implement + `metabase.driver.sql-jdbc.sync.interface/filtered-syncable-schemas` instead. See 0.43.0 notes below for more + details. + +- The multimethod `metabase.driver/format-custom-field-name`, which was deprecated in 0.42.0, has been removed. + Implement `metabase.driver/escape-alias` instead. See 0.42.0 notes below for more information. + +- The multimethod `metabase.driver.sql-jdbc.execute/read-column`, which was deprecated in 0.35.0, has been removed. + Implement `metabase.driver.sql-jdbc.execute/read-column-thunk` instead. See 0.35.0 notes below for more information. + +### Honey SQL 2 + +The following only applies to SQL drivers; you can ignore it for non-SQL drivers. + +Prior to Metabase 0.46.0, SQL drivers used Honey SQL 1 as an intermediate target when compiling queries. In 0.46.0 we +have began the process of migrating to Honey SQL 2 as our new intermediate target. + +We plan to continue to support use of Honey SQL 1 until Metabase 0.49.0. Please be sure to migrate your drivers before +then. + +In Metabase 0.46.x, 0.47.x, and 0.48.x, you can specify which version of Honey SQL you driver should use by +implementing the `metabase.driver.sql.query-processor/honey-sql-version` multimethod: + +```clj +(require '[metabase.driver.sql.query-processor :as sql.qp]) + +;;; use Honey SQL 2 for :my-driver +(defmethod sql.qp/honey-sql-version :my-driver + [_driver] + 2) +``` + +This method must return either `1` or `2`. Currently, the default implementation returns `1`. Effectively this means +you currently have to opt-in to Honey SQL 2 compilation. It's a good idea to do this sooner rather than later so your +driver is prepared for 0.49.0 well in advance. + +In Metabase 0.47.x or 0.48.x we will likely change the default Honey SQL version to `2` to ensure everyone is aware of +the upcoming breaking changes in 0.49.0 and give them one or two release cycles to update their drivers to target +Honey SQL 2. You will still be able to opt-in to using Honey SQL 1 until 0.49.0 by implementing +`sql.qp/honey-sql-version` and returning `1`. + +#### What You Need to Change + +Our Honey SQL utility namespace, `metabase.util.honeysql-extensions`, commonly aliased as `hx`, has been updated to +generate forms appropriate for either Honey SQL 1 or Honey SQL 2. This is done automatically based on your driver's +`honey-sql-version`. `metabase.driver.sql.query-processor` itself also supports both targets in the same way. + +The actual changes you will need to make to your driver code will probably be fairly small. The most important things +to note when porting your driver: + +1. Avoid use of things from Honey SQL 1 namespaces like `honeysql.core` or `honeysql.format`. If you must, use Honey + SQL `honey.sql` instead; you may not need either. + +2. While you can continue to use `metabase.util.honeysql-extensions` in the short term, since it can target either + version of Honey SQL, we will probably remove this namespace at some point in the future. Update your code to use + `metabase.util.honey-sql-2` instead. The namespaces implement an almost identical set of helper functions, so all + you should need to switch is which one you `:require` in your `ns` form. + +3. `honeysql.core/call` no longer exists; instead of a form like `(hsql/call :my_function 1 2)`, you simply return a + plain vector like `[:my_function 1 2]`. `(hsql/raw "x")` is now`[:raw "x"]`. New handlers can be registered with + Honey SQL 2 with `honey.sql/register-fn!`. There is no equivalent of the Honey SQL 1 `honeysql.format./ToSql` + protocol, so you should no longer define one-off types to implement custom SQL compilation rules. Use + `honey.sql/register-fn!` instead. + +4. In Honey SQL 1 you were able to register functions to a more limited extent by implementing the multimethod + `honeysql.format/fn-handler`. Metabase registered the functions `:extract`, `:distinct-count`, and + `:percentile-cont` in this way. For Honey SQL 2, we've registered these functions as qualified keywords in the + `metabase.util.honey-sql-2` namespace, to prevent confusion as to where they're defined. Thus you'll need to update + the keyword if you're using these functions. + + ```clj + ;;; Honey SQL 1 + (hsql/call :distinct-count expr) + ``` + + becomes + + ```clj + ;;; Honey SQL 2 + (require '[metabase.util.honey-sql-2 :as h2x]) + + [::h2x/distinct-count expr] + ``` + +5. Because custom expressions are now just plain vectors like `[:my_function 1]`, you may need to wrap expressions in + an additional vector if they appear inside `:select`, `:from`, or other places where a vector could be interpreted + as `[expression alias]`. e.g. + + ```clj + ;; Honey SQL 1 + (honeysql.core/format {:select [[:my_function 1]]}) + ;; => ["SELECT my_function AS 1"] + + ;; Honey SQL 2 + ;; + ;; WRONG + (honey.sql/format {:select [[:my_function 1]]}) + ;; => ["SELECT my_function AS ?" 1] + + ;; CORRECT + (honey.sql/format {:select [[[:my_function 1]]]}) + ;; => ["SELECT MY_FUNCTION(?)" 1] + ``` + + The SQL query processor does this automatically for forms it generates, so you only need to worry about this if + you're overriding the way it generates `:select` or other top-level clauses. + +6. Numbers are parameterized by default, e.g. `{:select [1]}` becomes `SELECT ?` rather than `SELECT 1`. You can use + `:inline` to force the SQL to be generated inline instead: `{:select [[[:inline 1]]]}` becomes `SELECT 1`. Numbers + generated by the SQL query processor code should automatically be inlined, but you may need to make sure any + numbers you generate are wrapped in `:inline` if they can end up as expressions inside a `GROUP BY` clause. Some + databases can recognize expressions as being the same thing only when they are _not_ parameterized: + + ```sql + -- This is okay + SELECT x + 1 + FROM table + GROUP BY x + 1 + + -- Bad: DB doesn't know whether the two x + ? expressions are the same thing + SELECT x + ? + FROM table + GROUP BY x + ? + ``` + +Exercise caution when `:inline`ing things -- take care not to use it on untrusted strings or other avenues for SQL +injection. Only inlining things that are a `number?` is a safe bet. + +Please read [Differences between Honey SQL 1.x and +2.x](https://github.com/seancorfield/honeysql/blob/develop/doc/differences-from-1-x.md) for more information on the +differences between the library versions. + +#### Breaking Changes in 0.46.0 related to the Honey SQL 2 transition + +**Note: these breaking changes will hopefully be fixed before 0.46.0 ships. This will be updated if they are.** + +The classes `metabase.util.honeysql_extensions.Identifer` and `metabase.util.honeysql_extensions.TypedHoneySQLForm` +have been moved to `metabase.util.honey_sql_1.Identifer` and `metabase.util.honey_sql_1.TypedHoneySQLForm`, +respectively. On the off chance that your driver directly referencing these class names, you may need to update things +to use the new class names. + +Similarly, `metabase.util.honeysql-extensions/->AtTimeZone` has been removed; use +`metabase.util.honeysql-extensions/at-time-zone` instead. + +## Metabase 0.45.0 + +- `metabase.driver.sql-jdbc.connection/details->connection-spec-for-testing-connection` has been removed in Metabase + 0.45.0, because it leaked SSH tunnels. See [#24445](https://github.com/metabase/metabase/issues/24445). If you are + using this function, please update your code to use + `metabase.driver.sql-jdbc.connection/with-connection-spec-for-testing-connection` instead, which properly cleans up + after itself. + +### New methods + +- `metabase.driver.sql-jdbc.sync.describe-table-fields` has been added. Implement this method if you want to override + the default behavior for fetching field metadata (such as types) for a table. + +- `metabase.driver.sql-jdbc.sync.describe-table/get-table-pks` has been added. This methods is used to get a set of pks + given a table. + +- `->honeysql [ :convert-timezone]` has been added. Implement this method if you want your driver to support + the `convertTimezone` expression. This method takes 2 or 3 arguments and returns a `timestamp without time zone` column. + +## Metabase 0.43.0 + +- The `:expressions` map in an MBQL query now uses strings as keys rather than keywords (see + [#14647](https://github.com/metabase/metabase/issues/14647)). You only need to be concerned with this if you are + accessing or manipulating this map directly. Drivers deriving from `:sql` implementing `->honeysql` for `[ :expression]` may need to be updated. A utility function, `metabase.mbql.util/expression-with-name`, has been + available since at least Metabase 0.35.0 and handles both types of keys. It is highly recommended that you use this + function rather than accessing `:expressions` directly, as doing so can make your driver compatible with both 0.42.0 + and with 0.43.0 and newer. + +- There is now a `describe-nested-field-columns` method under `sql-jdbc.sync` namespace which returns an instance of + NestedFCMetadata. This is in order to allow JSON columns in Postgres and eventually other DB's which are usually + ordinary RDBMS's but then sometimes they have a denormalized column with JSON or some other semantics. Given a table + with denormalized columns which have nested field semantics (so, typed sub-fields which are still denormalized but + stable in type between rows), return value should be a NestedFCMetadata, a map of flattened key paths to the + detected sub-field. Field detection in syncing will then be enriched with those nested types. This is materially + different from the way we do it for mongo because every kind of JSON column is different, but it's going to run + every sync so it can't be too slow, even on enormous tables and enormous denormalized columns on those enormous tables. + +## Metabase 0.42.0 + +Changes in Metabase 0.42.0 affect drivers that derive from `:sql` (including `:sql-jdbc`). +Non-SQL drivers likely will require no changes. + +0.42.0 introduces several significant changes to the way the SQL query processor compiles and determines aliases for +MBQL `:field` clauses. For more background, see pull request +[#19384](https://github.com/metabase/metabase/pull/19384). + +If you were manipulating Field or Table aliases, we consolidated a lot of overlapping vars and methods, which means you may need to delete deprecated method implementations. + +### Significant changes + +- The `metabase.driver.sql.query-processor/->honeysql` method for Field instances, e.g. + + ```clj + (defmethod sql.qp/->honeysql [:my-driver (class Field)] + [driver field] + ...) + ``` + + is no longer invoked. All compilation is now handled by the MBQL `:field` clause method, e.g. + + ```clj + (defmethod sql.qp/->honeysql [:my-driver :field] + [driver field-clause] + ...) + ``` + + If you were doing something special here, you'll need to move that special login into `[ :field]` instead. + (You may no longer need this special logic, however -- see below.) + +- `:field`, `:expression`, and `:aggregation-options` clauses now contain information about what aliases you should + use to refer to them on both the left-hand side and right-hand side of SQL `AS` or elsewhere in a query. See PR + [#19610](https://github.com/metabase/metabase/pull/19610) for a detailed discussion about the new information, + hereafter referred to as the /[#19610 information](https://github.com/metabase/metabase/pull/19610)/. + +- If you have a custom implementation of `->honeysql` for `:field` or `(class Field)`: `->honeysql` methods for `:field` should use or replace the + [#19610 information](https://github.com/metabase/metabase/pull/19610) rather than attempting to determine or + override it in some other fashion. + +### New methods + +- `metabase.driver/escape-alias` (moved from `metabase.driver.sql.query-processor/escape-alias`, which was introduced + in 0.41.0) is now used to generate the [#19610 information](https://github.com/metabase/metabase/pull/19610) and + used consistently across the SQL QP code. If you need to transform generated Field aliases for any reason (such as + escaping disallowed characters), implement this method. + +- `metabase.driver.sql-jdbc.sync.interface/filtered-syncable-schemas` has been added, and will eventually replace + `metabase.driver.sql-jdbc.sync.interface/syncable-schemas`. It serves a similar purpose, except that it's also + passed the inclusion and exclusion patterns (ex: `auth*,data*`) to further filter schemas that will be synced. + +### Deprecated methods and vars + +The following methods and vars are slated for removal in Metabase 0.45.0 unless otherwise noted. + +- `metabase.driver/format-custom-field-name` is now unused. Implement `metabase.driver/escape-alias` instead. + +- `metabase.driver.sql.query-processor/escape-alias` has been renamed to `metabase.driver/escape-alias`. Everything + else is the same. + +- `metabase.driver.sql.query-processor/field-clause->alias` no longer uses the optional parameter `unique-name-fn`. + Aliases are now made unique automatically, after escaping them; implement `metabase.driver/escape-alias` if you need + to do something special before they are made unique. (Unique aliases are also escaped a second time if you need to + do something /really/ special.) + +- `metabase.driver.sql.query-processor/field->alias`, which was deprecated in 0.41.0, is now unused in 0.42.0. + Implementing this method no longer has any effect. Implement `metabase.driver/escape-alias` instead if you need to + do something special; use the [#19610 information](https://github.com/metabase/metabase/pull/19610) if you need to escape the alias + for one reason or another. This method is still slated for removal in Metabase 0.44.0. + +- `metabase.driver.sql.query-processor/*field-options*` is now unused and is no longer bound automatically. If you need field options for some reason, see our SQL Server driver for an example on how to create it. + +- `metabase.driver.sql.query-processor/*table-alias*` is now unused and is no longer bound automatically. Use or + override `:metabase.query-processor.util.add-alias-info/source-table` from the [#19610 + information](https://github.com/metabase/metabase/pull/19610) instead. + +- `metabase.driver.sql.query-processor/*source-query*` is now unused and is no longer bound automatically. Use + `metabase.driver.sql.query-processor/*inner-query*` instead, which is always bound, even if we aren't inside of a + source query. + +- `metabase.driver.sql.query-processor/field->identifier` is now unused. Implementing this method should no longer be + necessary under any circumstances. Override `->honeysql` for `[ :field]` and manipulate the [#19610 + information](https://github.com/metabase/metabase/pull/19610) if you need to do something special here. + +- `metabase.driver.sql.query-processor/prefix-field-alias` is no longer used. Previously, it was made available to + give drivers a chance to escape automatically generated aliases for joined Fields. This is no longer necessary, + because `metabase.driver/escape-alias` is called on automatically generates aliases. Implement + `metabase.driver/escape-alias` if you need to do something special. +- `metabase.driver.sql-jdbc.sync.interface/syncable-schemas` has been deprecated in favor of + `metabase.driver.sql-jdbc.sync.interface/filtered-syncable-schemas` (see above). The existing default implementation + of `syncable-schemas` currently calls `filtered-syncable-schemas` (with `nil` filters, i.e. the filtering operation + is actually a no-op), but it will eventually be removed. + +#### Removed Methods and Vars + +- `metabase.mbql.schema/DatetimeFieldUnit`, deprecated in 0.39.0, is now removed. + +## Older versions + +Before 0.42.0, this information was tracked in our Wiki. You can find changes for versions before 0.42.0 in the +table below: + +| Version | Wiki page | +| ------- | ----------------------------------------------------------------------------------------------------- | +| 0.41.0 | [changes](https://github.com/metabase/metabase/wiki/What's-new-in-0.41.0-for-Metabase-driver-authors) | +| 0.40.0 | No changes. | +| 0.39.0 | No changes. | +| 0.38.0 | [changes](https://github.com/metabase/metabase/wiki/What's-new-in-0.38.0-for-Metabase-driver-authors) | +| 0.37.0 | [changes](https://github.com/metabase/metabase/wiki/What's-new-in-0.37.0-for-Metabase-driver-authors) | +| 0.36.0 | [changes](https://github.com/metabase/metabase/wiki/What's-new-in-0.36.0-for-Metabase-driver-authors) | +| 0.35.0 | [changes](https://github.com/metabase/metabase/wiki/What's-new-in-0.35.0-for-Metabase-driver-authors) | diff --git a/_docs/doc-update-detection/developers-guide/drivers/basics.md b/_docs/doc-update-detection/developers-guide/drivers/basics.md new file mode 100644 index 000000000..7a3f80309 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/drivers/basics.md @@ -0,0 +1,78 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Database driver basics' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/drivers/basics.md' +--- + +# Database driver basics + +A Metabase driver: + +- **Provides Metabase with basic information for the database** such as the database's capabilities, connection properties, and so on. +- **Provides Metabase with information about the schema of the database** -- the tables (or equivalent), the fields in those tables, the foreign key relationships (for databases that support foreign keys). + - This functionality is used by the Metabase _sync process_ and stored in the application database. + - The stored information is used in the visual Query Builder and other places to show users what tables/columns/etc. are available +- **Compiles our in-house query language, [MBQL](https://github.com/metabase/metabase/wiki/Query-Language-'98), into native queries.** + - MBQL queries are generated by the visual query builder. + - The Metabase **query processor\*** converts MBQL queries to native queries +- **Executes native queries and returns results**. + +## Write your driver as a module and package it as a plugin + +Metabase drivers are organized into modules and packaged as plugins. Modules are the source code; plugins are the JARs built from that source code. + +A Metabase plugin is a JAR file that contains the compiled class files and a Metabase [plugin manifest](plugins) that lists details about the driver. In most cases, plugins are lazily loaded, which means that Metabase won't initialize the drivers until it connects to a database that would use the driver. + +For Metabase to use your driver, all you need to do is put the driver JAR you built into the `/plugin` directory, which you'll find in the same directory where you run your metabase.jar. Something like this: + +``` +/Users/cam/metabase/metabase.jar +/Users/cam/metabase/plugins/my-plugin.jar +``` + +You can change the plugin directory by setting the [environment variable][env-var] `MB_PLUGINS_DIR`. + +## Example module directory + +Let's take a high-level look at the [SQLite driver](https://github.com/metabase/metabase/tree/master/modules/drivers/sqlite): + +``` +|-- deps.edn +|-- resources +| `-- metabase-plugin.yaml +|-- src +| `-- metabase +| `-- driver +| `-- sqlite.clj +`-- test + `-- metabase + |-- driver + | `-- sqlite_test.clj + `-- test + `-- data + `-- sqlite.clj +``` + +There are three files to call out here: + +### `deps.edn` + +The `deps.edn` file specifies the driver's dependencies. + +### `resources/metabase-plugin.yaml` + +Your driver's [manifest](plugins#plugin-manifests) includes details about your driver. + +### `src/metabase/driver/sqlite.clj` + +This is the core file for your driver. We'll talk more about it in [Implementing multimethods](multimethods). + +## Next Up + +We'll learn more about [plugin manifests](plugins). + +[env-var]: ../../configuring-metabase/environment-variables diff --git a/_docs/doc-update-detection/developers-guide/drivers/driver-tests.md b/_docs/doc-update-detection/developers-guide/drivers/driver-tests.md new file mode 100644 index 000000000..d38a853d7 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/drivers/driver-tests.md @@ -0,0 +1,244 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Submitting a PR for a new driver' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/drivers/driver-tests.md' +--- + +# Submitting a PR for a new driver + +If you want to submit a PR to add a driver plugin to the [Metabase repo](https://github.com/metabase/metabase) (as opposed to keeping it in a separate repo), you'll need to: + +- Be able to run your database locally with Docker. +- Make sure your driver passes Metabase's core test suite. + +## Testing your driver + +To test your driver, you'll need to: + +- Move your plugin into the [`modules/drivers`](https://github.com/metabase/metabase/tree/master/modules/drivers) directory in the Metabase repository. +- Add _test extensions_ to your driver. +- Edit [`.github/workflows/drivers.yml`](https://github.com/metabase/metabase/blob/master/.github/workflows/drivers.yml) to tell GitHub Actions how to set up a Docker image for your database and run tests against it. + +## Add test extensions to your driver + +Test extensions do things like create new databases and load data for given _database definitions_. Metabase defines a huge suite of tests that automatically run against all drivers, including your new driver. + +To run the test suite with your driver, you'll need to write a series of method implementations for special _test extension_ multimethods. Test extensions do things like create new databases and load data for _database definitions_. + +These test extensions will tell Metabase how to create new databases and load them with test data, and provide information about what Metabae can expect from the created database. Test extensions are simply additional multimethods used only by tests. Like the core driver multimethods, they dispatch on the driver name as a keyword, e.g. `:mysql`. + +## File organization + +Test extensions for a driver usually live in a namespace called `metabase.test.data.`. If your driver is for SQLite, your files should look something like: + +```clj +metabase/modules/drivers/sqlite/deps.edn ; <- deps go in here +metabase/modules/drivers/sqlite/resources/metabase-plugin.yaml ; <- plugin manifest +metabase/modules/drivers/sqilte/src/metabase/driver/sqlite.clj ; <- main driver namespace +``` + +So you'll create a new directory and file to house your text extension method implementations. + +```clj +metabase/modules/drivers/sqlite/test/metabase/test/data/sqlite.clj ; <- test extensions +``` + +## Where are test extension methods defined? + +Metabase test extensions live in the [`metabase.test.data.interface`](https://github.com/metabase/metabase/blob/master/test/metabase/test/data/interface.clj) namespace. Like the core driver methods, `:sql` and `:jdbc-sql` implement some of the test extensions themselves, but define additional methods you must implement to use them; see the [`metabase.test.data.sql`](https://github.com/metabase/metabase/blob/master/test/metabase/test/data/sql.clj) +and [`metabase.test.data.sql-jdbc`](https://github.com/metabase/metabase/blob/master/test/metabase/test/data/sql_jdbc.clj) namespaces. + +You'll need to require the following namespaces, aliased like so: + +```clj +(require '[metabase.test.data.interface :as tx]) ; tx = test extensions +(require '[metabase.test.data.sql :as sql.tx]) ; sql test extensions +(require '[metabase.test.data.sql-jdbc :as sql-jdbc.tx]) +``` + +## Registering test extensions + +Like the driver itself, you need to register the fact that your driver has test extensions, so Metabase knows it doesn't need to try to load them a second time. (If they're not loaded yet, Metabase will load them when needed by looking for a namespace named `metabase.test.data.`, which is why you need to follow that naming pattern.) The `:sql` and `:sql-jdbc` drivers have their own sets of test extensions, so depending on which parent you're using for your driver, register test extensions with: + +```clj +# Non-SQL drivers +(tx/add-test-extensions! :mongo) + +# non-JDBC SQL +(sql/add-test-extensions! :bigquery) + +# JDBC SQL +(sql-jdbc.tx/add-test-extensions! :mysql) +``` + +You only need one call -- there's no need to do all three for a `:sql-jdbc` driver. This call should go at the beginning of your test extension namespace, like this: + +```clj +(ns metabase.test.data.mysql + (:require [metabase.test.data.sql-jdbc :as sql-jdbc.tx])) + +(sql-jdbc.tx/register-test-extensions! :mysql) +``` + +## Anatomy of a Metabase test + +Let's look at an real-life Metabase test so we can understand how it works and what exactly we need to do to power it: + +```clj +;; expect-with-non-timeseries-dbs = run against all drivers listed in `DRIVERS` env var except timeseries ones like Druid +(expect-with-non-timeseries-dbs + ;; expected results + [[ 5 "Brite Spot Family Restaurant" 20 34.0778 -118.261 2] + [ 7 "Don Day Korean Restaurant" 44 34.0689 -118.305 2] + [17 "Ruen Pair Thai Restaurant" 71 34.1021 -118.306 2] + [45 "Tu Lan Restaurant" 4 37.7821 -122.41 1] + [55 "Dal Rae Restaurant" 67 33.983 -118.096 4]] + ;; actual results + (-> (data/run-mbql-query venues + {:filter [:ends-with $name "Restaurant"] + :order-by [[:asc $id]]}) + rows formatted-venues-rows)) +``` + +Let's say we launch tests with + +``` +DRIVERS=mysql clojure -X:dev:drivers:drivers-dev:test`. +``` + +1. Metabase will check and see if test extensions for `:mysql` are loaded. If not, it will `(require 'metabase.test.data.mysql)`. +2. Metabase will check to see if the default `test-data` database has been created for MySQL, loaded with data, and synced. If not, it will call the test extension method `tx/load-data!` to create the `test-data` database and load data into it. After loading the data, Metabase syncs the test database. (This is discussed in more detail below.) +3. Metabase runs an MBQL query against the `venues` table of the MySQL `test-data` database. The `run-mbql-query` macro is a helper for writing tests that looks up Field IDs based on names for symbols that have `$` in from of them. Don't worry too much about that right now; just know the actual query that is ran will look something like: + ```clj + {:database 100 ; ID of MySQL test-data database + :type :query + :query {:source-table 20 ; Table 20 = MySQL test-data.venues + :filter [:ends-with [:field-id 555] "Restaurant"] ; Field 555 = MySQL test-data.venues.name + :order-by [[:asc [:field-id 556]]]}} ; Field 556 = MySQL test-data.venues.id + ``` +4. The results are ran through helper functions `rows` and `formatted-venues-rows` which return only the parts of the query results we care about +5. Those results are compared against the expected results. + +That's about as much as you'd need to know about the internals of how Metabase tests work; now that we've covered that, let's take a look at how we can empower Metabase to do what it needs to do. + +## Loading Data + +In order to ensure consistent behavior across different drivers, the Metabase test suite creates new databases and load datas into them from a set of shared _Database Definitions_. That means whether we're running a test against MySQL, Postgres, SQL Server, or MongoDB, a single test can check that we get the exact same results for every driver! + +Most of these database definitions live in [EDN](https://github.com/edn-format/edn) files; the majority of tests run against a test database named "test data", whose definition can be found [here](https://github.com/metabase/metabase/blob/master/test/metabase/test/data/dataset_definitions/test-data.edn). Take a look at that file -- it's just a simple set of tables names, column names and types, and then a few thousand rows of data to load into those tables. + +Like test extension method definitions, schemas for `DatabaseDefinition` live in [`metabase.test.data.interface`](https://github.com/metabase/metabase/blob/master/test/metabase/test/data/interface.clj) -- you can take a look and see exactly what a database definition is supposed to look like. + +**Your biggest job as a writer of test definitions is to write the methods needed to take a database definition, create a new database with the appropriate tables and columns, and load data into it.** For non-SQL drivers, you'll need to implement `tx/load-data!`; `:sql` and `:sql-jdbc` have a shared implementation used by child drivers, but define their own set of test extension methods. For example, `:sql` (and `:sql-jdbc`) will handle the DDL statements for creating tables, but need to know what type it should use for the primary key, so you'll need to implement `sql.tx/pk-sql-type`: + +```clj +(defmethod sql.tx/pk-sql-type :mysql [_] "INTEGER NOT NULL AUTO_INCREMENT") +``` + +I'd like to document every single test extension method in detail here, but until I find the time to do that, the methods are all documented in the codebase itself; take a look at the appropriate test extension namespaces and see which methods you'll need to implement. You can also refer to the test extensions written for other similar drivers to get a picture of what exactly it is you need to be doing. + +## Connection Details + +Of course, Metabase also needs to know how it can connect to your newly created database. Specifically, it needs to know what it should save as part of the connection `:details` map when it saves the newly created database as a `Database` object. All drivers with test extensions need to implement `tx/dbdef->connection-details` to return an appropriate set of `:details` for a given database definition. For example: + +```clj +(defmethod tx/dbdef->connection-details :mysql [_ context {:keys [database-name]}] + (merge + {:host (tx/db-test-env-var :mysql :host "localhost") + :port (tx/db-test-env-var :mysql :port 3306) + :user (tx/db-test-env-var :mysql :user "root") + ;; :timezone :America/Los_Angeles + :serverTimezone "UTC"} + (when-let [password (tx/db-test-env-var :mysql :password)] + {:password password}) + (when (= context :db) + {:db database-name}))) +``` + +Let's take a look at what's going on here. + +### Connection context + +`tx/dbdef->connection-details` is called in two different contexts: + +- When creating a database, +- And when loading data into one and syncing. + +Most databases won't let you connect to a database that hasn't been created yet, meaning something like a `CREATE DATABASE "test-data";` statement would have to be ran _without_ specifying `test-data` as part of the connection. Thus, the `context` parameter. `context` is either `:server`, meaning "give me details for connecting to the DBMS server, but not to a specific database", or `:db`, meaning "give me details for connecting to a specific database". In MySQL's case, it adds the `:db` connection property whenever context is `:db`. + +### Getting connection properties from env vars + +You'll almost certainly be running your database in a local Docker container. Rather than hardcode the connection details (the username, host, port...) for the Docker container, we'd like to be flexible, and let people specify those in environment variables, in case they're running against a different container or are just running the database outside of a container, or on another computer entirely. You can use `tx/db-test-env-var` to get details from environment variables. For example, + +```clj +(tx/db-test-env-var :mysql :user "root") +``` + +Tells Metabase to look for the environment variable `MB_MYSQL_TEST_USER`; if not found, default to `"root"`. The name of the environment variable follows the pattern `MB__TEST_`, as passed into the function as first and second args, respectively. You don't need to specify a default value for `tx/db-test-env-var`; perhaps `user` is an optional parameter; and if `MB_MYSQL_TEST_USER` isn't specified, you don't need to specify it in the connection details. + +But what about properties you want to require, but do not have sane defaults? In those cases, you can use `tx/db-test-env-var-or-throw`. It the corresponding enviornment variable isn't set, these will throw an Exception, ultimately causing tests to fail. + +```clj +;; If MB_SQLSERVER_TEST_USER is unset, the test suite will quit with a message saying something like +;; "MB_SQLSERVER_TEST_USER is required to run tests against :sqlserver" +(tx/db-test-env-var-or-throw :sqlserver :user) +``` + +Note that `tx/dbdef->connection-details` won't get called in the first place for drivers you aren't running tests against (i.e., drivers not listed in the `DRIVERS` env var), so you wouldn't see that SQL Server error message when running tests against Mongo, for example. + +Besides `tx/db-test-env-var`, `metabase.test.data.interface` has several other helpful utility functions. Take a good look at that namespace as well as `metabase.test.data.sql` if your database uses SQL and `metabase.test.data.sql-jdbc` if your database uses a JDBC driver. + +## Other Test Extensions + +There's a few other things Metabase needs to know when comparing test results. For example, different databases name tables and columns in different ways; methods exist to let Metabase know it should expect something like the `venues` table in the `test-data` Database Definition to come back as `VENUES` for a database that uppercases everything. (We consider such minor variations in naming to still mean the same thing.) Take a look at `tx/format-name` and other methods like that and see which ones you need to implement. + +## What about DBMSes that don't let you create new databases programatically? + +This is actually a common problem, and luckily we have figured out how to work around it. The solution is usually something like using different _schemas_ in place of different databases, or prefixing table names with the database name, and creating everything in the same database. For SQL-based databases, you can implement `sql.tx/qualified-name-components` to have tests use a different identifier instead of what they would normally use, for example `"shared_db"."test-data_venues".id` instead of `"test-data".venues.id`. The SQL Server and Oracle test extensions are good examples of such black magic in action. + +## Setting up CI + +Once you have all the tests passing, you'll need to set up GitHub Actions to run those tests against your driver. You'll need to add a new job to [`.github/workflows/drivers.yml`](https://github.com/metabase/metabase/blob/master/.github/workflows/drivers.yml) to run tests against your database. + +Here is an example configuration for PostgreSQL. + +```yaml +be-tests-postgres-latest-ee: + needs: files-changed + if: github.event.pull_request.draft == false && needs.files-changed.outputs.backend_all == 'true' + runs-on: ubuntu-22.04 + timeout-minutes: 60 + env: + CI: "true" + DRIVERS: postgres + MB_DB_TYPE: postgres + MB_DB_PORT: 5432 + MB_DB_HOST: localhost + MB_DB_DBNAME: circle_test + MB_DB_USER: circle_test + MB_POSTGRESQL_TEST_USER: circle_test + MB_POSTGRES_SSL_TEST_SSL: true + MB_POSTGRES_SSL_TEST_SSL_MODE: verify-full + MB_POSTGRES_SSL_TEST_SSL_ROOT_CERT_PATH: "test-resources/certificates/us-east-2-bundle.pem" + services: + postgres: + image: circleci/postgres:latest + ports: + - "5432:5432" + env: + POSTGRES_USER: circle_test + POSTGRES_DB: circle_test + POSTGRES_HOST_AUTH_METHOD: trust + steps: + - uses: actions/checkout@v4 + - name: Test Postgres driver (latest) + uses: ./.github/actions/test-driver + with: + junit-name: "be-tests-postgres-latest-ee" +``` + +For more on what it is you're doing here and how all this works, see [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions). diff --git a/_docs/doc-update-detection/developers-guide/drivers/multimethods.md b/_docs/doc-update-detection/developers-guide/drivers/multimethods.md new file mode 100644 index 000000000..af9297e36 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/drivers/multimethods.md @@ -0,0 +1,147 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Implementing multimethods for your driver' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/drivers/multimethods.md' +--- + +# Implementing multimethods for your driver + +Implementing multimethods lets you take advantage of Metabase's existing driver code by extending those methods to work for your particular database. + +Let's first focus on the main driver file for our Fox Pro '98 `src/metabase/driver/foxpro98.clj`. Take a look at this sample code: + +```clj +;; Define a namespace for the driver +(ns com.mycompany.metabase.driver.foxpro98 + (:require [metabase.driver :as driver])) + +;; Can you include a different method here as an example? +(defmethod driver/display-name :foxpro98 [_] + "Visual FoxPro '98") +``` + +Let's walk through each code block. + +## Driver namespaces + +``` +;; Define a namespace for the driver +(ns com.mycompany.metabase.driver.foxpro98 + (:require [metabase.driver :as driver])) +``` + +### Each Metabase driver lives in its own namespace + +In this case, the namespace is`com.mycompany.metabase.driver.foxpro98`. +All core Metabase drivers live in `metabase.driver.` namespaces. It's probably best to use names that follow the [Java package naming conventions](https://en.wikipedia.org/wiki/Java_package#Package_naming_conventions). + +### Many drivers are further broken out into additional namespaces + +Especially larger drivers. Commonly, a driver will have a `query-processor` namespace (e.g., `com.mycompany.metabase.driver.foxpro98.query-processor`) that contains the logic for converting MBQL queries (queries built using Metabase's graphical query builder) into native queries (like SQL). The query processor is often the most complicated part of a driver, so keeping that logic separate can help make things easier to work with. Some drivers also have a separate `sync` namespace that has implementations for methods used by Metabase's [database synchronization](../../databases/sync-scan). + +## Driver initialization + +All drivers can include additional code to be executed once (and only once) using `metabase.driver/initialize!` when Metabase initializes the driver, that is, before the driver establishes a connection to a database for the first time. (In fact, Metabase uses `metabase.driver/initialize!` to lazy-load the driver.) There are only a few cases where you should use `metabase.driver/initialize`, such as allocating resources or setting certain system properties. + +## `metabase.driver` multimethods + +The [`metabase.driver` namespace](https://github.com/metabase/metabase/blob/master/src/metabase/driver.clj) defines a series of [multimethods](https://clojure.org/reference/multimethods), and drivers provide implementations for them, as in our example: + +```clj +(defmethod driver/display-name :foxpro98 [_] + "Visual FoxPro '98") +``` + +The four main features of a Metabase driver described above are all implemented by multimethods. These methods dispatch on the driver's keyword, `:foxpro98` in our case. In fact, that's all a Metabase driver is -- a keyword! There are no classes or objects to be seen -- just a single keyword. + +You can browse the [`metabase.driver` namespace](https://github.com/metabase/metabase/blob/master/src/metabase/driver.clj) for a complete list of multimethods that you could implement. Read the docstring for each method and decide whether you need to implement it. Most methods are optional. + +## Listing the available driver multimethods + +To quickly look up a list of all driver multimethods, you can run the command + +``` +clojure -M:run driver-methods +``` + +which will print a list of all driver namespaces and multimethods. This includes many things like `sql` and `sql-jdbc` multimethods, as well as test extension multimethods. + +If you want to see the docstrings for the methods as well, run: + +``` +clojure -M:run driver-methods docs +``` + +## Parent drivers + +Many drivers share implementation details, and writing complete implementations for sync methods and the like would involve a lot of duplicate code. Thus **many high-level features are partially or fully implemented in shared "parent" drivers**, such as the most common parent, `:sql-jdbc`. A "parent" driver is analogous to a superclass in object-oriented programming. + +You can define a driver parent by listing the parent in the [plugin manifest](plugins). + +Parents like `:sql-jdbc` are intended as a common abstract "base class" for drivers that can share much of their implementation; in the case of `:sql-jdbc`, it's intended for SQL-based drivers that use a JDBC driver under the hood.`:sql-jdbc` and other parents provide implementations for many of the methods needed to power the four main features of a Metabase driver. In fact, `:sql-jdbc` provides implementations of things like `driver/execute-prepared-statement!`, so a driver using it as a parent does not need to provide one itself. However, various parent drivers define their own multimethods to implement. + +## Notable parent drivers + +These parents are kind of a big deal. + +- `:sql-jdbc` can be used as the parent for SQL-based databases with a JDBC driver. + - `:sql-jdbc` implements most of the four main features, but instead you must implement `sql-jdbc` multimethods found in `metabase.driver.sql-jdbc.*` namespaces, as well as some methods in `metabase.driver.sql.*` namespaces. +- `:sql` is itself the parent of `:sql-jdbc`; it can be used for SQL-based databases that _do not_ have a JDBC driver, such as BigQuery. + - `:sql` implements a significant chunk of driver functionality, but you must implement some methods found in `metabase.driver.sql.*` namespaces to use it. +- Some drivers use other "concrete" drivers as their parent -- for example, `:redshift` uses `:postgres` as a parent, only supplying method implementations to override postgres ones where needed. + +### Calling parent driver implementations + +You can get a parent driver's implementation for a method by using `get-method`: + +```clj +(defmethod driver/mbql->native :bigquery [driver query] + ((get-method driver/mbql-native :sql) driver query)) +``` + +This is the equivalent of calling `super.someMethod()` in object-oriented programming. + +You must pass the driver argument to the parent implementation as-is so any methods called by that method used the correct implementation. Here's two ways of calling parents that you should avoid: + +```clj +(defmethod driver/mbql->native :bigquery [_ query] + ;; BAD! If :sql's implementation of mbql->native calls any other methods, it won't use the :bigquery implementation + ((get-method driver/mbql->native :sql) :sql query)) +``` + +also avoid: + +```clj +(defmethod driver/mbql->native :bigquery [_ query] + ;; BAD! If someone else creates a driver using :bigquery as a parent, any methods called by :sql's implementation + ;; of mbql->native will use :bigquery method implementations instead of custom ones for that driver + ((get-method driver/mbql->native :sql) :bigquery query)) +``` + +### Multiple parents + +Astute readers may have noticed that BigQuery is mentioned as having both `:sql` and `:google` as a parent. This multiple inheritance is allowed and helpful! You can define a driver with multiple parents as follows: + +```clj +(driver/register! :bigquery, :parent #{:sql :google}) +``` + +In some cases, both parents may provide an implementation for a method; to fix this ambiguity, simply provide an implementation for your driver and pass them to the preferred parent driver's implementation as described above. + +For drivers shipped as a plugin, you'll register methods in the plugin manifest. + +## Working with the driver from the REPL and in CIDER + +Having to install `metabase-core` locally and build driver uberjars would be obnoxious, especially if you had to repeat it to test every change. Luckily, you can run commands as if everything was part of one giant project: + +To start a REPL. + +```bash +clojure -A:dev:drivers:drivers-dev +``` + +You'll need to rebuild the driver and install it in your `./plugins` directory, and restart Metabase when you make changes. diff --git a/_docs/doc-update-detection/developers-guide/drivers/plugins.md b/_docs/doc-update-detection/developers-guide/drivers/plugins.md new file mode 100644 index 000000000..747916146 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/drivers/plugins.md @@ -0,0 +1,230 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Plugin manifests' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/drivers/plugins.md' +--- + +# Plugin manifests + +Metabase plugin JARs contain a _plugin manifest_ -- a top-level file named `metabase-plugin.yaml`. When Metabase launches, it iterates over every JAR in the plugins directory, and looks for the manifest in each. This manifest tells Metabase what the plugin provides and how to initialize it. + +## Example manifest + +```yaml +info: + name: Metabase SQLite Driver + version: 1.0.0-SNAPSHOT-3.25.2 + description: Allows Metabase to connect to SQLite databases. +contact-info: + name: Toucan McBird + address: toucan.mcbird@example.com +driver: + name: sqlite + display-name: SQLite + lazy-load: true + parent: sql-jdbc + connection-properties: + - name: db + display-name: Filename + placeholder: /home/camsaul/toucan_sightings.sqlite + required: true +init: + - step: load-namespace + namespace: metabase.driver.sqlite + - step: register-jdbc-driver + class: org.sqlite.JDBC +``` + +The `driver` section tells Metabase that the plugin defines a driver named `:sqlite` that has `:sql-jdbc` as a parent. Metabase's plugin system uses these details to call `driver/register!`. The plugin also lists the display name and connection properties for the driver, which Metabase's plugin system uses to creates implementations for `driver/display-name` and `driver/connection-properties`. + +## Lazy loading + +The driver in the [example above](#example-manifest) is listed as `lazy-load: true`, which means that, while the method implementation mentioned above are created when Metabase launches, Metabase won't initialize the driver until the first time someone attempts to connect to a database that uses that driver. + +You _can_ (but shouldn't) set a driver to `lazy-load: false`, as this will make Metabase take longer to launch and eat up more memory. + +## Plugin initialization + +Metabase will initialize plugins automatically as needed. Initialization goes something like this: Metabase adds the driver to the classpath, then it performs each `init` section of the plugin manifest, in order. In the [example manifest above](#example-manifest), there are two steps, a `load-namespace` step, and a `register-jdbc-driver` step: + +```yaml +init: + - step: load-namespace + namespace: metabase.driver.sqlite + - step: register-jdbc-driver + class: org.sqlite.JDBC +``` + +## Loading namespaces + +You'll need to add one or more `load-namespace` steps to your driver manifest to tell Metabase which namespaces contain your driver method implementations. In the example above, the namespace is `metabase.driver.sqlite`. `load-namespace` calls `require` the [normal Clojure way](https://clojuredocs.org/clojure.core/require), meaning it will load other namespaces listed in the `:require` section of its namespace declaration as needed. If your driver's method implementations are split across multiple namespaces, make sure they'll get loaded as well -- you can either have the main namespace handle this (e.g., by including them in the `:require` form in the namespace declaration) or by adding additional `load-namespace` steps. + +For some background on namespaces, see [Clojure namespaces](https://clojure.org/guides/learn/namespaces). + +## Registering JDBC Drivers + +Drivers that use a JDBC driver under the hood will need to add a `register-jdbc-driver` step as well. + +The if-you're-interested reason is that Java's JDBC `DriverManager` won't use JDBC drivers loaded with something other than the system `ClassLoader`, which effectively only means `Drivermanager` will only use JDBC driver classes that are packaged as part of the core Metabase uberjar. Since the system classloader doesn't allow you to load the classpath at runtime, Metabase uses a custom `ClassLoader` to initialize plugins. To work around this limitation, Metabase ships with a JDBC proxy driver class that can wrap other JDBC drivers. When Metabase calls `register-jdbc-driver`, Metabase actually registers a new instance of the proxy class that forwards method calls to the actual JDBC driver. `DriverManager` is perfectly fine with this. + +## Building the driver + +To build a driver as a plugin JAR, check out the [Build-driver scripts README](https://github.com/metabase/metabase/tree/master/bin/build-drivers.md). + +Place the JAR you built in your Metabase's `/plugins` directory, and you're off to the races. + +## The Metabase plugin manifest reference + +Here's an example plugin manifest with comments to get you started on writing your own. + +```txt +# Basic user-facing information about the driver goes under the info: key +info: + + # Make sure to give your plugin a name. In the future, we can show + # this to the user in a 'plugin management' admin page. + name: Metabase SQLite Driver + + # For the sake of consistency with the core Metabase project you + # should use semantic versioning. It's not a bad idea to include the + # version of its major dependency (e.g., a JDBC driver) when + # applicable as part of the 'patch' part of the version, so we can + # update dependencies and have that reflected in the version number + # + # For now core Metabase modules should have a version + # 1.0.0-SNAPSHOT-x until version 1.0 ships and the API for plugins + # is locked in + version: 1.0.0-SNAPSHOT-3.25.2 + + # Describe what your plugin does. Not used currently, but in the + # future we may use this description in a plugins admin page. + description: Allows Metabase to connect to SQLite databases. + +# You can list any dependencies needed by the plugin by specifying a +# list of dependencies. If all dependencies are not met, the plugin +# will not be initialized. +# +# A dependency may be either a 'class' or (in the future) a 'plugin' dependency +dependencies: + + # A 'class' dependency checks whether a given class is available on + # the classpath. It doesn't initialize the class; Metabase defers initialization + # until it needs to use the driver + # Don't use this for classes that ship as part of the plugin itself; + # only use it for external dependencies. + - class: oracle.jdbc.OracleDriver + + # You may optionally add a message that will be displayed for + # information purposes in the logs, and possibly in a plugin + # management page as well in the future + message: > + Metabase requires the Oracle JDBC driver to connect to JDBC databases. See + https://metabase.com/docs/latest/administration-guide/databases/oracle.html + for more details + + # A 'plugin' dependency checks whether a given plugin is available. + # The value for 'plugin' is whatever that plugin has as its 'name:' -- make + # sure you match it exactly! + # + # If the dependency is not available when this module is first loaded, the module + # will be tried again later after more modules are loaded. This means things will + # still work the way we expect even if, say, we initially attempt to load the + # BigQuery driver *before* loading its dependency, the shared Google driver. Once + # the shared Google driver is loaded, Metabase will detect that BigQuery's + # dependencies are now satisfied and initialize the plugin. + # + # In the future, we'll like add version restrictions as well, but for now we only match + # by name. + - plugin: Metabase SQLHeavy Driver + +# If a plugin adds a driver it should define a driver: section. +# +# To define multiple drivers, you can pass a list of maps instead. Note +# that multiple drivers currently still must share the same dependencies +# set and initialization steps. Thus registering multiple drivers is most +# useful for slight variations on the same driver or including an abstract +# parent driver. Note that init steps will get ran once for each driver +# that gets loaded. This can result in duplicate driver instances registered +# with the DriverManager, which is certainly not ideal but does not actually +# hurt anything. +# +# In the near future I might move init steps into driver itself (or +# at least allow them there) +driver: + + # Name of the driver; corresponds to the keyword (e.g. :sqlite) used + # in the codebase + name: sqlite + + # Nice display name shown to admins when connecting a database + display-name: SQLite + + # Whether loading this driver can be deferred until the first + # attempt to connect to a database of this type. Default: true. Only + # set this to false if absolutely neccesary. + lazy-load: true + + # Parent driver, if any. + parent: sql-jdbc + + # You may alternatively specify a list of parents for drivers with + # more than one: + parent: + - google + - sql + + # Whether this driver is abstract. Default: false + abstract: false + + # List of connection properties to ask users to set to connect to + # this driver. + connection-properties: + # Connection properties can be one of the defaults found in + # metabase.driver.common, listed by name: + - dbname + - host + + # Or a full map for a custom option. Complete schema for custom + # options can be found in metabase.driver. NOTE: these are not + # currently translated for i18n; I'm working on a way to translate + # these. Prefer using one of the defaults from + # metabase.driver.common if possible. + - name: db + display-name: Filename + placeholder: /home/camsaul/toucan_sightings.sqlite + required: true + + # Finally, you can use merge: to merge multiple maps. This is + # useful to override specific properties in one of the defaults. + - merge: + - port + - placeholder: 1433 + +# Steps to take to initialize the plugin. For lazy-load drivers, this +# is delayed until the driver is initialized the first time we connect +# to a database with it +init: + + # load-namespace tells Metabase to require a namespace from the JAR, + # you can do whatever Clojurey things you need to do inside that + # namespace + - step: load-namespace + namespace: metabase.driver.sqlite + + # register-jdbc-driver tells Metabase to register a JDBC driver that + # will be used by this driver. (It actually registers a proxy + # driver, because DriverManager won't allow drivers that are loaded + # by different classloaders than it was loaded by (i.e., the system + # classloader); don't worry to much about this, but know for + # JDBC-based drivers you need to include your dependency here) + - step: register-jdbc-driver + class: org.sqlite.JDBC +``` + +## Next up + +[Implementing multimethods](multimethods) for your driver. diff --git a/_docs/doc-update-detection/developers-guide/drivers/start.md b/_docs/doc-update-detection/developers-guide/drivers/start.md new file mode 100644 index 000000000..724f65f9a --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/drivers/start.md @@ -0,0 +1,45 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Guide to writing a Metabase driver' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/drivers/start.md' +--- + +# Guide to writing a Metabase driver + +So here's the scenario: you love Metabase. It's changed your life. But you have some data in a Visual Fox Pro '98 database and you need to make charts with it, and it might be a while before the core Metabase team writes a driver for Visual Fox Pro '98. No problem! Writing a driver can be fun. + +## Does a driver for your data source already exist? + +Before you start building a driver from scratch, see if one already exists that you could contribute to: + +- [Officially supported drivers](../../databases/connecting#connecting-to-supported-databases) +- [Community drivers](../community-drivers) + +## Setting up + +Before you start working on a driver, you'll need to set up your [development environment](../devenv). + +Having an in-depth understanding of Clojure is less important when writing JDBC-based drivers because their implementation is simpler -- much of the work is already done for you -- but it would still be helpful to understand what things like [multimethods](https://clojure.org/reference/multimethods) are. See [Working with Clojure](../clojure). + +## Writing a driver + +Try to avoid skipping right to whichever page you think will give you the code you'll need to copy-pasta. While Metabase drivers are often fairly small (some as little as fifty lines of code), you should put some careful thought into deciding what goes into those fifty lines. You'll have an easier time writing the driver, and end up with a better one. + +1. [Driver basics](basics) +2. [Plugin manifests](plugins) +3. [Implementing multimethods for your driver](multimethods) +4. [Submitting a PR for your driver](driver-tests) + +## Example drivers + +- [Sample driver](https://github.com/metabase/sample-driver) +- [Metabase driver modules](https://github.com/metabase/metabase/tree/master/modules/drivers) +- [A sample sudoku driver](https://github.com/metabase/sudoku-driver) + +## Driver development announcements + +Occasionally, we may make changes to Metabase that impact database drivers. We'll try to give everyone as much of a heads up as possible. For notifications regarding potential driver changes, subscribe to the [Metabase Community Authors mailing list](http://eepurl.com/gQcIO9). diff --git a/_docs/doc-update-detection/developers-guide/e2e-tests.md b/_docs/doc-update-detection/developers-guide/e2e-tests.md new file mode 100644 index 000000000..3112e9377 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/e2e-tests.md @@ -0,0 +1,305 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'End-to-end tests with Cypress' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/e2e-tests.md' +--- + +# End-to-end tests with Cypress + +Metabase uses Cypress for “end-to-end testing”, that is, tests that are executed against the application as a whole, including the frontend, backend, and application database. These tests are essentially scripts written in JavaScript that run in the web browser: visit different URLs, click various UI elements, type text, and assert that things happen as expected (for example, an element appearing on screen, or a network request occuring). + +## Getting Started + +Metabase’s Cypress tests are located in the `e2e/test/scenarios` source tree, in a structure that roughly mirrors Metabase’s URL structure. For example, tests for the admin “datamodel” pages are located in `e2e/test/scenarios/admin/datamodel`. + +Our custom Cypress runner builds its own backend and creates a temporary H2 app db. Both are destroyed when this process is killed. The reserved default port is `4000` on the local host. There is nothing stopping you from running your local Metabase instance on `localhost:3000` at the same time. This might even be helpful for debugging purposes. + +### Standard Development Flow + +1. Continuously build the frontend + + a. If you need only the frontend, run `yarn build-hot` + + b. If you want to run a local Metabase instance alongside Cypress, the easiest way to achieve this is by using `yarn dev` or `yarn dev-ee` (both rely on frontend hot reloading under the hood) + +2. In a separate terminal session (without killing the previous one) run `yarn test-cypress`. This will open a Cypress GUI that will let you choose which tests to run. Alternatively, take a look at `run_cypress_local.js` and `e2e/test/scenarios/docker-compose.yml` for all possible options. + +### Running Options + +To run all Cypress tests headlessly in the terminal: + +```sh +OPEN_UI=false yarn run test-cypress +``` + +You can quickly test a single file only by using the official `--spec` flag. +This flag can be used to run all specs within a folder, or to run multiple assorted specs. Consult [the official documentation](https://docs.cypress.io/app/references/command-line#cypress-run-spec-lt-spec-gt) for instructions. + +```sh +OPEN_UI=false yarn test-cypress --spec e2e/test/scenarios/question/new.cy.spec.js +``` + +You can specify a browser to execute Cypress tests in using the `--browser` flag. For more details, please consult [the official documentation](https://docs.cypress.io/guides/guides/launching-browsers). + +Specifying a browser makes most sense when running Cypress in a _run_ mode. On the other hand, Cypress _open_ mode (GUI) allows one to easily switch between all available browsers on the system. However, some people prefer to specify a browser even in this scenario. If you do this, keep in mind that you are merely preselecting an initial browser for Cypress but you still have the option to choose a different one. + +## Anatomy of the Test + +Cypress test files are structured like Mocha tests, where `describe` blocks are used to group related tests, and `it` blocks are the tests themselves. + +```js +describe("homepage", () => { + it("should load the homepage and...", () => { + cy.visit("/metabase/url"); + // ... + }); +}); +``` + +We strongly prefer using selectors like `cy.findByText()` and `cy.findByLabelText()` from [`@testing-library/cypress`](https://github.com/testing-library/cypress-testing-library) since they encourage writing tests that don't depend on implementation details like CSS class names. + +Try to avoid repeatedly testing pieces of the application incidentally. For example, if you want to test something about the query builder, jump straight there using a helper like `openOrdersTable()` rather than starting from the home page, clicking "New", then "Question", etc. + +## Cypress Documentation + +- Introduction: https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html +- Commands: https://docs.cypress.io/api/api/table-of-contents.html +- Assertions: https://docs.cypress.io/guides/references/assertions.html + +## Tips/Gotchas + +### `contains` vs `find` vs `get` + +Cypress has a set of similar commands for selecting elements. Here are some tips for using them: + +- [`contains`](https://docs.cypress.io/api/commands/contains) is (by default) case-sensitive to the text _in the DOM_. If it’s not matching text you’d expect, check that CSS hasn’t updated the case. You can explicitly tell it to ignore the case with the following option `{ matchCase: false }`. + - `contains` matches substrings. Given two strings “filter by” and “Add a filter”, `cy.contains(“filter”);` will match both. To avoid these issues, you can either pass a regexp that pins the start/end of the string or scope a string to a specific selector: `cy.contains(selector, content);`. +- [`find`](https://docs.cypress.io/api/commands/find) will let you search within your previous selection. +- [`get`](https://docs.cypress.io/api/commands/get) will search the entire page even if chained, unless you explicitly tweak the `withinSubject` option. + +### How to access Sample Database tables and field IDs? + +The Sample Database that we use in E2E tests can change at any time, and with it the references to its tables and fields. Never **ever** use hard coded numeric references to those IDs. We provide a helpful mechanism to achieve this that is guaranteed to produce correct results. Every time you spin Cypress up, it fetches the information about the Sample Database, extracts table and field IDs and writes that to the `e2e/support/cypress_sample_database` JSON that we then re-export and make available to all tests. + +```js +// Don't +const query = { + "source-table": 1, + aggregation: [["count"]], + breakout: [["field", 7, null]], +}; + +// Do this instead +import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; +const { PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE; + +const query = { + "source-table": PRODUCTS_ID, + aggregation: [["count"]], + breakout: [["field", PRODUCTS.CATEGORY, null]], +}; +``` + +### Increase viewport size to avoid scrolling + +Sometimes Metabase views are a bit large for Cypress’ default 1280x800 viewport. This can require you to scroll for tests to work. For example, virtualized tables will not even render the contents outside of the viewport. To avoid these problems, increase the viewport size for a specific test. Unless you're specifically testing how the application behaves on a window resize, please avoid using the `cy.viewport(width, height);` in the middle of the test. Set the viewport width/height using the optional Cypress test config instead. This config works with both `describe` and `it` blocks. + +```js +describe("foo", { viewportWidth: 1400 }, () => {}); + +it("bar", { viewportWidth: 1600, viewportHeight: 1200 }, () => {}); +``` + +### Code reloading vs test reloading + +When you edit a Cypress test file, the tests will refresh and run again. However, when you edit a code file, Cypress won’t detect that change. If you’re running `yarn build-hot`, the code will rebuild and update within Cypress. You’ll have to manually click rerun after the new code has loaded. + +### Inspecting while the “contains helper” is open + +One great feature of Cypress is that you can use the Chrome inspector after each step of a test. They also helpfully provide a helper that can test out `contains` and `get` calls. This helper creates new UI that prevents inspecting from targeting the correct elements. If you want to inspect the DOM in Chrome, you should close this helper. + +### Putting the wrong HTML template in the Uberjar + +`yarn build` and `yarn build-hot` each overwrite an HTML template to reference the correct JavaScript files. If you run `yarn build` before building an Uberjar for Cypress tests, you won’t see changes to your JavaScript reflected even if you then start `yarn build-hot`. + +### Running Cypress on M1 machines + +You might run into problems when running Cypress on M1 machine. +This is caused by the `@bahmutov/cypress-esbuild-preprocessor` that is using `esbuild` as a dependency. The error might look [like this](https://github.com/evanw/esbuild/issues/1819#issuecomment-1018771557). [The solution](https://github.com/evanw/esbuild/issues/1819#issuecomment-1080720203) is to install NodeJS using one of the Node version managers like [nvm](https://github.com/nvm-sh/nvm) or [n](https://github.com/tj/n). + +Another issue you will almost surely face is the inability to connect to our Mongo QA Database. You can solve it by providing the following env: + +```shell +export EXPERIMENTAL_DOCKER_DESKTOP_FORCE_QEMU=1 +``` + +### Running tests that depend on Docker images + +A subset of our tests depend on the external services that are available through the Docker images. At the time of this writing, those are the three supported external QA databases, Webmail, Snowplow and LDAP servers. The default cypress command will spin up all necessary docker containers for these tests to function properly, but you can toggle them off if you want + +```sh +START_CONTAINERS=false yarn test-cypress +``` + +### Running tests with Snowplow involved + +Tests that depend on Snowplow expect a running server. This is enabled by default. You can manually enable them as well by spinning up the snowplow micro docker container and setting the appropriate environment variables: + +``` +docker-compose -f ./snowplow/docker-compose.yml up -d +export MB_SNOWPLOW_AVAILABLE=true +export MB_SNOWPLOW_URL=http://localhost:9090 +``` + +## Testing with Snowplow + +We have a few helpers for dealing with tests involving snowplow + +1. You can use `describeWithSnowplow` (or `describeWithSnowplowEE` for EE edition) method to define tests that only run when a Snowplow instance is running +2. Use `resetSnowplow()` test helper before each test to clear the queue of processed events. +3. Use `expectGoodSnowPlowEvent({ ...payload})` to assert on the content of a snowplow event. Use `expectGoodSnowplowEvents(count)` to assert that events have been sent and processed correctly. Prefer the more precise assertion on the actual payload to a mere count of events. +4. Use `expectNoBadSnowplowEvents()` after each test to assert that no invalid events have been sent. + +### Running tests that require SMTP server + +Some of our tests depend on the email being set up, and require a local SMTP server. We use `maildev` Docker image for that purpose. At the time of this writing the image we use is `maildev/maildev:2.1.0`. The default cypress configuration for local development will handle this for you. If you want to set it up manually, you can use this command: + +```sh +docker run -d -p 1080:1080 -p 1025:1025 maildev/maildev:latest +``` + +### Cypress comes with `Lodash` for free + +We don't need to have [Lodash](https://lodash.com/) in our direct dependencies to be able to [use it with Cypress](https://docs.cypress.io/api/utilities/_). It is aliased with an underscore and its methods can be accessed with `Cypress._.method()`. We can use `_.times` method to stress-test a certain test (or a set of tests) locally. + +```js +// Run the test N times +Cypress._.times(N, () => { + it("should foo", () => { + // ... + }); +}); +``` + +### Embedding SDK tests + +Tests located in `e2e/test-component/scenarios/embedding-sdk/` are used to run automated checks for the Embedding SDK. + +In order to run the tests locally, see [sdk docs about e2e](https://github.com/metabase/metabase/blob/master/enterprise/frontend/src/embedding-sdk/dev.md) + +### Sample Apps compatibility with Embedding SDK tests + +In order to check compatibility between Sample Apps and Embedding SDK, we have a special test suite for each sample app that pulls this Sample App, starts it and runs its Cypress tests against the local `metabase.jar` and local `@metabase/embedding-sdk-react` package. + +To run these tests locally, run: +``` +ENTERPRISE_TOKEN= TEST_SUITE=-e2e OPEN_UI=false EMBEDDING_SDK_VERSION=local START_METABASE=false GENERATE_SNAPSHOTS=false START_CONTAINERS=false yarn test-cypress +``` + +For example for the `metabase-nodejs-react-sdk-embedding-sample`, run: +``` +ENTERPRISE_TOKEN= TEST_SUITE=metabase-nodejs-react-sdk-embedding-sample-e2e OPEN_UI=false EMBEDDING_SDK_VERSION=local START_METABASE=false GENERATE_SNAPSHOTS=false START_CONTAINERS=false yarn test-cypress +``` + +On our CI, test failures do not block the merging of a pull request (PR). However, if a test fails, it’s most likely due to one of the following reasons: + +- **Build Failure**: + + The failure occurs during the build of a local `@metabase/embedding-sdk-react` dist. This indicates there is likely a syntax or type error in the front-end code. +- **Test Run Failure**: + + The failure occurs during the actual test execution. In this case, the PR may have introduced a change that either: + - Breaks the entire Metabase or Embedding SDK, or + - Breaks the compatibility between the Embedding SDK and the Sample Apps. + +If a PR breaks compatibility between the Embedding SDK and the Sample Apps, the PR can still be merged. However, for each Sample App affected, a separate PR should be created to restore compatibility with the new `@metabase/embedding-sdk-react` version when it is released. These compatibility PRs should be merged only once the Embedding SDK version containing breaking changes is officially released. + +## DB Snapshots + +At the beginning of each test suite we wipe the backend's db and settings cache. This ensures that the test suite starts in a predictable state. + +Typically, we use the default snapshot by adding `before(restore)` inside the first `describe` block to restore before running the whole test suite. If you want to use a snapshot besides the default one, specify the name as an argument to `restore` like this: `before(() => restore("blank"))`. You can also call `restore()` inside `beforeEach()` to reset before every test, or inside specific tests. + +Snapshots are created with a separate set of Cypress tests. These tests start with a blank database and execute specific actions to put the database in predictable state. For example: signup as bob@metabase.com, add a question, turn on setting ABC. + +These snapshot-generating tests have the extension `.cy.snap.js`. When these tests run they create db dumps in `frontend/tests/snapshots/*.sql`. They are run before the tests begin and don't get committed to git. + +## Running in CI + +Cypress records videos of each test run, which can be helpful in debugging. Additionally, failed tests have higher quality images saved. + +These files can be found under the “Artifacts” section for each run's summary in GitHub Actions. +The example of the artifacts for a failed test in "Onboarding" directory: +![GitHub Actions artifacts section](https://user-images.githubusercontent.com/31325167/241774190-f19da1d5-8fca-4c48-9342-ead18066bd12.png) + +## Running Cypress tests against Metabase® Enterprise Edition™ + +Prior to running Cypress against Metabase® Enterprise Edition™, set `MB_EDITION=ee` environment variable. + +**Enterprise instance will start without a premium token!** + +If you want to test premium features (feature flags), valid tokens need to be available to all Cypress tests. We achieve this by prefixing environment variables with `CYPRESS_`. +You should provide two tokens that correspond to the `EE/PRO` self-hosted (all features enabled) and `STARTER` Cloud (no features enabled) Metabase plans. For more information, please see [Metabase pricing page](/pricing/). (note: only a few tests require the no features token) + +- `CYPRESS_ALL_FEATURES_TOKEN` +- `CYPRESS_NO_FEATURES_TOKEN` + +``` +MB_EDITION=ee ENTERPRISE_TOKEN=xxxxxx yarn test-cypress +``` + +If you navigate to the `/admin/settings/license` page, the license input field should display the active token. Be careful when sharing screenshots! + +- If tests start running but the enterprise features are missing: make sure that the token you use has corresponding feature flags enabled. +- If everything with the token seems to be okay, go nuclear and destroy all Java processes: run `killall java` and restart Cypress. + +## Tags + +Cypress allows us to [tag](https://github.com/cypress-io/cypress/tree/develop/npm/grep#tags-in-the-test-config-object) tests, to easily find certain categories of tags. For example, we can tag all tests that require an external database with `@external` and then run only those tests with `yarn test-cypress --env grepTags="@external"`. Tags should start with `@` just to make it easier to distinguish them from other strings in searches. + +These are the tags currently in use: + +- `@external` - tests that require an external docker container to run +- `@actions` - tests that use metabase actions and mutate data in a data source + +## How to stress-test a flake fix? + +Fixing a flaky test locally doesn't mean the fix works in GitHub's CI environment. The only way to be sure the fix works is to stress-test it in CI. That's what `.github/workflows/e2e-stress-test-flake-fix.yml` is made for. It allows you to quickly test the fix in your branch without waiting for the full build to complete. + +Please follow these steps: + +### Prepare + +- Create a new branch with your proposed fix and push it to the remote +- Either skip opening a PR altogether or open a **draft** pull request + +### Trigger the stress-test workflow manually + +- Go to `https://github.com/metabase/metabase/actions/workflows/e2e-stress-test-flake-fix.yml` +- Click on _Run workflow_ trigger next to "This workflow has a workflow_dispatch event trigger." + +1. Choose your own branch in the first field "Use workflow from" (this part is crucial!) +2. Copy and paste the relative path of the spec you want to test (e.g. `e2e/test/scenarios/onboarding/urls.cy.spec.js`) - you don't have to wrap it in quotes +3. Set the desired number of times to run the test +4. Optionally provide a grep filter, according to [the documentation](https://github.com/cypress-io/cypress/tree/develop/npm/grep) +5. Click the green "Run workflow" button and wait for the results + +### Things to keep in mind when using this workflow + +- It will automatically try to find and download the previously built Metabase uberjar stored as an artifact from one of the past commits / CI runs. +- It was intended to be used for pure E2E fixes that don't require new Metabase uberjar. +- If the fix required a source-code change (either backend of frontend), please open a regular PR instead and let the CI run all tests first. After this, + you can trigger the stress-test workflow manually, as explained above, and it will automatically download newly built artifact from this CI run. Please, + keep in mind that CI needs to fully finish running first. The workflow uses GitHub REST API which doesn't see artifacts otherwise. + +## Reports + +Individual Mocha reports are automatically generated per spec. They are stored in `cypress/reports/mochareports`. Please keep in mind that the root level `cypress/` folder is git ignored! + +When tests run _in CI_ we do some extra steps by merging these individual reports (using `mochawesome-merge`), formatting them, and then generating customized GitHub Actions job summaries. + +On an off chance that you need a unified test report _while running tests locally_, you can achieve that by invoking `yarn generate-cypress-html-report`. diff --git a/_docs/doc-update-detection/developers-guide/emacs.md b/_docs/doc-update-detection/developers-guide/emacs.md new file mode 100644 index 000000000..72833cca1 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/emacs.md @@ -0,0 +1,23 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Developing Metabase with Emacs' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/emacs.md' +--- + +# Developing Metabase with Emacs + +`.dir-locals.el` contains some Emacs Lisp that tells `clojure-mode` how to indent Metabase macros and which arguments are docstrings. Whenever this file is updated, +Emacs will ask you if the code is safe to load. You can answer `!` to save it as safe. + +By default, Emacs will insert this code as a customization at the bottom of your `init.el`. +You'll probably want to tell Emacs to store customizations in a different file. Add the following to your `init.el`: + +```emacs-lisp +(setq custom-file (concat user-emacs-directory ".custom.el")) ; tell Customize to save customizations to ~/.emacs.d/.custom.el +(ignore-errors ; load customizations from ~/.emacs.d/.custom.el + (load-file custom-file)) +``` diff --git a/_docs/doc-update-detection/developers-guide/frontend.md b/_docs/doc-update-detection/developers-guide/frontend.md new file mode 100644 index 000000000..b44a4c448 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/frontend.md @@ -0,0 +1,504 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: Frontend +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/frontend.md' +--- + +# Frontend + +## Entity Loaders + +If you're developing a new feature or just generally need to get at some of the application data on the frontend, Entity Loaders are going to be your friend. They abstract away calling the API, handling loading and error state, cache previously loaded objects, invalidating the cache (in some cases) and let you easily perform updates, or create new items. + +### Good uses for Entity Loaders + +- I need to get a specific X (user, database, etc) and display it. +- I need to get a list of X (databases, questions, etc) and display it. + +### Currently available entities: + +- Questions, Dashboards, Pulses +- Collections +- Databases, Tables, Fields, Segments, Metrics +- Users, Groups +- Full current list of entities here: https://github.com/metabase/metabase/tree/master/frontend/src/metabase/entities + +There are two ways to use loaders, either as React "render prop" components or as React component class decorators ("higher order components"). + +### Object loading + +In this example we're going to load information about a specific database for a new page. + +```js +import React from "react"; +import Databases from "metabase/entities/databases"; + +@Databases.load({ id: 4 }) +class MyNewPage extends React.Component { + render() { + const { database } = this.props; + return ( +
+

{database.name}

+
+ ); + } +} +``` + +This example uses a class decorator to ask for and then display a database with ID 4. If you instead wanted to use a render prop component your code would look like this. + +```js +import React from "react"; +import Databases from "metabase/entities/databases"; + +class MyNewPage extends React.Component { + render() { + const { database } = this.props; + return ( +
+ + {({ database }) =>

{database.name}

} +
+
+ ); + } +} +``` + +Now you most likely don't just want to display just one static item so for cases where some of the values you might need will be dynamic you can use a function to get at the props and return the value you need. If you're using the component approach you can just pass props as you would normally for dynamic values. + +```js +@Databases.load({ + id: (state, props) => props.params.databaseId +})) +``` + +## List loading + +Loading a list of items is as easy as applying the `loadList` decorator: + +```js +import React from "react"; +import Users from "metabase/entities/users"; + +@Users.loadList() +class MyList extends React.Component { + render() { + const { users } = this.props; + return
{users.map(u => u.first_name)}
; + } +} +``` + +Similar to the object loader's `id` argument you can also pass a `query` object (if the API supports it): + +```js +@Users.loadList({ + query: (state, props) => ({ archived: props.showArchivedOnly }) +}) +``` + +### Control over loading and error states + +By default both `EntityObject` and `EntityList` loaders will handle loading state for you by using `LoadingAndErrorWrapper` under the hood. If for some reason you want to handle loading on your own you can disable this behavior by setting `loadingAndErrorWrapper: false`. + +### Wrapped objects + +If you pass `wrapped: true` to a loader then the object or objects will be wrapped with helper classes that let you do things like `user.getName()`, `user.delete()`, or `user.update({ name: "new name" )`. Actions are automatically already bound to `dispatch`. + +This may incur a performance penalty if there are many objects. + +Any additional selectors and actions defined in the entities' `objectSelectors` or `objectActions` will appear as the wrapped object's methods. + +### Advanced usage + +You can also use the Redux actions and selectors directly, for example, `dispatch(Users.actions.loadList())` and `Users.selectors.getList(state)`. + +## Style Guide + +### Set up Prettier + +We use [Prettier](https://prettier.io/) to format our JavaScript code, and it is enforced by CI. We recommend setting your editor to "format on save". You can also format code using `yarn prettier`, and verify it has been formatted correctly using `yarn lint-prettier`. + +We use ESLint to enforce additional rules. It is integrated into the Webpack build, or you can manually run `yarn lint-eslint` to check. + +### React and JSX Style Guide + +For the most part we follow the [Airbnb React/JSX Style Guide](https://github.com/airbnb/javascript/tree/master/react). ESLint and Prettier should take care of a majority of the rules in the Airbnb style guide. Exceptions will be noted in this document. + +- Prefer React [function components over class components](https://reactjs.org/docs/components-and-props.html#function-and-class-components) +- Avoid creating new components within the `containers` folder, as this approach has been deprecated. Instead, store both connected and view components in the `components` folder for a more unified and efficient organization. If a connected component grows substantially in size and you need to extract a view component, opt for using the `View` suffix. +- For control components, typically we use `value` and `onChange`. Controls that have options (e.x. `Radio`, `Select`) usually take an `options` array of objects with `name` and `value` properties. +- Components named like `FooModal` and `FooPopover` typically refer to the modal/popover _content_ which should be used inside a `Modal`/`ModalWithTrigger` or `Popover`/`PopoverWithTrigger` +- Components named like `FooWidget` typically include a `FooPopover` inside a `PopoverWithTrigger` with some sort of trigger element, often `FooName` + +- Use arrow function instance properties if you need to bind a method in a class (instead of `this.method = this.method.bind(this);` in the constructor), but only if the function needs to be bound (e.x. if you're passing it as a prop to a React component) + +```javascript +class MyComponent extends React.Component { + constructor(props) { + super(props); + // NO: + this.handleChange = this.handleChange.bind(this); + } + // YES: + handleChange = e => { + // ... + }; + // no need to bind: + componentDidMount() {} + render() { + return ; + } +} +``` + +- For styling components we currently use a mix of `styled-components` and ["atomic" / "utility-first" CSS classes](https://github.com/metabase/metabase/tree/master/frontend/src/metabase/css/core). +- Prefer using `grid-styled`'s `Box` and `Flex` components over raw `div`. +- Components should typically pass along their `className` prop to the root element of the component. It can be merged with additional classes using the `cx` function from the `classnames` package. +- In order to make components more reusable, a component should only apply classes or styles to the root element of the component which affects the layout/styling of it's own content, but _not_ the layout of itself within it's parent container. For example, it can include padding or the `flex` class, but it shouldn't include margin or `flex-full`, `full`, `absolute`, `spread`, etc. Those should be passed via `className` or `style` props by the consumer of the component, which knows how the component should be positioned within itself. +- Avoid breaking JSX up into separate method calls within a single component. Prefer inlining JSX so that you can better see what the relation is of the JSX a `render` method returns to what is in the `state` or `props` of a component. By inlining JSX you'll also get a better sense of what parts should and should not be separate components. + +```javascript + +// don't do this +render () { + return ( +
+ {this.renderThing1()} + {this.renderThing2()} + {this.state.thing3Needed && this.renderThing3()} +
+ ); +} + +// do this +render () { + return ( +
+ + + {this.state.thing3Needed && } +
+ ); +} +``` + +### JavaScript Conventions + +- `import`s should be ordered by type, typically: + 1. external libraries (`react` is often first, along with things like `ttags`, `underscore`, `classnames`, etc) + 2. Metabase's top-level React components and containers (`metabase/components/*`, `metabase/containers/*`, etc) + 3. Metabase's React components and containers specific to this part of the application (`metabase/*/components/*` etc) + 4. Metabase's `lib`s, `entities`, `services`, Redux files, etc +- Prefer `const` to `let` (and never use `var`). Only use `let` if you have a specific reason to reassign the identifier (note: this now enforced by ESLint) +- Prefer [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) for inline functions, especially if you need to reference `this` from the parent scope (there should almost never be a need to do `const self = this;` etc), but usually even if you don't (e.x. `array.map(x => x * 2)`). +- Prefer `function` declarations for top-level functions, including React function components. The exception is for one-liner functions that return a value + +```javascript +// YES: +function MyComponent(props) { + return
...
; +} +// NO: +const MyComponent = props => { + return
...
; +}; +// YES: +const double = n => n * 2; +// ALSO OK: +function double(n) { + return n * 2; +} +``` + +- Prefer native `Array` methods over `underscore`'s. We polyfill all ES6 features. Use Underscore for things that aren't implemented natively. +- Prefer [`async`/`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) over using `promise.then(...)` etc directly. +- You may use assignment destructuring or argument destructuring, but avoid deeply nested destructuring, since they can be hard to read and `prettier` sometimes formats them with extra whitespace. + - avoid destructuring properties from "entity"-like objects, e.x. don't do `const { display_name } = column;` + - don't destructure `this` directly, e.x. `const { foo } = this.props; const { bar } = this.state;` instead of `const { props: { foo }, state: { bar } } = this;` +- Avoid nested ternaries as they often result in code that is difficult to read. If you have logical branches in your code that are dependent on the value of a string, prefer using an object as a map to multiple values (when evaluation is trivial) or a `switch` statement (when evaluation is more complex, like when branching on which React component to return): + +```javascript +// don't do this +const foo = str == 'a' ? 123 : str === 'b' ? 456 : str === 'c' : 789 : 0; + +// do this +const foo = { + a: 123, + b: 456, + c: 789, +}[str] || 0; + +// or do this +switch (str) { + case 'a': + return ; + case 'b': + return ; + case 'c': + return ; + case 'd': + default: + return ; +} +``` + +If your nested ternaries are in the form of predicates evaluating to booleans, prefer an `if/if-else/else` statement that is siloed to a separate, pure function: + +```javascript +const foo = getFoo(a, b); + +function getFoo(a, b, c) { + if (a.includes("foo")) { + return 123; + } else if (a === b) { + return 456; + } else { + return 0; + } +} +``` + +- Be conservative with what comments you add to the codebase. Comments shouldn't be used as reminders or as todos--record those by creating a new issue in Github. Ideally, code should be written in such a way that it explains itself clearly. When it does not, you should first try rewriting the code. If for whatever reason you are unable to write something clearly, add a comment to explain the "why". + +```javascript + +// don't do this--the comment is redundant + +// get the native permissions for this db +const nativePermissions = getNativePermissions(perms, groupId, { + databaseId: database.id, +}); + +// don't add TODOs -- they quickly become forgotten cruft + +isSearchable(): boolean { + // TODO: this should return the thing instead + return this.isString(); +} + +// this is acceptable -- the implementer explains a not-obvious edge case of a third party library + +// foo-lib seems to return undefined/NaN occasionally, which breaks things +if (isNaN(x) || isNaN(y)) { + return; +} + +``` + +- Avoid complex logical expressions inside of if statements + +```javascript +// don't do this +if (typeof children === "string" && children.split(/\n/g).length > 1) { + // ... +} + +// do this +const isMultilineText = + typeof children === "string" && children.split(/\n/g).length > 1; +if (isMultilineText) { + // ... +} +``` + +- Use ALL_CAPS for constants + +```javascript +// do this +const MIN_HEIGHT = 200; + +// also acceptable +const OBJECT_CONFIG_CONSTANT = { + camelCaseProps: "are OK", + abc: 123, +}; +``` + +- Prefer named exports over default exports + +```javascript +// this makes it harder to search for Widget +import Foo from "./Widget"; +// do this to enforce using the proper name +import { Widget } from "./Widget"; +``` + +- Avoid magic strings and numbers + +```javascript +// don't do this +const options = _.times(10, () => ...); + +// do this in a constants file +export const MAX_NUM_OPTIONS = 10; +const options = _.times(MAX_NUM_OPTIONS, () => ...); +``` + +### Write Declarative Code + +You should write code with other engineers in mind as other engineers will spend more time reading than you spend writing (and re-writing). Code is more readable when it tells the computer "what to do" versus "how to do." Avoid imperative patterns like for loops: + +```javascript +// don't do this +let foo = []; +for (let i = 0; i < list.length; i++) { + if (list[i].bar === false) { + continue; + } + + foo.push(list[i]); +} + +// do this +const foo = list.filter(entry => entry.bar !== false); +``` + +When dealing with business logic you don't want to be concerned with the specifics of the language. Instead of writing `const query = new Question(card).query();` which entails instantiating a new `Question` instance and calling a `query` method on said instance, you should introduce a function like `getQueryFromCard(card)` so that implementers can avoid thinking about what goes into getting a `query` value from a card. + +## Component Styling Tree Rings + +### CSS modules + +```css +.primary { + color: -var(--mb-color-brand); +} +``` + +```javascript +import S from "./Foo.css"; + +const Foo = () =>
; +``` + +### [Emotion](https://emotion.sh/) (discouraged) + +```javascript +import styled from "@emotion/styled"; + +const Foo = styled.div` + color: ${props => props.color}; +`; + +const Bar = ({ color }) => ; +``` + +## Popover + +Popovers are popups or modals. + +In Metabase core, they are visually responsive: they appear above or below the element that triggers their appearance. Their height is automatically calculated to make them fit on the screen. + +### Where to Find Popovers in the User Journey + +#### When creating custom questions + +1. From home, click on `New` and then `Question` +2. 👀 The option picker that automatically opened next to `Pick your starting data` is a ``. +3. Choose `Sample Database` if not already selected +4. Choose any of the tables, for example `People` + +Here, clicking on the following will open `` components: + +- `Pick columns` (arrow on the right-hand side of a `FieldsPicker` control in the section labeled `Data`) +- Gray icon of a grid with + below section labeled `Data` +- `Add filters to narrow your answers` +- `Pick the metric you want to see` +- `Pick a column to group by` +- `Sort` icon with arrows pointing up and down above `Visualize` button + +## Unit testing + +### Setup pattern + +We use the following pattern to unit test components: + +```tsx +import React from "react"; +import userEvent from "@testing-library/user-event"; +import { Collection } from "metabase-types/api"; +import { createMockCollection } from "metabase-types/api/mocks"; +import { renderWithProviders, screen } from "__support__/ui"; +import CollectionHeader from "./CollectionHeader"; + +interface SetupOpts { + collection: Collection; +} + +const setup = ({ collection }: SetupOpts) => { + const onUpdateCollection = jest.fn(); + + renderWithProviders( + , + ); + + return { onUpdateCollection }; +}; + +describe("CollectionHeader", () => { + it("should be able to update the name of the collection", () => { + const collection = createMockCollection({ + name: "Old name", + }); + + const { onUpdateCollection } = setup({ + collection, + }); + + await userEvent.clear(screen.getByDisplayValue("Old name")); + await userEvent.type(screen.getByPlaceholderText("Add title"), "New title"); + await userEvent.tab(); + + expect(onUpdateCollection).toHaveBeenCalledWith({ + ...collection, + name: "New name", + }); + }); +}); +``` + +Key points: + +- `setup` function +- `renderWithProviders` adds providers used by the app, including `redux` + +### Request mocking + +We use [`fetch-mock`](https://www.npmjs.com/package/fetch-mock) to mock requests: + +```tsx +import fetchMock from "fetch-mock"; +import { setupCollectionsEndpoints } from "__support__/server-mocks"; + +interface SetupOpts { + collections: Collection[]; +} + +const setup = ({ collections }: SetupOpts) => { + setupCollectionsEndpoints({ collections }); + + // renderWithProviders and other setup +}; + +describe("Component", () => { + it("renders correctly", async () => { + setup(); + expect(await screen.findByText("Collection")).toBeInTheDocument(); + }); +}); +``` + +Key points: + +- `setup` function +- Call helpers from `__support__/server-mocks` to setup endpoints for your data diff --git a/_docs/doc-update-detection/developers-guide/internationalization.md b/_docs/doc-update-detection/developers-guide/internationalization.md new file mode 100644 index 000000000..dc38ba018 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/internationalization.md @@ -0,0 +1,86 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: Internationalization +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/internationalization.md' +--- + +# Internationalization + +We are an application with lots of users all over the world. To help them use Metabase in their own language, we mark all of our strings as i18n. + +## Quick Guide + +If you need to add new strings (try to be judicious about adding copy) do the following: + +1. Tag strings in the frontend using `t` and `jt` ES6 template literals (see more details in https://ttag.js.org/): + +```javascript +const someString = t`Hello ${name}!`; +const someJSX =
{jt`Hello ${name}`}
; +``` + +and in the backend using `trs` (to use the site language) or `tru` (to use the current User's language): + +```clojure +(trs "Hello {0}!" name) +``` + +## Translation errors or missing strings + +If you see incorrect or missing strings for your language, please visit our [Crowdin project](https://crowdin.com/project/metabase-i18n) and submit your fixes there. + +## Backend Translation Guide + +Metabase allows for translations into many languages. An authoritative list can be found in `resources/locales.clj`. + +## The Metabase Side + +Metabase is concerned about localization into two distinct locales: translating into the server's locale and translating into the user's locale. The distinction is largely: will this be logged on the server or sent over the wire back to the user. + +To translate a string for the server, use `metabase.util.i18n/trs` and for the user's locale, use the similar `metabase.util.i18n/tru`. Think `tr-server` and `tr-user`. + +### How it works + +At a high level, the string to be translated is treated as a lookup key into a map of source-string -> localized-string. This translated string is used like so: + +```clojure + +;; from source of `translate` in `metabase.util.i18n` + +(.format (MessageFormat. looked-up-string) (to-array args)) + +``` + +Everything else is largely bookkeeping. This uses the [java.text.MessageFormat](https://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html) class for splicing in format args. + +The functions `trs` and `tru` create instances of two records, `SiteLocalizedString` and `UserLocalizedString` respectively with overrides to the `toString` method. This method will do the lookup to the current locale (user or site as appropriate), lookup the string to be translated to the associated translated string, and then call the `.format` method on the `MessageFormat`. + +### The maps from source to translated string + +One step in our build process creates an edn file of source to translated string for each locale we support. These are located in `resources/i18n`. If you do not have these files, you can run `bin/build-translation-resources` to generate them. + +We have lots of contributors who help us keep a corpus of translated strings into many different languages. We use [Crowdin](https://crowdin.com/project/metabase-i18n) to keep an authoritative list. We export `.po` files from this, which is essentially a dictionary from source to translated string. As part of our build process we format these files as edn files, maps from the source to translated string, for each locale. + +### Format Args + +Besides string literals, we also want to translate strings that have arguments spliced into the middle. We use the syntax from the [java.text.MessageFormat](https://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html) class mentioned before. These are zero-indexed args of the form `{0}`, `{1}`. + +eg, + +```clojure +(trs "{0} accepted their {1} invite" (:common_name new-user) (app-name-trs)) +(tru "{0}th percentile of {1}" p (aggregation-arg-display-name inner-query arg)) +(tru "{0} driver does not support foreign keys." driver/*driver*) +``` + +#### Escaping + +Every string language needs an escape character. Since `{0}` is an argument to be spliced in, how would you put a literal "{0}" in the string. The apostrophe serves this role and is described in the MessageFormat [javadocs](https://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html). + +These is an unfortunate side effect of this though. Since the apostrophe is such a commeon part of speech (especially in french), we often can end up with escape characters used as a regular part of a string rather than the escape character. Format strings need to use double apostrophes like `(deferred-tru "SAML attribute for the user''s email address")` to escape the apostrophe. + +There are lots of translated strings in French that use a single apostrophe incorrectly. (eg "l'URL" instead of "l''URL"). We have a manual fix to this in `bin/i18n/src/i18n/create_artifacts/backend.clj` where we try to identify these apostrophes which are not escape characters and replace them with a double quote. diff --git a/_docs/doc-update-detection/developers-guide/mage.md b/_docs/doc-update-detection/developers-guide/mage.md new file mode 100644 index 000000000..60ea5d5f3 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/mage.md @@ -0,0 +1,40 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: Mage +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/mage.md' +--- + +# MAGE - Development Automation + +Run `./bin/mage` to list your tasks. All of them support `-h` to learn more and show examples. + +All tasks support a `-h` option and will print their usage info. + +``` shell +$ ./bin/mage + ███╗ ███╗ █████╗ ██████╗ ███████╗ + ████╗ ████║██╔══██╗██╔════╝ ██╔════╝ + ██╔████╔██║███████║██║ ███╗█████╗ + ██║╚██╔╝██║██╔══██║██║ ██║██╔══╝ + ██║ ╚═╝ ██║██║ ██║╚██████╔╝███████╗ + ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ + The Metabase Automation Genius Engine + +The following tasks are available: + +cljfmt-staged Runs cljfmt on staged files +kondo Runs Kondo against a file, directory, or everything we usually lint +... +start-db Start a db on a default port in docker +jar-download Given a version, downloads a metabase jar +$ ./bin/mage kondo -h + +``` + +### mage Autocomplete + +Run `./bin/mage setup-autocomplete` and follow the instructions to setup autocomplete in your terminal. diff --git a/_docs/doc-update-detection/developers-guide/mbql-library-changelog.md b/_docs/doc-update-detection/developers-guide/mbql-library-changelog.md new file mode 100644 index 000000000..f7086a921 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/mbql-library-changelog.md @@ -0,0 +1,37 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'MBQL Library changelog' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/mbql-library-changelog.md' +--- + +# MBQL Library Changelog + +Changes made to the library API for manipulating MBQL queries, found in `metabase.lib.js`. The latest API documentation +can be found [here](https://metabase-dev-docs.github.io/metabase/metabase.lib.js.html). + +This library is mainly used by Metabase's own frontend, but it is treated as a proper API surface which is versioned +and documented in this changelog. + +## Metabase 0.50.0 + +- Created this file and began versioning this API. +- New function `as-returned` has been added. It handles a tricky case when adding filters or expressions to a query + with aggregations. + + Suppose we have a query with aggregations in its last stage. When adding a filter or expression to that stage, it's + applied **before** the aggregations. That may be the desired behavior, but if we want a filter or custom expression + based on the aggregations and breakouts in the last stage, there was no good support in this API. + + `as-returned` looks at the query and stage, and shifts to a later stage if necessary. If a later stage is needed but + we were already on the last stage, a new empty stage is appended. + +- New functions `column-extractions`, `extract`, and `extraction-expression` have been added. + - `column-extractions` returns a list of _extractions_, which are possible custom expressions we can derive from a + given column. For example, getting the host or base domain name from a URL or email address, or the day of the week + from a date or datetime. + - `extract` applies an extraction to the query. + - `extraction-expression` returns the expression for the extraction, allowing further editing. diff --git a/_docs/doc-update-detection/developers-guide/start.md b/_docs/doc-update-detection/developers-guide/start.md new file mode 100644 index 000000000..9a0b24cef --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/start.md @@ -0,0 +1,58 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: 'Developers Guide' +title: 'Developer Guide' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/start.md' +redirect_from: + - /docs/doc-update-detection/developers-guide +--- + +# Developer Guide + +This guide contains detailed information on how to work on Metabase codebase. + +## Contributing + +- [How to contribute back to the Metabase project](../CONTRIBUTING) + +## Setup and build + +- [How to set up a development environment](devenv) +- [How to run a development branch of Metabase using Docker](dev-branch-docker) +- [How to compile your own copy of Metabase](build) + +## Working with the code + +- [How to work with the frontend code](frontend) +- [How to add support in Metabase for other languages](internationalization) +- [Working with Clojure](clojure) +- [Annotated Clojure source code](https://metabase-dev-docs.github.io/) +- [Automating Common Tasks with MAGE](mage) + +## Testing + +- [How to write and run end-to-end tests](e2e-tests) +- [How to use visual tests](visual-tests) + +## API documentation + +- [Autogenerated API docs](../api) +- [Working with the Metabase API](/learn/metabase-basics/administration/administration-and-operation/metabase-api) +- [Driver Interface Changelog](driver-changelog) +- [MBQL Library Changelog](mbql-library-changelog) + +## Database drivers + +- [Community drivers](./community-drivers) +- [Guide to writing a driver](drivers/start) + +## Metabase documentation + +- [Developing Metabase documentation](./docs) + +## Releases + +- [Metabase release versioning](./versioning) diff --git a/_docs/doc-update-detection/developers-guide/versioning.md b/_docs/doc-update-detection/developers-guide/versioning.md new file mode 100644 index 000000000..0b2ccffa1 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/versioning.md @@ -0,0 +1,71 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Metabase release versioning' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/versioning.md' +--- + +# Metabase release versioning + +We follow our own flavor of the [semantic versioning guidelines](https://semver.org/) in order to distinguish the [open-source version](/product/starter) of Metabase from the paid, source-available version of Metabase (available in the [Pro](/product/pro) and [Enterprise](/product/enterprise) plans). + +Semantic versioning typically follows the format: `Major.Minor.Point.Patch`. For example, version `3.15.2` or `3.15.2.1`. + +With Metabase releases, we prefix the version with a `0` or `1`, depending on the license. + +## The Metabase version schema + +``` +License.Major.Point.Hotfix +``` + +E.g., + +``` +v0.46.3.1 +``` + +`v0.46.3.1` would be for a hotfix (`1`) for the third (`3`) point release of Metabase `46`, the open-source edition (`0`). + +### License + +- `0` for the free, open-source version (sometimes called OSS, for open-source software). +- `1` for the paid, source-available version that has all the bells and whistles (sometimes called EE for "Enterprise Edition"). + +### Major + +We release major version when we introduce new features or breaking changes. + +### Point + +Sometimes called a minor release, we issue point releases when we add bug fixes and refinements to existing features. + +### Hotfix + +Sometimes called a patch release, we issue these hotfix releases to fix security issues in a timely manner, or to undo a horrific regression. + +## Other release terms + +### The Gold Release + +The gold release is the first release of a new major version of Metabase. So for Metabase version 46, the gold releases would be: + +- `v0.46.0` (the OSS version) +- `v1.46.0` (the EE version) + +### Release Candidates + +We usually publish release candidates to kick the tires on new features before releasing a new major version (a gold release). To distinguish these release candidates, we append an `-RC#` at the end. + +E.g., + +- `v1.46.0-RC1` (the first release candidate for the EE version) +- `v0.46.0-RC3` (the third release candidate for the OSS version) + +## Further reading + +- [Metabase releases on Github](https://github.com/metabase/metabase/releases) +- [Metabase release blog posts](/releases) diff --git a/_docs/doc-update-detection/developers-guide/visual-studio-code.md b/_docs/doc-update-detection/developers-guide/visual-studio-code.md new file mode 100644 index 000000000..59951c831 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/visual-studio-code.md @@ -0,0 +1,70 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Developing with Visual Studio Code' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/visual-studio-code.md' +--- + +# Developing with Visual Studio Code + +## Debugging + +First, install the following extension: + +- [Debugger for Firefox](https://marketplace.visualstudio.com/items?itemName=firefox-devtools.vscode-firefox-debug) + +_Note_: Debugger for Chrome has been deprecated. You can safely delete it as Visual Studio Code now has [a bundled JavaScript Debugger](https://github.com/microsoft/vscode-js-debug) that covers the same functionality. + +Before starting the debugging session, make sure that Metabase is built and running. Choose menu _View_, _Command Palette_, search for and choose _Tasks: Run Build Task_. Alternatively, use the corresponding shortcut `Ctrl+Shift+B`. The built-in terminal will appear to show the progress, wait a few moment until webpack indicates a complete (100%) bundling. + +To begin debugging Metabase, switch to the Debug view (shortcut: `Ctrl+Shift+D`) and then select one of the two launch configurations from the drop-down at the top: + +- Debug with Firefox, or +- Debug with Chrome + +After that, begin the debugging session by choosing menu _Run_, _Start Debugging_ (shortcut: `F5`). + +For more details, please refer to the complete VS Code documentation on [Debugging](https://code.visualstudio.com/docs/editor/debugging). + +## Docker-based Workflow + +These instructions allow you to work on Metabase codebase on Windows, Linux, or macOS using [Visual Studio Code](https://code.visualstudio.com/), **without** manually installing the necessary dependencies. This is possible by leveraging Docker container and the Remote Containers extension from VS Code. + +For more details, please follow the complete VS Code guide on [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers). + +Requirements: + +- [Visual Studio Code](https://code.visualstudio.com/) (obviously) +- [Docker](https://www.docker.com/) +- [Remote - Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) for VS Code + +_Important_: Ensure that Docker is running properly and it can be used to download an image and launch a container, e.g. by running: + +``` +$ docker run hello-world +``` + +If everything goes well, you should see the following message: + +``` +Hello from Docker! +This message shows that your installation appears to be working correctly. +``` + +Steps: + +1. Clone Metabase repository + +2. Launch VS Code and open your cloned Metabase repository + +3. From the _View_ menu, choose _Command Palette..._ and then find _Remote-Container: Reopen in Container_. (VS Code may also prompt you to do this with an "Open in container" popup). + **Note**: VS Code will create the container for the first time and it may take some time. Subsequent loads should be much faster. + +4. Use the menu _View_, _Command Palette_, search for and choose _Tasks: Run Build Task_ (alternatively, use the shortcut `Ctrl+Shift+B`). + +5. After a while (after all JavaScript and Clojure dependencies are completely downloaded), open localhost:3000 with your web browser. + +See [here](dev-branch-docker) for more on running development branches of Metabase using Docker. diff --git a/_docs/doc-update-detection/developers-guide/visual-tests.md b/_docs/doc-update-detection/developers-guide/visual-tests.md new file mode 100644 index 000000000..1e230de63 --- /dev/null +++ b/_docs/doc-update-detection/developers-guide/visual-tests.md @@ -0,0 +1,36 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Developers Guide' +title: 'Visual Tests' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/developers-guide/visual-tests.md' +--- + +# Visual Tests + +We use [Loki](https://loki.js.org/) with Storybook for visual tests. Loki captures snapshots from selected stories and creates PNG references in `./loki/references` folder. + +## Local machine + +Before running Loki tests locally, ensure that both Storybook and Docker are running. + +### Commands + +- Run Visual Tests: `yarn test-visual:loki` +- Update failing snapshots: `yarn test-visual:loki-approve-diff` +- Generate an HTML Report: `yarn test-visual:loki-report` +- Generate and Open Report: `yarn test-visual:loki-report-open` + +## CI + +Visual tests are automatically triggered on pull requests. The Loki CI job builds the Storybook, captures new snapshots, and compares them with the references. If there are differences, the "Loki Visual Regression Testing" check will fail. + +To view the visual diff report, open the failed job page, go to the Summary section, and download the `loki-report` artifact. + +If the differences are intentional or caused by a flake, update the reference snapshots by adding the `loki-update` label to the pull request. + +## Adding new tests + +Adding new test is as simple as adding new stories. As of today, we use visual tests only for charts, however, you can use it for any other stories. Make sure the `storiesFilter` value in `loki.config.js` includes the stories you want to have as visual tests. diff --git a/_docs/doc-update-detection/embedding/images/04-preview.png b/_docs/doc-update-detection/embedding/images/04-preview.png new file mode 100644 index 000000000..92c62242d Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/04-preview.png differ diff --git a/_docs/doc-update-detection/embedding/images/05-code.png b/_docs/doc-update-detection/embedding/images/05-code.png new file mode 100644 index 000000000..9557e92db Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/05-code.png differ diff --git a/_docs/doc-update-detection/embedding/images/action-buttons.png b/_docs/doc-update-detection/embedding/images/action-buttons.png new file mode 100644 index 000000000..4833ac0c6 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/action-buttons.png differ diff --git a/_docs/doc-update-detection/embedding/images/additional-info.png b/_docs/doc-update-detection/embedding/images/additional-info.png new file mode 100644 index 000000000..ed2e1a56a Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/additional-info.png differ diff --git a/_docs/doc-update-detection/embedding/images/all-users.png b/_docs/doc-update-detection/embedding/images/all-users.png new file mode 100644 index 000000000..b89582dde Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/all-users.png differ diff --git a/_docs/doc-update-detection/embedding/images/create-a-public-link.png b/_docs/doc-update-detection/embedding/images/create-a-public-link.png new file mode 100644 index 000000000..fdcd683cd Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/create-a-public-link.png differ diff --git a/_docs/doc-update-detection/embedding/images/dashboard-sharing.png b/_docs/doc-update-detection/embedding/images/dashboard-sharing.png new file mode 100644 index 000000000..8b2f0d12a Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/dashboard-sharing.png differ diff --git a/_docs/doc-update-detection/embedding/images/embedded-example-dashboard.png b/_docs/doc-update-detection/embedding/images/embedded-example-dashboard.png new file mode 100644 index 000000000..65c0fd398 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/embedded-example-dashboard.png differ diff --git a/_docs/doc-update-detection/embedding/images/enable-public-sharing.png b/_docs/doc-update-detection/embedding/images/enable-public-sharing.png new file mode 100644 index 000000000..13a96abea Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/enable-public-sharing.png differ diff --git a/_docs/doc-update-detection/embedding/images/interactive-question-sample-app.png b/_docs/doc-update-detection/embedding/images/interactive-question-sample-app.png new file mode 100644 index 000000000..f492bbcb8 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/interactive-question-sample-app.png differ diff --git a/_docs/doc-update-detection/embedding/images/interactive-question.png b/_docs/doc-update-detection/embedding/images/interactive-question.png new file mode 100644 index 000000000..a46e7cae6 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/interactive-question.png differ diff --git a/_docs/doc-update-detection/embedding/images/jwt-setup.png b/_docs/doc-update-detection/embedding/images/jwt-setup.png new file mode 100644 index 000000000..539d36e1d Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/jwt-setup.png differ diff --git a/_docs/doc-update-detection/embedding/images/map-user-attribute.png b/_docs/doc-update-detection/embedding/images/map-user-attribute.png new file mode 100644 index 000000000..366ac30e9 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/map-user-attribute.png differ diff --git a/_docs/doc-update-detection/embedding/images/no-top-no-side.png b/_docs/doc-update-detection/embedding/images/no-top-no-side.png new file mode 100644 index 000000000..0a07d147b Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/no-top-no-side.png differ diff --git a/_docs/doc-update-detection/embedding/images/powered-by-metabase.png b/_docs/doc-update-detection/embedding/images/powered-by-metabase.png new file mode 100644 index 000000000..7108cd02c Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/powered-by-metabase.png differ diff --git a/_docs/doc-update-detection/embedding/images/public-embed.png b/_docs/doc-update-detection/embedding/images/public-embed.png new file mode 100644 index 000000000..8e87c240c Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/public-embed.png differ diff --git a/_docs/doc-update-detection/embedding/images/public-export.png b/_docs/doc-update-detection/embedding/images/public-export.png new file mode 100644 index 000000000..e22760ad0 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/public-export.png differ diff --git a/_docs/doc-update-detection/embedding/images/public-link-custom-destination.png b/_docs/doc-update-detection/embedding/images/public-link-custom-destination.png new file mode 100644 index 000000000..ee4b0bd8c Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/public-link-custom-destination.png differ diff --git a/_docs/doc-update-detection/embedding/images/pug-and-play.png b/_docs/doc-update-detection/embedding/images/pug-and-play.png new file mode 100644 index 000000000..096915f98 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/pug-and-play.png differ diff --git a/_docs/doc-update-detection/embedding/images/query-builder.png b/_docs/doc-update-detection/embedding/images/query-builder.png new file mode 100644 index 000000000..7bc097aa3 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/query-builder.png differ diff --git a/_docs/doc-update-detection/embedding/images/sandboxed-invoices-table.png b/_docs/doc-update-detection/embedding/images/sandboxed-invoices-table.png new file mode 100644 index 000000000..0eaa36d82 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/sandboxed-invoices-table.png differ diff --git a/_docs/doc-update-detection/embedding/images/see-shared-content.png b/_docs/doc-update-detection/embedding/images/see-shared-content.png new file mode 100644 index 000000000..c577f72c1 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/see-shared-content.png differ diff --git a/_docs/doc-update-detection/embedding/images/sharing-embed.png b/_docs/doc-update-detection/embedding/images/sharing-embed.png new file mode 100644 index 000000000..0a898e674 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/sharing-embed.png differ diff --git a/_docs/doc-update-detection/embedding/images/side-nav.png b/_docs/doc-update-detection/embedding/images/side-nav.png new file mode 100644 index 000000000..daff7aa27 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/side-nav.png differ diff --git a/_docs/doc-update-detection/embedding/images/static-question.png b/_docs/doc-update-detection/embedding/images/static-question.png new file mode 100644 index 000000000..0ce9d08c7 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/static-question.png differ diff --git a/_docs/doc-update-detection/embedding/images/sync-groups.png b/_docs/doc-update-detection/embedding/images/sync-groups.png new file mode 100644 index 000000000..8d5e5aa44 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/sync-groups.png differ diff --git a/_docs/doc-update-detection/embedding/images/top-nav.png b/_docs/doc-update-detection/embedding/images/top-nav.png new file mode 100644 index 000000000..64f76f746 Binary files /dev/null and b/_docs/doc-update-detection/embedding/images/top-nav.png differ diff --git a/_docs/doc-update-detection/embedding/interactive-embedding-quick-start-guide.md b/_docs/doc-update-detection/embedding/interactive-embedding-quick-start-guide.md new file mode 100644 index 000000000..2cd3d1d76 --- /dev/null +++ b/_docs/doc-update-detection/embedding/interactive-embedding-quick-start-guide.md @@ -0,0 +1,268 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Interactive embedding quickstart' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/interactive-embedding-quick-start-guide.md' +redirect_from: + - /learn/customer-facing-analytics/interactive-embedding-quick-start +--- + +# Interactive embedding quickstart + +You'll embed the full Metabase application in your app. Once logged in, people can view a Metabase dashboard in your web app, and be able to use the full Metabase application to explore their data, and only their data. + +{% include shared/in-page-promo-embedding-workshop.html %} + +## Prerequisites + +- You have an app that you can embed Metabase in. +- You have a Pro or Enterprise subscription of Metabase. If you're unsure where to start, sign up for a free trial for [Pro On-Prem](/product/pro). If you have Docker Desktop installed, you can just search for "metabase-enterprise" to find the Docker image and run it. Alternatively, you can follow [these instructions](../installation-and-operation/running-metabase-on-docker#pro-or-enterprise-quick-start). + +The code featured in this guide can be found in our [sample repo](https://github.com/metabase/metabase-nodejs-express-interactive-embedding-sample). + +## Set up SSO and interactive embedding in Metabase + +### Have a dashboard ready to embed + +You'll first need a dashboard to embed. If you don't have one yet, you can use the Example Dashboard Metabase includes on new instances or you can generate one using x-rays. + +Visit that dashboard and make a note of its URL, e.g. `/dashboard/1-e-commerce-insights`. You'll need to put this relative URL in your app, as you'll use the dashboard as the first page that logged-in people will see when they visit the analytics section in your app. It's enough to include the ID only and omit the rest of the URL, e.g. `/dashboard/1`. + +You could also use the dashboard's [Entity ID](../installation-and-operation/serialization#metabase-uses-entity-ids-to-identify-and-reference-metabase-items). On the dashboard, click on the **info** button. On the **Overview** tab, look for the dashboard's **Entity ID**. Copy that Entity ID. You'll use that Entity ID in the iframe's `src` URL: (e.g., `src=/dashboard/entity/[Entity ID]`). + +### Enable interactive embedding + +In Metabase, click on the **gear** icon in the upper right and go to **Admin settings** > **Settings** > **Embedding**. Look for **Interactive Embedding** and click on the **Enabled** toggle. + +Click on the **Configure** button under **Interactive Embedding**. Under **Authorized origins**, add the URL of the website or web app where you want to embed Metabase. If you're running your app locally, you can add localhost and specify the port number, e.g. `http://localhost:8080`. + +#### SameSite configuration + +If you're embedding Metabase in a different domain, you may need to [set the session cookie's SameSite value to `none`](./interactive-embedding#embedding-metabase-in-a-different-domain) + +### Set up SSO with JWT in your Metabase + +#### Enable authentication with JWT + +While still in the Admin panel's **Settings** section, click on **Authentication**. + +On the card that says **JWT**, click the **Setup** button (you may have to scroll down to view the JWT card). + +![Admin settings: Authentication > JTW setup.](./images/jwt-setup.png) + +#### Set JWT Identity provider URI + +In your app, you'll create a route for SSO at `/sso/metabase`. In the **JWT IDENTITY PROVIDER URI** field, enter the URL of your SSO route. For example, our sample app runs on port 8080, so in that case this JWT IDENTITY PROVIDER URI could be `http://localhost:8080/sso/metabase`. + +#### Generate a JWT signing key + +Click on the **Generate key** button to generate a signing key. Keep this key a secret. You'll use it on your server. If you generate another key, you'll overwrite the existing key, so you'll need to update the key in your app as well. + +Copy this key, as you'll need it in the next section. + +### Save and enable JWT authentication + +We'll set up group synchronization later, but for now, be sure to click the **Save and enable** button to activate JWT authentication. + +## Set up SSO with JWT in your app's server + +### Add the signing key and Metabase site URL to your app + +Here you'll need to input some values for your SSO to work. + +You'll want to declare up two constants in your app: + +- `METABASE_JWT_SHARED_SECRET`, paste the JWT signing key that you got from your Metabase here. +- `METABASE_SITE_URL`, which points to your Metabase's root path. + +```javascript +const METABASE_JWT_SHARED_SECRET = "YOURSIGNINGKEY"; +const METABASE_SITE_URL = "https://your-domain.metabaseapp.com"; +``` + +The signing key should preferably be setup as an environment variable, to avoid accidentally committing your key to your app's repo. + +### Add a JWT library to your app's server + +Add a JWT library to your app. For example, if you're using a Node backend with JavaScript, we recommend using [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken). + +In your terminal: + +```sh +npm install jsonwebtoken --save +``` + +And in your app, require the library: + +```javascript +{% include_file "{{ dirname }}/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts" snippet="jsonwebtoken-import" %} +``` + +### Restricting access to certain routes + +Presumably, your app already has some way of making sure some routes are only accessible after having signed in. Our examples use a simple helper function named `restrict` that protects these routes: + +```javascript +{% include_file "{{ dirname }}/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts" snippet="restrict-helper" %} +``` + +### Add a function to sign users + +We need to write a function to sign user JWTs, using the JWT library. + +```javascript +{% include_file "{{ dirname }}/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts" snippet="sign-user-token-helper" %} +``` + +### Add a `sso/metabase` route + +You'll need to add a route to sign people in to your Metabase via SSO using JWT. If the person isn't signed in to your app yet, your app should redirect them through your sign-in flow. In the code below, this check and redirection is handled by the `restrict` function we introduced earlier. + +```javascript +{% include_file "{{ dirname }}/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts" snippet="sso-route" %} +``` + +If the person has never signed in to Metabase before, Metabase will create an account for them. + +### CHECKPOINT: sign in to your Metabase using SSO + +Make sure you are signed out of your Metabase. From the Metabase sign-in page, click on "Sign in with SSO". You should be redirected to your app. + +Log in to your app. Your app should redirect you to your Metabase welcome page. If the person doesn't yet have a Metabase account, Metabase should create an account for them. + +## Embed Metabase in your app + +Now to embed your Metabase in your app. You'll want to set up a route to serve your embedded analytics. Let's call it `/analytics`. Note that we're using the `restrict` helper function (defined above) because this page should only be viewable after people sign in to your app. + +In this route, we need to render an iframe that will load your Metabase. The `src` attribute of the iframe should point to the relative path of the SSO endpoint of your app. Once the person signs in to your app (and therefore in to your Metabase), we add the query string parameter `return_to` so that the iframe displays the requested dashboard. + +`METABASE_DASHBOARD_PATH` should be pointing to the relative path of the dashboard you created at the beginning of this guide (`/dashboard/[ID]`, or if you used the dashboard's Entity ID: `/dashboard/entity/[Entity ID]`). + +```javascript +{% include_file "{{ dirname }}/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts" snippet="analytics-route" %} +``` + +The `METABASE_DASHBOARD_PATH` is just the first thing people will see when they log in, but you could set that path to any Metabase URL. And since you're embedding the full Metabase, people will be able to drill through the data and view other questions, dashboards, and collections. + +### CHECKPOINT: view a Metabase dashboard in your app + +People using your app should now be able to access `/analytics` and view your embedded Metabase dashboard. + +How to test: Sign in to your app and visit the `/analytics` route. You should see the Metabase dashboard. + +> If you're using the Safari browser, and you're serving Metabase and your app from different domains, you may need to go to Safari's settings and turn off [Prevent cross-site tracking](https://support.apple.com/guide/safari/prevent-cross-site-tracking-sfri40732/mac). + +## Set up a group in Metabase + +Now that you have SSO and interactive embedding set up, it's time to set up groups so that you can apply permissions to your embedded Metabase entities (questions, dashboards, collections, and so on). + +### Add a `groups` key to your token + +Recall the `signUserToken` function used to create the JWTs. Add a `groups` key to the signed token that maps to an array. Metabase will look at the values in that array to see if any of the values map to a group in Metabase (We'll walk through mapping groups in a bit). + +```javascript +{% include_file "{{ dirname }}/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts" snippet="user-groups-sign-user-token-helper" %} +``` + +### Create a group in Metabase + +In Metabase, click the **gear** icon and go to **Admin settings** > **People** > **Groups**. Click the **Create a group** button. Add a group that corresponds with a group in your app. If you're using the sample app, add a group called `Customer Acme`. + +### Synchronize groups between Metabase and your app + +You'll map this string in the `groups` key to a Metabase group, so that when the person signs in via SSO, Metabase automatically assigns them to the appropriate Metabase group. + +In Metabase's admin section, go to **Settings** > **Authentication**. Scroll to the **JWT** card and click **Edit**. + +In the **Group schema** section, toggle on **Synchronize group memberships**. For each group you want to sync, add a group mapping. When you click **New mapping**, enter "Customer-Acme", the string that you included in the `groups` array in your JWT payload. You can then associate that group name with the Metabase group "Customer Acme" that we created earlier. + +![Mapping user attributes to groups.](./images/sync-groups.png) + +Be sure to **Save changes**. + +### CHECKPOINT: verify that Metabase assigns people to groups when they log in + +First, sign out of Metabase and sign in using SSO. + +Then sign out and sign in to your Metabase as an admin and go to **Admin settings** > **People** section and verify that Metabase added the person to the appropriate group. + +Note: only Metabase admins and group managers are aware of groups. Basic users have no concept of groups, and no way of knowing which groups they're a part of. + +## Set permissions + +Now to apply permissions to that group so that people only see data specific to their accounts. + +### Reset permissions for the All Users group + +Metabase ships with two initial groups: "Admins" and "All Users". By default, Metabase gives the "All Users" group access to connected data sources. And since Metabase grants people the privileges of their most permissive group, you'll want to restrict what the "All Users" groups can see before you add them to groups with limited or no access to data sources and collections. + +To reset permissions for the All users group, click on the **gear** icon and go to **Admin settings** > **Permissions**. Under the **Data** tab, go to **Groups** and select **All Users**. For the **Sample Database** in the **View data** column, select "Blocked". Click **Save changes** and a modal will pop up summarizing what you're changing. Click **Yes**. + +![Resetting permissions of the All Users group to](./images/all-users.png) + +### Allow view access to the automatically generated dashboards collection + +Still in the **Permissions** tab, click on the **Collections** sub-tab, then on the **Automatically generated dashboards** collection, and set the **Collection access** permissions for the **All Users** group to **View**. + +Click **Save changes**, then **Yes**. + +### Add a user attribute to the token + +You can include user attributes in the JSON web token. Metabase will pick up any keys from the JWT payload and store them as user attributes. Among other use cases, you can use these user attributes to set row-level permissions on tables, so people can only see results tied to their accounts. + +If you're using our sample app, edit the `signUserToken` function used to create the JWT by adding a key `account_id` with value `28`. + +```javascript +{% include_file "{{ dirname }}/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts" snippet="user-attribute-sign-user-token-helper" %} +``` + +That user ID will correspond to the `Account ID` column in the Sample Database's Invoices table. We'll use this `account_id` user attribute to sandbox the Invoices table, so people will only see rows in that table that contain their account ID. + +Note that to persist the user attribute in Metabase, you'll need to log in. Log in to your app as a non-admin, and visit the page with your embedded Metabase. + +### Set row-level permissions with data sandboxing + +In Metabase, go to **Admin settings** > **Permissions**. Under the **Data** tab on the left, click on a group. For "Sample Database", change its **Data access** column to **Granular**. + +Metabase will display a list of the tables in the database. Next, change **Data access** for the "Invoices" table to **Sandboxed**. + +![Sandboxing a table.](./images/sandboxed-invoices-table.png) + +Next, Metabase will prompt you with a modal to associate a column in that table with a user attribute. + +Leave the **Filter by a column in a table** option checked, and associate the "Account ID" column in the Invoices table with the user attribute `account_id`. (Note that Metabase will only display the user attributes if the user has signed in through SSO before.) + +![Mapping a column in the sandboxed table to a user attribute.](./images/map-user-attribute.png) + +Click **Save** to confirm your select. Then click the **Save changes** button in the upper right. + +Metabase will ask if you're sure you want to do this. You are sure. + +### CHECKPOINT: view sandboxed dashboard + +Make sure you've logged out of your previous session. + +Log in to your app, navigate to `/analytics`. The dashboard will now present different information, since only a subset of the data is visible to this person. Click on **Browse Data** at the bottom of the left nav. View your sandboxed **Invoices** table, and you should only see rows in that table that are associated with the person's account. + +## Hiding Metabase elements + +You can decide to [show or hide various Metabase elements](./interactive-embedding#showing-or-hiding-metabase-ui-components), like whether to show the nav bar, search or the **+New** button, and so on. + +For example, to hide the logo and the top navigation bar of your embedded Metabase, you'd append the query string parameters `?logo=false&top_nav=false` to the `return_to` URL that you include in the SSO redirect. + +In the handler of your `/sso/metabase` path, add the query parameters: + +```javascript +{% include_file "{{ dirname }}/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts" snippet="hide-metabase-elements" %} +``` + +### CHECKPOINT: verify hidden UI elements + +Sign out and sign in to your app again and navigate to `/analytics`. Your embedded Metabase should not include the logo or the top navigation. + +## Next steps + +You can [customize how Metabase looks](../configuring-metabase/appearance) in your app: fonts, colors, and logos. diff --git a/_docs/doc-update-detection/embedding/interactive-embedding.md b/_docs/doc-update-detection/embedding/interactive-embedding.md new file mode 100644 index 000000000..8a339f72b --- /dev/null +++ b/_docs/doc-update-detection/embedding/interactive-embedding.md @@ -0,0 +1,380 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Interactive embedding' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/interactive-embedding.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/full-app-embedding + - /docs/doc-update-detection/embedding/full-app-embedding +--- + +# Interactive embedding + +{% include plans-blockquote.html feature="Interactive embedding" %} + +{% include shared/in-page-promo-embedding-workshop.html %} + +**Interactive embedding** is what you want if you want to offer [multi-tenant, self-service analytics](/learn/metabase-basics/embedding/multi-tenant-self-service-analytics). + +Interactive embedding is the only type of embedding that integrates with your [permissions](../permissions/introduction) and [SSO](../people-and-groups/start#authentication) to give people the right level of access to [query](/glossary/query_builder) and [drill-down](/learn/metabase-basics/querying-and-dashboards/questions/drill-through) into your data. + +## Interactive embedding demo + +To get a feel for what you can do with interactive embedding, check out our [interactive embedding demo](/embedding-demo). + +To see the query builder in action, click on **Reports** > **+ New** > **Question**. + +## Quick start + +Check out the [Interactive embedding quick start](/docs/latest/embedding/interactive-embedding-quick-start-guide). + +## Prerequisites for interactive embedding + +1. Make sure you have a [license token](../installation-and-operation/activating-the-enterprise-edition) for a [Pro or Enterprise plan](https://store.metabase.com/checkout/login-details). +2. Organize people into Metabase [groups](../people-and-groups/start). +3. Set up [permissions](../permissions/introduction) for each group. +4. Set up [SSO](../people-and-groups/start#authentication) to automatically apply permissions and show people the right data upon sign-in. In general, **we recommend using [SSO with JWT](../people-and-groups/authenticating-with-jwt)**. + +If you're dealing with a [multi-tenant](/learn/metabase-basics/embedding/multi-tenant-self-service-analytics) situation, check out our recommendations for [Configuring permissions for different customer schemas](/learn/metabase-basics/administration/permissions/multi-tenant-permissions). + +If you have your app running locally, and you're using the Pro Cloud version, or hosting Metabase and your app in different domains, you'll need to set your Metabase environment's session cookie samesite option to "none". + +## Enabling interactive embedding in Metabase + +1. Go to **Settings** > **Admin settings** > **Embedding**. +2. Click **Enable**. +3. Click **Interactive embedding**. +4. Under **Authorized origins**, add the URL of the website or web app where you want to embed Metabase (such as `https://*.example.com`). + +## Setting up embedding on your website + +1. Create an iframe with a `src` attribute set to: + - the [URL](#pointing-an-iframe-to-a-metabase-url) of the Metabase page you want to embed, or + - an [authentication endpoint](#pointing-an-iframe-to-an-authentication-endpoint) that redirects to your Metabase URL. +2. Optional: Depending on the way your web app is set up, set [environment variables](../configuring-metabase/environment-variables) to: + - [Add your license token](../configuring-metabase/environment-variables#mb_premium_embedding_token). + - [Embed Metabase in a different domain](#embedding-metabase-in-a-different-domain). + - [Secure your interactive embed](#securing-interactive-embeds). +3. Optional: Enable communication to and from the embedded Metabase using supported [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) messages: + - [From Metabase](#supported-postmessage-messages-from-embedded-metabase) + - [To Metabase](#supported-postmessage-messages-to-embedded-metabase) +4. Optional: Set parameters to [show or hide Metabase UI components](#showing-or-hiding-metabase-ui-components). + +Once you're ready to roll out your interactive embed, make sure that people **allow** browser cookies from Metabase, otherwise they won't be able to log in. + +### Pointing an iframe to a Metabase URL + +Go to your Metabase and find the page that you want to embed. + +For example, to embed your Metabase home page, set the `src` attribute to your [site URL](../configuring-metabase/settings#site-url), such as: + +``` +src="http://metabase.yourcompany.com/" +``` + +To embed a specific Metabase dashboard, you'll want to use the dashboard's Entity ID URL `/dashboard/entity/[Entity ID]`. + +``` +src="http://metabase.yourcompany.com/dashboard/entity/[Entity ID]" +``` + +To get a dashboard's Entity ID, visit the dashboard and click on the **info** button. In the **Overview** tab, copy the **Entity ID**. Then in your iframe's `src` attribute to: + +``` +src=http://metabase.yourcompany.com/dashboard/entity/Dc_7X8N7zf4iDK9Ps1M3b +``` + +If your dashboard has more than one tab, select the tab you want people to land on and copy the Tab's ID. Add the tab's ID to the URL: + +``` +src=http://metabase.yourcompany.com/dashboard/entity/Dc_7X8N7zf4iDK9Ps1M3b?tab=YLNdEYtzuSMA0lqO7u3FD +``` + +You _can_ use a dashboard's sequential ID, but you should prefer the Entity ID, as Entity IDs are stable across different Metabase environments (e.g., if you're testing on a staging environment, the Entity IDs will remain the same when [exporting the data and importing it](../installation-and-operation/serialization) into a production environment). + +If you want to point to a question, collection, or model, visit the item, click on its info, grab the item's Entity ID and follow the url structure: `/[Item type]/entity/[Entity-Id]`. Examples: + +- `/collection/entity/[Entity ID]` +- `/model/entity/[Entity ID]` +- `/question/entity/[Entity ID]` + +### Pointing an iframe to an authentication endpoint + +Use this option if you want to send people directly to your SSO login screen (i.e., skip over the Metabase login screen with an SSO button), and redirect to Metabase automatically upon authentication. + +You'll need to set the `src` attribute to your auth endpoint, with a `return_to` parameter pointing to the encoded Metabase URL. For example, to send people to your SSO login page and automatically redirect them to `http://metabase.yourcompany.com/dashboard/1`: + +``` +https://metabase.example.com/auth/sso?return_to=http%3A%2F%2Fmetabase.yourcompany.com%2Fdashboard%2F1 +``` + +If you're using [JWT](../people-and-groups/authenticating-with-jwt), you can use the relative path for the redirect (i.e., your Metabase URL without the [site URL](../configuring-metabase/settings#site-url)). For example, to send people to a Metabase page at `/dashboard/1`: + +``` +https://metabase.example.com/auth/sso?jwt=&return_to=%2Fdashboard%2F1 +``` + +You must URL encode (or double encode, depending on your web setup) all of the parameters in your redirect link, including parameters for filters (e.g., `filter=value`) and [UI settings](#showing-or-hiding-metabase-ui-components) (e.g., `top_nav=true`). For example, if you added two filter parameters to the JWT example shown above, your `src` link would become: + +``` +https://metabase.example.com/auth/sso?jwt=&redirect=%2Fdashboard%2F1%3Ffilter1%3Dvalue%26filter2%3Dvalue +``` + +## Cross-browser compatibility + +To make sure that your embedded Metabase works in all browsers, put Metabase and the embedding app in the same top-level domain (TLD). The TLD is indicated by the last part of a web address, like `.com` or `.org`. + +Note that your interactive embed must be compatible with Safari to run on _any_ browser in iOS (such as Chrome on iOS). + +## Embedding Metabase in a different domain + +> Skip this section if your Metabase and embedding app are already in the same top-level domain (TLD). + +If you want to embed Metabase in another domain (say, if Metabase is hosted at `metabase.yourcompany.com`, but you want to embed Metabase at `yourcompany.github.io`), you can tell Metabase to set the session cookie's SameSite value to "none". + +You can set session cookie's SameSite value in **Admin settings** > **Embedding** > **Interactive embedding** > **SameSite cookie setting**. + +SameSite values include: + +- **Lax** (default): Allows cookies to be sent when someone navigates to the origin site from an external site (like when following a link). +- **None**: Allows all cross-site requests. Incompatible with most Safari and iOS browsers, such as Chrome on iOS. If you set this environment variable to "None", you must use HTTPS in Metabase to prevent browsers from rejecting the request. +- **Strict** (not recommended): Never allows cookies to be sent on a cross-site request. Warning: this will prevent users from following external links to Metabase. + +You can also set the [`MB_SESSION_COOKIE_SAMESITE` environment variable](../configuring-metabase/environment-variables#mb_session_cookie_samesite). + +If you're using Safari, you'll need to [allow cross-site tracking](https://support.apple.com/en-tj/guide/safari/sfri40732/mac). Depending on the browser, you may also run into issues when viewing emdedded items in private/incognito tabs. + +Learn more about [SameSite cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite). + +## Securing interactive embeds + +Metabase uses HTTP cookies to authenticate people and keep them signed into your embedded Metabase, even when someone closes their browser session. If you enjoy diagrammed auth flows, check out [Interactive embedding with SSO](/learn/metabase-basics/embedding/securing-embeds). + +To limit the amount of time that a person stays logged in, set [`MAX_SESSION_AGE`](../configuring-metabase/environment-variables#max_session_age) to a number in minutes. The default value is 20,160 (two weeks). + +For example, to keep people signed in for 24 hours at most: + +```sh +MAX_SESSION_AGE=1440 +``` + +To automatically clear a person's login cookies when they end a browser session: + +```sh +MB_SESSION_COOKIES=true +``` + +To manually log someone out of Metabase, load the following URL (for example, in a hidden iframe on the logout page of your application): + +```sh +https://metabase.yourcompany.com/auth/logout +``` + +If you're using [JWT](../people-and-groups/authenticating-with-jwt) for SSO, we recommend setting the `exp` (expiration time) property to a short duration (e.g., 1 minute). + +## Supported postMessage messages _from_ embedded Metabase + +To keep up with changes to an embedded Metabase URL (for example, when a filter is applied), set up your app to listen for "location" messages from the embedded Metabase. If you want to use this message for deep-linking, note that "location" mirrors "window.location". + +```json +{ + "metabase": { + "type": "location", + "location": LOCATION_OBJECT_OR_URL + } +} +``` + +To make an embedded Metabase page (like a question) fill up the entire iframe in your app, set up your app to listen for a "frame" message with "normal" mode from Metabase: + +```json +{ + "metabase": { + "type": "frame", + "frame": { + "mode": "normal" + } + } +} +``` + +To specify the size of an iframe in your app so that it matches an embedded Metabase page (such as a dashboard), set up your app to listen for a "frame" message with "fit" mode from Metabase: + +```json +{ + "metabase": { + "type": "frame", + "frame": { + "mode": "fit", + "height": HEIGHT_IN_PIXELS + } + } +} +``` + +## Supported postMessage messages _to_ embedded Metabase + +To change an embedding URL, send a "location" message from your app to Metabase: + +```json +{ + "metabase": { + "type": "location", + "location": LOCATION_OBJECT_OR_URL + } +} +``` + +## Group strategies with sandboxing + +If you want multiple people from a single customer account to collaborate on questions and dashboards, you'll need to set up one [group](../people-and-groups/managing#groups) per customer account. + +You can handle [data sandboxing](../permissions/data-sandboxes) with a single, separate group that just sandboxes your data. For example, each person could be part of a customer group that sets up data permissions with sandboxing via a certain attribute that applies to everyone across all your customer accounts. + +Additionally, each person within a single customer account could also be a member of a group specific to that customer account. That way they can collaborate on collections with other people in their organization, without seeing stuff created by people from other customers' accounts. + +## Showing or hiding Metabase UI components + +To change the interface of your interactive embed, you can add parameters to the end of your embedding URL. If you want to change the colors or fonts in your embed, see [Customizing appearance](../configuring-metabase/appearance). + +For example, you can disable Metabase's [top nav bar](#top_nav) and [side nav menu](#side_nav) like this: + +``` +your_embedding_url?top_nav=false&side_nav=false +``` + +![Top nav and side nav disabled](./images/no-top-no-side.png) + +Options include: + +- [Action buttons](#action_buttons) +- [Additional info](#additional_info) +- [Breadcrumbs](#breadcrumbs) +- [Header](#header) +- [Locale](#locale) +- [Logo](#logo) +- [New button](#new_button) +- [Search](#search) +- [Side nav](#side_nav) +- [Top nav](#top_nav) + +> To make sure that query parameters are preserved when using [click behavior](../dashboards/interactive#customizing-click-behavior), configure the [Site URL](../configuring-metabase/settings#site-url) Admin setting to be your Metabase server URL. + +### `action_buttons` + +Visible by default on question pages when the [header](#header) is enabled. + +To hide the action buttons such as **Filter**, **Summarize**, the query builder button, and so on: + +``` +header=false&action_buttons=false +``` + +![Action buttons](./images/action-buttons.png) + +### `additional_info` + +Visible by default on question and dashboard pages, when the [header](#header) is enabled. + +To hide the gray text "Edited X days ago by FirstName LastName", as well as the breadcrumbs with collection, database, and table names: + +`header=false&additional_info=false` + +![Additional info](./images/additional-info.png) + +### `breadcrumbs` + +Shown by default in the top nav bar. Collection breadcrumbs show the path to the item (i.e., the collection(s) the item is in). To hide the breadcrumbs: + +``` +breadcrumbs=false +``` + +### `header` + +Visible by default on question and dashboard pages. + +To hide a question or dashboard's title, [additional info](#additional_info), and [action buttons](#action_buttons): + +`header=false` + +### `locale` + +You can change the language of the user interface via a parameter. For example, to set the locale to Spanish: + +``` +locale=es +``` + +Read more about [localization](../configuring-metabase/localization). + +### `logo` + +Whether to show the logo that opens and closes the sidebar nav. Default is true. How Metabase displays the logo depends on the `side_nav` setting. Here's a rough breakdown of how these two parameters interact: + +If `logo=true` and: + +- `side_nav=true`: Looks like regular Metabase (with whatever logo you have set). +- `side_nav=false`: There is no sidebar, so nothing happens when you hover over the logo. + +If `logo=false` and: + +- `side_nav=true`: Metabase shows the generic sidebar icon, with a gray color in normal state, and a brand color on hover. +- `side_nav=false`: There is no side nav nor logo, so the breadcrumbs move all the way to the left of the screen. + +### `new_button` + +Hidden by default. To show the **+ New** button used to create queries or dashboards: + +``` +top_nav=true&new_button=true +``` + +### `search` + +Hidden by default. To show the search box in the top nav: + +``` +top_nav=true&search=true +``` + +### `side_nav` + +The navigation sidebar is shown on `/collection` and home page routes, and hidden everywhere else by default. + +To allow people to minimize the sidebar: + +``` +top_nav=true&side_nav=true +``` + +![Side nav](./images/side-nav.png) + +### `top_nav` + +Shown by default. To hide the top navigation bar: + +``` +top_nav=false +``` + +![Top nav bar](./images/top-nav.png) + +`search`, `new_button`, and `breadcrumbs` all depend on `top_nav` being set to `true`. If these three children (`search`, `new_button`, and `breadcrumbs`) are all false, Metabase will hide the top nav bar. + +## Reference apps + +To build a sample interactive embed using SSO with JWT, see our reference apps: + +- [Node.js + Express](https://github.com/metabase/metabase-nodejs-express-interactive-embedding-sample) (with [quick start guide](/docs/latest/embedding/interactive-embedding-quick-start-guide)) +- [Node.js + React](https://github.com/metabase/sso-examples/tree/master/app-embed-example) + +## Further reading + +- [Interactive embedding quick start](/docs/latest/embedding/interactive-embedding-quick-start-guide) +- [Strategies for delivering customer-facing analytics](/learn/metabase-basics/embedding/overview). +- [Permissions strategies](/learn/metabase-basics/administration/permissions/strategy). +- [Customizing Metabase's appearance](../configuring-metabase/appearance). diff --git a/_docs/doc-update-detection/embedding/introduction.md b/_docs/doc-update-detection/embedding/introduction.md new file mode 100644 index 000000000..fb165b01f --- /dev/null +++ b/_docs/doc-update-detection/embedding/introduction.md @@ -0,0 +1,72 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedding introduction' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/introduction.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/13-embedding +--- + +# Embedding introduction + +You can embed Metabase tables, charts, and dashboards—even Metabase's query builder—in your website or application. + +Here are the different ways you can embed Metabase. + +{% include shared/in-page-promo-embedding-workshop.html %} + +## Embedded analytics SDK with React + +With the [Embedded analytics SDK](./sdk/introduction), you can embed individual Metabase components with React (like standalone charts, dashboards, the query builder, and more). You can manage access and interactivity per component, and you have advanced customization for seamless styling. + +**When to use the Embedded analytics SDK**: you want the most control over how you embed Metabase in your React app. + +## Interactive embedding + +Interactive embedding is the only kind of embedding that [integrates with SSO and data permissions](./interactive-embedding) to enable true self-service access to the underlying data. + +**When to use interactive embedding**: you want to [offer multi-tenant, self-service analytics](/blog/why-full-app-embedding). With interactive embedding, people can create their own questions, dashboards, models, and more, all in their own data sandbox. + +## Static embedding + +Also known as signed embedding, [static embedding](./static-embedding) is a secure way to embed charts and dashboards. + +**When to use static embedding**: you don't want to offer ad-hoc querying or chart drill-through. To filter data relevant to the viewer, you can use static embeds with [locked parameters](./static-embedding-parameters#locked-parameters-limit-the-values-available-to-other-editable-parameters). + +## Public links and embeds + +If you'd like to share your data with the good people of the internet, admins can create a [public link](./public-links) or embed a question or dashboard directly in your website. + +**When to use public links and embeds**: public links and embeds are good for one-off charts and dashboards. Admins can use them when you just need to show someone a chart or dashboard without giving people access to your Metabase. And you don't care who sees the data; you want to make those stats available to everyone. + +## Comparison of embedding types + +| Action | [Embedded analytics SDK](./sdk/introduction) | [Interactive](./interactive-embedding) | [Static](./static-embedding) | [Public](../embedding/public-links) | +| ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | ----------------------------------------- | ------------------------------- | -------------------------------------- | +| Display charts and dashboards | ✅ | ✅ | ✅ | ✅ | +| Display interactive [filter widgets](/glossary/filter_widget) | ✅ | ✅ | ✅ | ✅ | +| Export results\* | ✅ | ✅ | ✅ | ✅ | +| Restrict data with [locked filters](./static-embedding-parameters#restricting-data-in-a-static-embed-with-locked-parameters) | ❌ | ❌ | ✅ | ❌ | +| Restrict data with [sandboxes](../permissions/data-sandboxes) | ✅ | ✅ | ❌ | ❌ | +| Use the [drill-through menu](/learn/metabase-basics/querying-and-dashboards/questions/drill-through) | ✅ | ✅ | ❌ | ❌ | +| Self-serve via [query builder](/glossary/query_builder) | ✅ | ✅ | ❌ | ❌ | +| View usage of embeds with [usage analytics](../usage-and-performance-tools/usage-analytics) | ✅ | ✅ | ❌ | ❌ | +| [Actions on dashboards](../dashboards/actions) | ✅ | ✅ | ❌ | ❌ | +| Embed individual Metabase components | ✅ | ❌ | ❌ | ❌ | +| Manage access and interactivity per component | ✅ | ❌ | ❌ | ❌ | + +\* Each embedding type allows data downloads by default, but only [Pro and Enterprise](/pricing/) plans can disable data downloads. + +## Switching from static to interactive embedding + +[Interactive embedding](./interactive-embedding) requires authentication via single sign-on (SSO), so you'll need to set that up both in your Metabase and in your application's server. Check out our [Interactive embedding quick start](/docs/latest/embedding/interactive-embedding-quick-start-guide). + +## Further reading + +- [Strategies for delivering customer-facing analytics](/learn/metabase-basics/embedding/overview). +- [Publishing data visualizations to the web](/learn/metabase-basics/embedding/charts-and-dashboards). +- [Multi-tenant self-service analytics](/learn/metabase-basics/embedding/multi-tenant-self-service-analytics). +- [Customizing Metabase's appearance](../configuring-metabase/appearance). diff --git a/_docs/doc-update-detection/embedding/public-links.md b/_docs/doc-update-detection/embedding/public-links.md new file mode 100644 index 000000000..b717e0eb3 --- /dev/null +++ b/_docs/doc-update-detection/embedding/public-links.md @@ -0,0 +1,197 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Public sharing' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/public-links.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/12-public-links + - /docs/doc-update-detection/embedding/12-public-links +--- + +# Public sharing + +> Only admins can create public links and iframes. + +Admins can create and share public links (URLs) for questions and dashboards. People can view them as standalone destinations (URLs) or as embedded iframes in another page or app. In both cases, the public item will display static (view-only) results of your question or dashboard, so visitors won't be able to drill-down into the underlying data on their own. + +## Create a public link for a question + +![Create a public link for a question](./images/create-a-public-link.png) + +To create a public link for a question, admins can click on the **Sharing** icon at the top right of a question and select **Create a public link**. Copy the link and test it out by viewing the link in a private/incognito browser session. + +## Public link to export question results in CSV, XLSX, JSON + +This export option is only available for questions, not dashboards. + +To create a public link that people can use to download the results of a question: + +1. Click on the **Sharing** icon for the question. +2. Select **Create a public link**. +3. Click on the file format you want (below the **Public link** URL): CSV, XLSX, or JSON. + +![Public export](./images/public-export.png) + +Open the public link in a new tab to test the download. + +## Create a public link for a dashboard + +To share a dashboard via a public link, admins can click on the **Sharing** button in the top right menu. + +![Sharing a dashboard](./images/dashboard-sharing.png) + +To embed a dashboard, see [static embedding](./static-embedding). + +## Exporting raw, unformatted question results + +To export the raw, unformatted rows, you'll need to append `?format_rows=false` to the URL Metabase generates. For example, if you create a public link for a CSV download, the URL would look like: + +```html +https://www.example.com/public/question/cf347ce0-90bb-4669-b73b-56c73edd10cb.csv?format_rows=false +``` + +By default, Metabase will export the results of a question that include any formatting you added (for example, if you formatted a column with floats to display as a percentage (0.42 -> 42%)). + +See docs for the [export format endpoint](/docs/latest/api#tag/public/GET/public/card/{uuid}/query/{export-format}). + +## Simulating drill-through with public links + +Metabase's automatic [drill-through](/learn/metabase-basics/querying-and-dashboards/questions/drill-through) won't work on public dashboards because public links don't give people access to your raw data. + +You can simulate drill-through on a public dashboard by setting up a [custom click behavior](../dashboards/interactive) that sends people from one public link to another public link. + +1. Create a second dashboard to act as the destination dashboard. +2. [Create a public link](#create-a-public-link-for-a-dashboard) for the destination dashboard. +3. Copy the destination dashboard's public link. +4. On your primary dashboard, create a [custom destination](../dashboards/interactive#custom-destinations) with type "URL". +5. Set the custom destination to the destination dashboard's public link. +6. Optional: pass a filter value from the primary dashboard to the destination dashboard by adding a query parameter to the end of the destination URL: + +``` +{%raw%} +/public/dashboard/?child_filter_name={{parent_column_name}} +{%endraw%} +``` + +For example, if you have a primary public dashboard that displays **Invoices** data, you can pass the **Plan** name (on click) to a destination public dashboard that displays **Accounts** data: + +![Public link with custom destination](./images/public-link-custom-destination.png) + +## Public embeds + +![Public embed](./images/public-embed.png) + +If you want to embed your question or dashboard as an iframe in a simple web page or app: + +1. Click on the **Sharing** icon for your question or dashboard. +2. Click **Embed**. +3. In the bottom of the embedding popup, click on **Get embedding code**. +4. Copy the iframe snippet Metabase generates for you. +5. Paste the iframe snippet in your destination of choice. + +To customize the appearance of your question or dashboard, you can update the link in the `src` attribute with [public embed parameters](#public-embed-parameters). + +## Public embed parameters + +To apply appearance or filter settings to your public embed, you can add parameters to the end of the link in your iframe's `src` attribute. + +Note that it's possible to find the public link URL behind a public embed. If someone gets access to the public link URL, they can remove the parameters from the URL to view the original question or dashboard (that is, without any appearance or filter settings). + +If you'd like to create a secure embed that prevents people from changing filter names or values, check out [static embedding](./static-embedding). + +## Appearance parameters + +To toggle appearance settings, add _hash_ parameters to the end of the public link in your iframe's `src` attribute. + +See [appearance parameters](./static-embedding-parameters#customizing-the-appearance-of-a-static-embed). + +## Filter parameters + +You can display a filtered view of your question or dashboard in a public embed. Make sure you've set up a [question filter](../questions/query-builder/filters) or [dashboard filter](../dashboards/filters) first. + +To apply a filter to your embedded question or dashboard, add a _query_ parameter to the end of the link in your iframe's `src` attribute, like this: + +``` +/dashboard/42?filter_name=value +``` + +For example, say that we have a dashboard with an "ID" filter. We can give this filter a value of 7: + +``` +/dashboard/42?id=7 +``` + +To set the "ID" filter to a value of 7 _and_ hide the "ID" filter widget from the public embed: + +``` +/dashboard/42?id=7#hide_parameters=id +``` + +To specify multiple values for filters, separate the values with ampersands (&), like this: + +``` +/dashboard/42?id=7&name=janet +``` + +You can hide multiple filter widgets by separating the filter names with commas, like this: + +``` +/dashboard/42#hide_parameters=id,customer_name +``` + +Note that the name of the filter in the URL should be specified in lower case, and with underscores instead of spaces. If your filter is called "Filter for User ZIP Code", you'd write: + +``` +/dashboard/42?filter_for_user_zip_code=02116 +``` + +## Disable public sharing + +Public sharing is enabled by default. + +![Enable public sharing](./images/enable-public-sharing.png) + +To disable public sharing: + +1. Click on the **Gear** icon in the upper right. +2. Select **Admin settings**. +3. In the **Settings** tab, select **Public sharing**. +4. Toggle off **Public sharing**. + +Once toggled on, the **Public sharing** section will display Metabase questions, dashboards, and actions with active public links. + +If you disable public sharing, then re-enable public sharing, all your previously generated public links will still work (as long as you didn't deactivate them). + +## Deactivating public links and embeds + +### Individual question or dashboard links and embeds + +1. Visit the question or dashboard. +2. Click on **Sharing** icon. +3. Select **Public link** or **Embed**. +4. Click **Remove public link**. + +## Deactivating multiple public links and embeds + +Admins can view and deactivate all public links for a Metabase. + +1. Click on the **gear** icon in the upper right. +2. Select **Admin settings**. +3. Go to the **Settings** tab. +4. Go to the **Public sharing** tab in the left sidebar. +5. For each item you want to deactivate, click on the **X** to revoke its public link. + +## See all publicly shared content + +Admins can see all publicly shared questions, dashboards, and actions in **Admin Settings > Public Sharing**. + +![See shared content](./images/see-shared-content.png) + +## Further reading + +- [Publishing data visualizations to the web](/learn/metabase-basics/embedding/charts-and-dashboards). +- [Customizing Metabase's appearance](../configuring-metabase/appearance). +- [Embedding introduction](../embedding/start). diff --git a/_docs/doc-update-detection/embedding/sdk/appearance.md b/_docs/doc-update-detection/embedding/sdk/appearance.md new file mode 100644 index 000000000..1b4118737 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/appearance.md @@ -0,0 +1,35 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - appearance' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/appearance.md' +--- + +# Embedded analytics SDK - appearance + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +You can style your embedded Metabase components with a theme. + +Here's an example that includes the various styling options available: + +```ts +{% include_file "{{ dirname }}/snippets/appearance/theme.ts" %} +``` + +### Customizing loader and error components + +You can provide your own components for loading and error states by specifying `loaderComponent` and `errorComponent` as props to `MetabaseProvider`. + +```tsx +{% include_file "{{ dirname }}/snippets/appearance/customizing-loader-and-components.tsx" snippet="imports" %} + +{% include_file "{{ dirname }}/snippets/appearance/customizing-loader-and-components.tsx" snippet="example" %} +``` + +## Limitations + +Colors configured in a question's visualization settings will override theme colors. diff --git a/_docs/doc-update-detection/embedding/sdk/authentication.md b/_docs/doc-update-detection/embedding/sdk/authentication.md new file mode 100644 index 000000000..040f4a4ed --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/authentication.md @@ -0,0 +1,110 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - authentication' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/authentication.md' +--- + +# Embedded analytics SDK - authentication + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +For using the SDK in production, you'll need to set up authentication with JWT SSO. + +If you're developing locally, you can also set up authentication with [API keys](#authenticating-locally-with-api-keys). + +## Setting up JWT SSO + +Prerequisites: + +- [A Metabase Pro or Enterprise license](/pricing/) (If you don't have a license, check out [this quickstart](./quickstart)) + +To set up JWT SSO with Metabase and your app, you'll need to: + +1. [Enable JWT SSO in your Metabase](#1-enable-jwt-sso-in-your-metabase) +2. [Add a new endpoint to your backend to handle authentication](#2-add-a-new-endpoint-to-your-backend-to-handle-authentication) +3. [Wire the SDK in your frontend to your new endpoint](#3-wire-the-sdk-in-your-frontend-to-your-new-endpoint) + +### 1. Enable JWT SSO in your Metabase + +1. Configure JWT by going to **Admin Settings** > **Settings** > **Authentication** and clicking on **Setup** +2. Generate a key and copy it to your clipboard. + +### 2. Add a new endpoint to your backend to handle authentication + +You'll need add a library to your backend to sign your JSON Web Tokens. + +For Node.js, we recommend jsonwebtoken: + +``` +npm install jsonwebtoken --save +``` + +Next, set up your endpoint: this example code for Node.js sets up an endpoint in an app, `/sso/metabase`, that creates a token using the shared secret to authenticate calls to Metabase. + +```js +{% include_file "{{ dirname }}/snippets/authentication/express-server.ts" %} +``` + +### 3. Wire the SDK in your frontend to your new endpoint + +Update the SDK config in your frontend code to point your backend's authentication endpoint. + +```js +{% include_file "{{ dirname }}/snippets/authentication/auth-config-base.tsx" snippet="example" %} +``` + +(Optional) If you use headers instead of cookies to authenticate calls from your frontend to your backend, you'll need to use a [custom fetch function](#customizing-jwt-authentication). + +## If your frontend and backend don't share a domain, you need to enable CORS + +You can add some middleware in your backend to handle cross-domain requests. + +```js +{% include_file "{{ dirname }}/snippets/authentication/express-server-cors.ts" snippet="example" %} +``` + +## Getting Metabase authentication status + +You can query the Metabase authentication status using the `useMetabaseAuthStatus` hook. This is useful if you want to completely hide Metabase components when the user is not authenticated. + +This hook can only be used within components wrapped by `MetabaseProvider`. + +```jsx +{% include_file "{{ dirname }}/snippets/authentication/get-auth-status.tsx" snippet="example" %} +``` + +## Customizing JWT authentication + +You can customize how the SDK fetches the refresh token by specifying the `fetchRefreshToken` function with the `defineMetabaseAuthConfig` function: + +```typescript +{% include_file "{{ dirname }}/snippets/authentication/auth-config-jwt.tsx" snippet="example" %} +``` + +## Security warning: each end-user _must_ have their own Metabase account + +Each end-user _must_ have their own Metabase account. + +The problem with having end-users share a Metabase account is that, even if you filter data on the client side via the SDK, all end-users will still have access to the session token, which they could use to access Metabase directly via the API to get data they're not supposed to see. + +If each end-user has their own Metabase account, however, you can configure permissions in Metabase and everyone will only have access to the data they should. + +In addition to this, we consider shared accounts to be unfair usage. Fair usage of the SDK involves giving each end-user of the embedded analytics their own Metabase account. + +## Authenticating locally with API keys + +> The Embedded analytics SDK only supports JWT authentication in production. Authentication with API keys is only supported for local development and evaluation purposes. + +For developing locally to try out the SDK, you can authenticate using an API key. + +First, create an [API key](../../people-and-groups/api-keys). + +Then you can then use the API key to authenticate with Metabase in your application. All you need to do is include your API key in the config object using the key: `apiKey`. + +```typescript +{% include_file "{{ dirname }}/snippets/authentication/auth-config-api-key.tsx" %} +``` diff --git a/_docs/doc-update-detection/embedding/sdk/collections.md b/_docs/doc-update-detection/embedding/sdk/collections.md new file mode 100644 index 000000000..a4c490fbc --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/collections.md @@ -0,0 +1,39 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - collections' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/collections.md' +--- + +# Embedded analytics SDK - collections + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +You can embed Metabase's collection browser so that people can explore items in your Metabase from your application. + +## `CollectionBrowser` props + +| Prop | Type | Description | +| ------------------ | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| collectionId | `number \| 'root' \| 'personal'` | The numerical ID of the collection, "personal" for the user's personal collection, or "root" for the root collection. You can find this ID in the URL when accessing a collection in your Metabase instance. For example, the collection ID in `http://localhost:3000/collection/1-my-collection` would be `1`. Defaults to "personal" | +| onClick | `(item: CollectionItem) => void` | An optional click handler that emits the clicked entity. | +| pageSize | `number` | The number of items to display per page. The default is 25. | +| visibleEntityTypes | `["question", "model", "dashboard", "collection"]` | The types of entities that should be visible. If not provided, all entities will be shown. | + +## Example embedding code with `CollectionBrowser` + +```tsx +{% include_file "{{ dirname }}/snippets/collections/collection-browser.tsx" %} +``` + +## Hide the collection picker and hard code the collection you want people to save stuff to + +With static questions, you set a specific collection as the collection people can save items to, so that they don't have bother picking a collection. To hard-code a collection: + +1. Set `isSaveEnabled` to true. +2. Set `targetCollection` to the collection ID you want people to save items to. + +For more options, see [Question props](./questions#question-props). diff --git a/_docs/doc-update-detection/embedding/sdk/config.md b/_docs/doc-update-detection/embedding/sdk/config.md new file mode 100644 index 000000000..e978b224d --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/config.md @@ -0,0 +1,58 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - config' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/config.md' +--- + +# Embedded analytics SDK - config + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +To use the SDK in your app, you need to import the `MetabaseProvider` component and provide it with an `authConfig` object, like so: + +```typescript +{% include_file "{{ dirname }}/snippets/config/config-base.tsx" snippet="example" %} +``` + +You can also pass additional props to `MetabaseProvider`: + +- `authConfig` (Required). Defines how to authenticate with Metabase. +- `theme` (Optional) See [Appearance](./appearance). +- `pluginsConfig` (Optional). See [Plugins](./plugins). +- `eventHandlers` (Optional). See [Global event handlers](#global-event-handlers). +- `className` (Optional). Classes to be added to the wrapper element. +- `locale` (Optional). Defines the display language. Accepts an ISO language code such as `en` or `de`. +- `loaderComponent` (Optional). A custom loader component to display while the SDK is loading. +- `errorComponent` (Optional). A custom error component to display when the SDK encounters an error. +- `allowConsoleLog` (Optional). If `true`, log messages will be printed to the console. + +## Example `config` object passed to `MetabaseProvider` + +```typescript +{% include_file "{{ dirname }}/snippets/config/config-with-theme.tsx" %} +``` + +## Global event handlers + +`MetabaseProvider` also supports `eventHandlers`. + +Currently, we support: + +- `onDashboardLoad?: (dashboard: Dashboard | null) => void;`. Triggers when a dashboard loads with all visible cards and their content +- `onDashboardLoadWithoutCards?: (dashboard: Dashboard | null) => void;`. Triggers after a dashboard loads, but without its cards (at this stage only the dashboard title, tabs, and cards grid are rendered, but the contents of the cards have yet to load. + +```typescript +{% include_file "{{ dirname }}/snippets/config/config-with-event-handlers.tsx" snippet="example" %} +``` + +## Reloading Metabase components + +In case you need to reload a Metabase component, for example, your users modify your application data and that data is used to render a question in Metabase. If you embed this question and want to force Metabase to reload the question to show the latest data, you can do so by using the `key` prop to force a component to reload. + +```typescript +{% include_file "{{ dirname }}/snippets/config/reload-metabase-provider.tsx" snippet="example" %} +``` diff --git a/_docs/doc-update-detection/embedding/sdk/dashboards.md b/_docs/doc-update-detection/embedding/sdk/dashboards.md new file mode 100644 index 000000000..f3351fa09 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/dashboards.md @@ -0,0 +1,160 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - dashboards' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/dashboards.md' +--- + +# Embedded analytics SDK - dashboards + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +You can embed an interactive, editable, or static dashboard. + +**Please keep in mind - embedding multiple instances of dashboards on the same page is not yet supported.** + +## Embedding a dashboard + +You can embed a dashboard using the one of the dashboard components: + +- `StaticDashboard` + +A lightweight dashboard component. Use this component when you want to display results without letting people interact with the data. + +- `InteractiveDashboard` + +A dashboard component with drill downs, click behaviors, and the ability to view and click into questions. Use this component when you want to allow people to explore their data. + +- `EditableDashboard` + +A dashboard component with the features available in the `InteractiveDashboard` component, as well as the ability to add and update questions, layout, and content within your dashboard. Use this component when you want to give people the ability to modify your dashboards, for example in an admin panel in your app. + +## Dashboard component props + +| Prop | Type | Description | +| ---------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| dashboardId | `number \| string` | The ID of the dashboard. This is either:
- the numerical ID when accessing a dashboard link, i.e. `http://localhost:3000/dashboard/1-my-dashboard` where the ID is `1`
- the string ID found in the `entity_id` key of the dashboard object when using the API directly or using the SDK Collection Browser to return data | +| initialParameters\*\* | `Record` | Query parameters for the dashboard. For a single option, use a `string` value, and use a list of strings for multiple options. | +| withTitle | `boolean` | Whether the dashboard should display a title. | +| withCardTitle | `boolean` | Whether the dashboard cards should display a title. | +| withDownloads | `boolean \| null` | Whether to hide the download button. | +| hiddenParameters\*\* | `string[] \| null` | A list of [parameters to hide](../../embedding/public-links#appearance-parameters). | +| drillThroughQuestionHeight\* | `number \| null` | Height of a question component when drilled from the dashboard to a question level. | +| questionPlugins\* | `{ mapQuestionClickActions: Function } \| null` | Additional mapper function to override or add drill-down menu. See the implementing custom actions section for more details. | +| onLoad | `(dashboard: Dashboard \| null) => void` | Event handler that triggers after dashboard loads with all visible cards and their content. | +| onLoadWithoutCards | `(dashboard: Dashboard \| null) => void` | Event handler that triggers after dashboard loads, but without its cards - at this stage dashboard title, tabs and cards grid is rendered, but cards content is not yet loaded. | +| renderDrillThroughQuestion\* | `() => ReactNode` | A react component that renders [a question's layout](#customizing-drill-through-question-layout) shown after drilling through a question or clicking on a question card in the dashboard. | +| drillThroughQuestionProps\* | `[InteractiveQuestionProps](./questions#question-props)` | Props for the drill-through question | + +_\* Not available for `StaticDashboard`._ + +_\*\* Combining `initialParameters` and `hiddenParameters` to filter data on the frontend is a [security risk](./authentication#security-warning-each-end-user-must-have-their-own-metabase-account). Combining `initialParameters` and `hiddenParameters` to declutter the user interface is fine._ + +By default, dashboard components take full page height (100vh). You can override this with custom styles passed via `style` or `className` props. + +```tsx +{% include_file "{{ dirname }}/snippets/dashboards/custom-height.tsx" snippet="example" %} +``` + +## Example embedded dashboard with `InteractiveDashboard` component + +```typescript +{% include_file "{{ dirname }}/snippets/dashboards/interactive-dashboard.tsx" %} +``` + +## Customizing drill-through question layout + +When drilling through or clicking on a question card in the dashboard, you will be taken to the question view. By default, the question is shown in the [default layout](./questions#customizing-interactive-questions) for interactive questions. + +To customize the question layout, pass a `renderDrillThroughQuestion` prop to the `InteractiveDashboard` component, with the custom view as the child component. + +```typescript +{% include_file "{{ dirname }}/snippets/dashboards/custom-drill-through-question-layout.tsx" snippet="example-1" %} + +{% include_file "{{ dirname }}/snippets/dashboards/custom-drill-through-question-layout.tsx" snippet="example-2" %} +``` + +The questionView prop accepts a React component that will be rendered in the question view, which you can build with namespaced components within the `InteractiveQuestion` component. See [customizing interactive questions](./questions#customizing-interactive-questions) for an example layout. + +## Dashboard plugins + +### `dashboardCardMenu` + +This plugin allows you to add, remove, and modify the custom actions on the overflow menu of dashboard cards. The plugin appears as a dropdown menu on the top right corner of the card. + +The plugin's default configuration looks like this: + +```typescript +{% include_file "{{ dirname }}/snippets/dashboards/plugins.tsx" snippet="example-base-1" %} +``` + +`dashboardCardMenu`: can be used in the InteractiveDashboard like this: + +```typescript +{% include_file "{{ dirname }}/snippets/dashboards/plugins.tsx" snippet="example-base-2" %} +``` + +#### Enabling/disabling default actions + +To remove the download button from the dashcard menu, set `withDownloads` to `false`. To remove the edit link from the dashcard menu, set `withEditLink` to `false`. + +```typescript +{% include_file "{{ dirname }}/snippets/dashboards/plugins.tsx" snippet="example-default-actions" %} +``` + +#### Adding custom actions to the existing menu: + +You can add custom actions to the dashcard menu by adding an object to the `customItems` array. Each element can either be an object or a function that takes in the dashcard's question, and outputs a list of custom items in the form of: + +```typescript +{% include_file "{{ dirname }}/snippets/dashboards/plugins.tsx" snippet="example-custom-action-type" %} +``` + +Here's an example: + +```typescript +{% include_file "{{ dirname }}/snippets/dashboards/plugins.tsx" snippet="example-custom-actions" %} +``` + +#### Replacing the existing menu with your own component + +If you want to replace the existing menu with your own component, you can do so by providing a function that returns a React component. This function also can receive the question as an argument. + +```typescript +{% include_file "{{ dirname }}/snippets/dashboards/plugins.tsx" snippet="example-custom-actions-menu" %} +``` + +## Creating dashboards + +Creating a dashboard could be done with `useCreateDashboardApi` hook or `CreateDashboardModal` component. + +### Hook + +```typescript +{% include_file "{{ dirname }}/snippets/dashboards/create-dashboard.tsx" snippet="example-hook" %} +``` + +Props: + +| Prop | Type | Description | +| ------------ | -------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| name | `string` | (required) Dashboard title | +| description | `string \| null` | Optional dashboard description | +| collectionId | `number \| 'root' \| 'personal'` | Collection in which to create a new dashboard. You can use predefined system values like `root` or `personal`. | + +### Component + +```typescript +{% include_file "{{ dirname }}/snippets/dashboards/create-dashboard.tsx" snippet="example-component" %} +``` + +Supported component props: + +| Prop | Type | Description | +| ------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------ | +| collectionId? | `number \| 'root' \| 'personal'` | Initial collection in which to create a dashboard. You can use predefined system values like `root` or `personal`. | +| onCreate | `(dashboard: Dashboard) => void` | Handler to react on dashboard creation. | +| onClose | `() => void` | Handler to close modal component | diff --git a/_docs/doc-update-detection/embedding/sdk/introduction.md b/_docs/doc-update-detection/embedding/sdk/introduction.md new file mode 100644 index 000000000..4f54f230e --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/introduction.md @@ -0,0 +1,111 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/introduction.md' +--- + +# Embedded analytics SDK + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +With the Embedded analytics SDK, you can embed individual Metabase components with React (like standalone charts, dashboards, the query builder, and more). You can manage access and interactivity per component, and you have advanced customization for seamless styling. + +## Example apps built with the embedded analytics SDK + +To give you an idea of what's possible with the SDK, we've put together example sites at [metaba.se/sdk-demo](https://metaba.se/sdk-demo). Navigate between different shop websites. Check them out and poke around their products and analytics sections, as well as the New Question and New Dashboard options. + +![Pug and play example app built with embedded analytics SDK](../images/pug-and-play.png) + +Here's the [Shoppy source code](https://github.com/metabase/shoppy). + +## Embedded analytics SDK prerequisites + +- React application using React 18 or React 19. +- Nodejs 20.x or higher. +- Metabase version 1.52 or higher. + +## Quickstarts + +- [Quickstart](./quickstart) (If you have Metabase and an app) +- [Quickstart CLI](./quickstart-cli) (If you have an app, but no Metabase) +- [Quickstart with sample React app](./quickstart-with-sample-app) (If you don't have either) + +## Installation + +To use the SDK, you'll need to enable the SDK in Metabase, and install the SDK in your React app. + +### Enable the SDK in Metabase + +Enable the Embedded analytics SDK by going to **Admin settings > Settings > Embedding**. Toggle on the SDK, and hit **Configure**. Enter the origins for your website or app where you want to allow SDK embedding, separated by a space. Localhost is automatically included. + +### Install the SDK in your React application + +You can install the Embedded analytics SDK for React via npm. Make sure to use the dist-tag that corresponds to your Metabase version, example: 53-stable for Metabase 53: + +```bash +npm install @metabase/embedding-sdk-react@53-stable +``` + +or with yarn: + +```bash +yarn add @metabase/embedding-sdk-react@53-stable +``` + +## Developing with the Embedded analytics SDK + +Start with one of the quickstarts, then see these pages for more info on components, theming, and more. + +- [Authentication](./authentication) +- [Questions](./questions) +- [Dashboards](./dashboards) +- [Appearance](./appearance) +- [Collections](./collections) +- [Plugins](./plugins) +- [Config](./config) +- [Versioning](./version) +- [Notes on Next.js](./next-js) + +## Embedded analytics SDK source code + +You can find the [Embedded analytics SDK source code in the Metabase repo](https://github.com/metabase/metabase/tree/master/enterprise/frontend/src/embedding-sdk). + +## Changelog + +View the SDK's changelog: + +* [54-nightly](https://github.com/metabase/metabase/blob/master/enterprise/frontend/src/embedding-sdk/CHANGELOG.md) +* [53-stable](https://github.com/metabase/metabase/blob/release-x.53.x/enterprise/frontend/src/embedding-sdk/CHANGELOG.md) +* [52-stable](https://github.com/metabase/metabase/blob/release-x.52.x/enterprise/frontend/src/embedding-sdk/CHANGELOG.md) + +## Embedded analytics SDK on NPM + +Check out the Metabase Embedded analytics SDK on NPM: [metaba.se/sdk](https://metaba.se/sdk). + +## SDK limitations + +The SDK doesn't support: + +- Verified content +- Official collections +- Subscriptions +- Alerts +- Server-side rendering (SSR) +- Multiple _interactive_ dashboards on the same application page. If you need to embed multiple dashboards on the same application page, you can embed static dashboards. +- React 19 + +## Issues, feature requests and support + +[Bugs](https://github.com/metabase/metabase/issues/?q=is%3Aissue%20state%3Aopen%20label%3AType%3ABug%20label%3AEmbedding%2FSDK) and [feature requests](https://github.com/metabase/metabase/issues/?q=is%3Aissue%20state%3Aopen%20label%3AEmbedding%2FSDK%20label%3A%22Type%3ANew%20Feature%22) are tracked on GitHub. + +You can upvote an existing feature request by leaving a thumbs up emoji reaction on the issue. Feel free to leave comments with context that could be useful. [Read more](/docs/latest/troubleshooting-guide/requesting-new-features). + +Before creating new issues, please make sure an issue for your problem or feature request doesn't already exist. +To seek help: + +- Paid customers can contact our success team through the usual channels. +- People using the open-source edition can post on our [discussion forums](https://discourse.metabase.com/). diff --git a/_docs/doc-update-detection/embedding/sdk/next-js.md b/_docs/doc-update-detection/embedding/sdk/next-js.md new file mode 100644 index 000000000..baf8fb9a9 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/next-js.md @@ -0,0 +1,91 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - Using the SDK with Next.js' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/next-js.md' +--- + +# Embedded analytics SDK - Using the SDK with Next.js + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +{% include youtube.html id='UfL8okz36d0' %} + +Some notes on using the Embedded analytics SDK with [Next.js](https://nextjs.org/). The SDK is tested to work with Next.js 14, although it may work with other versions. + +## SDK components with Server Side Rendering (SSR) or React Server Components + +For now, the SDK components are only supported for client-side rendering. To use the SDK components with server-side rendering, or with React Server components, you can either use a compatibility layer or manually wrap the components. + +### Compatibility layer for server-side rendering (SSR) (EXPERIMENTAL) + +To use SDK components with Next.js, the SDK provides an experimental compatibility layer that [wraps all the components with dynamic imports and disables SSR](https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#with-no-ssr). To work with the app router, this compatibility layer uses `use client`. + +To use the compatibility layer, change your imports from `@metabase/embedding-sdk-react` to `@metabase/embedding-sdk-react/nextjs`. + +See a [sample Next.js app that uses this compatibility layer](https://github.com/metabase/metabase-nextjs-sdk-embedding-sample). + +## Manual wrapping of the components + +If you want to customize the loading of the components, you can create your own wrapper. + +In your app, create a `metabase` directory, and add a `EmbeddingSdkProvider.tsx` file to that directory. This file will contain the provider with the appropriate configuration. + +```tsx +{% include_file "{{ dirname }}/snippets/next-js/manual-wrapping-embedded-sdk-provider.tsx" snippet="example" %} +``` + +Next, add an `index.tsx` file to that `metabase` directory. This file will include the `use client` directive, and it'll export a lazy-loaded version of the `EmbeddingSdkProvider` with SSR disabled. + +```tsx +{% include_file "{{ dirname }}/snippets/next-js/manual-wrapping-entrypoint.tsx" snippet="example" %} +``` + +You can now import components like so: + +```tsx +{% include_file "{{ dirname }}/snippets/next-js/manual-wrapping-usage.tsx" %} +``` + +## Handling authentication + +App Router and Pages Router have different ways to define API routes. If you want to authenticate users from your server with JWT, you can follow the instructions below. But if you want to authenticate with API keys for local development, see [Authenticating locally with API keys](./authentication#authenticating-locally-with-api-keys). + +### Using App Router + +You can create a Route handler that signs people in to Metabase. + +Create a new `route.ts` file in your `app/*` directory, for example `app/sso/metabase/route.ts` that corresponds to an endpoint at /sso/metabase. + +```typescript +{% include_file "{{ dirname }}/snippets/next-js/app-router-authentication-api-route.ts" snippet="imports" %} + +{% include_file "{{ dirname }}/snippets/next-js/app-router-authentication-api-route.ts" snippet="example" %} +``` + +Then, pass this `authConfig` to `MetabaseProvider` + +```typescript +{% include_file "{{ dirname }}/snippets/next-js/authentication-auth-config.tsx" %} +``` + +### Using Pages Router + +You can create an API route that signs people in to Metabase. + +Create a new `metabase.ts` file in your `pages/api/*` directory, for example `pages/api/sso/metabase.ts` that corresponds to an endpoint at /api/sso/metabase. + +```typescript +{% include_file "{{ dirname }}/snippets/next-js/pages-router-authentication-api-route.ts" snippet="imports" %} + +{% include_file "{{ dirname }}/snippets/next-js/pages-router-authentication-api-route.ts" snippet="example" %} +``` + +Then, pass this `authConfig` to `MetabaseProvider` + +```ts +{% include_file "{{ dirname }}/snippets/next-js/authentication-auth-config.tsx" %} +``` diff --git a/_docs/doc-update-detection/embedding/sdk/plugins.md b/_docs/doc-update-detection/embedding/sdk/plugins.md new file mode 100644 index 000000000..a94311cab --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/plugins.md @@ -0,0 +1,36 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - plugins' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/plugins.md' +--- + +# Embedded analytics SDK - plugins + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +The Metabase Embedded analytics SDK supports plugins to customize the behavior of components. These plugins can be used in a global context or on a per-component basis. + +## Global plugins + +To use a plugin globally, add the plugin to the `MetabaseProvider`'s `pluginsConfig` prop: + +```typescript +{% include_file "{{ dirname }}/snippets/plugins/global-plugins.tsx" snippet="example" %} +``` + +## Component plugins + +To use a plugin on a per-component basis, pass the plugin as a prop to the component: + +```typescript +{% include_file "{{ dirname }}/snippets/plugins/component-plugins.tsx" snippet="example" %} +``` + +## Further reading + +- [Interactive question plugins](./questions#interactive-question-plugins) +- [Dashboard plugins](./dashboards#dashboard-plugins) diff --git a/_docs/doc-update-detection/embedding/sdk/questions.md b/_docs/doc-update-detection/embedding/sdk/questions.md new file mode 100644 index 000000000..247c756b4 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/questions.md @@ -0,0 +1,327 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - questions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/questions.md' +description: 'How to embed charts in your app with the Embedded analytics SDK.' +--- + +# Embedded analytics SDK - questions + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +There are different ways you can embed questions: + +- [Static question](#embedding-a-static-question). Embeds a chart. Clicking on the chart doesn't do anything. +- [Interactive question](#embedding-an-interactive-question). Clicking on the chart gives you the drill-through menu. +- [Query builder](#embedding-the-query-builder-for-creating-new-questions). Embeds the graphical query builder without a pre-defined query. + +## Embedding a static question + +![Static question](../images/static-question.png) + +You can embed a static question using the `StaticQuestion` component. + +The component has a default height, which can be customized by using the `height` prop. To inherit the height from the parent container, you can pass `100%` to the height prop. + +```typescript +{% include_file "{{ dirname }}/snippets/questions/static-question.tsx" %} +``` + +## Embedding an interactive question + +![Interactive question](../images/interactive-question.png) + +You can embed an interactive question using the `InteractiveQuestion` component. + +```typescript +{% include_file "{{ dirname }}/snippets/questions/interactive-question.tsx" %} +``` + +## Question props + +| Prop | Type | Description | +| ----------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `entityTypeFilter` | string array; options include "table", "question", "model", "metric" | (optional) An array that specifies which entity types are available in the data picker | +| `height` | number or string | (optional) A number or string specifying a CSS size value that specifies the height of the component | +| `initialSqlParameters` | `Record` | (optional) For SQL questions only. A mapping of [SQL parameter names to parameter values](#pass-sql-parameters-to-sql-questions-with-initialsqlparameters), such as `{ product_id: "42"}` | +| `isSaveEnabled` | boolean | (optional, default: `true`) Whether users can save the question | +| `onBeforeSave` | `() => void` | (optional) A callback function that triggers before saving. Only relevant when `isSaveEnabled = true` | +| `onSave` | `() => void` | (optional) A callback function that triggers when a user saves the question. Only relevant when `isSaveEnabled = true` | +| `plugins` | `{ mapQuestionClickActions: Function }` or null | Additional mapper function to override or add drill-down menu | +| `questionId` | number or string | (required) The ID of the question. This is either:
- The numerical ID when accessing a question link, e.g., `http://localhost:3000/question/1-my-question` where the ID is `1`
- The `entity_id` key of the question object. You can find a question's Entity ID in the info panel when viewing a question
- `new` to show the notebook editor for creating new questions. `isSaveEnabled` must be `true` to allow saving the question | +| `targetCollection` | number \| "root" \| "personal" | (optional) The collection to save the question to. This will hide the collection picker from the save modal. Only applicable to interactive questions | +| `title` | boolean \| string \| `ReactNode` \| `() => ReactNode` | (optional) Determines whether the question title is displayed, and allows a custom title to be displayed instead of the default question title. Shown by default. Only applicable to interactive questions when using the default layout | +| `withChartTypeSelector` | boolean | (optional, default: `true`) Determines whether the chart type selector and corresponding settings button are shown. Only relevant when using the default layout | +| `withResetButton` | boolean | (optional, default: `true`) Determines whether a reset button is displayed. Only relevant when using the default layout | + +## Pass SQL parameters to SQL questions with `initialSqlParameters` + +You can pass parameter values to questions defined with SQL via the `initialSqlParameters` prop, in the format of `{parameter_name: parameter_value}`. Learn more about [SQL parameters](../../questions/native-editor/sql-parameters). + +```typescript +{% include_file "{{ dirname }}/snippets/questions/initial-sql-parameters.tsx" snippet="example" %} +``` + +`initialSqlParameters` can't be used with questions built using the query builder. + +## Customizing interactive questions + +By default, the Embedded analytics SDK provides a default layout for interactive questions that allows you to view your questions, apply filters and aggregations, and access functionality within the query builder. + +Here's an example of using the `InteractiveQuestion` component with its default layout: + +```typescript +{% include_file "{{ dirname }}/snippets/questions/customize-interactive-question.tsx" snippet="example-default-interactive-question" %} +``` + +To customize the layout, use namespaced components within the `InteractiveQuestion` component. For example: + +```typescript +{% include_file "{{ dirname }}/snippets/questions/customize-interactive-question.tsx" snippet="example-customized-interactive-question" %} +``` + +## Interactive question components + +These components are available via the `InteractiveQuestion` namespace (e.g., ``). + +_\* signifies a required prop_ + +### `InteractiveQuestion.BackButton` + +A navigation button that returns to the previous view. Only renders when `onNavigateBack` prop from `InteractiveQuestion` is available. + +Uses [Mantine ActionIcon props](https://v6.mantine.dev/core/action-icon/) under the hood, as well as: + +| Prop | Type | Description | +| --------- | ------------------- | ----------------------------------------------- | +| className | string | Custom CSS class name for styling the component | +| style | React.CSSProperties | Inline styles to apply to the component | + +### `InteractiveQuestion.Breakout` + +A set of badges for managing data groupings (breakouts). + +No props. Uses question context for breakout functionality. + +### `InteractiveQuestion.BreakoutDropdown` + +Dropdown button for the Breakout component. + +Uses [Popover props](https://v6.mantine.dev/core/popover/?t=props) except `onClose`, `children`, and `opened` under the hood, as well as: + +| Prop | Type | Description | +| --------- | ------------------- | ----------------------------------------------- | +| className | string | Custom CSS class name for styling the component | +| style | React.CSSProperties | Inline styles to apply to the component | + +### `InteractiveQuestion.ChartTypeDropdown` + +Dropdown for selecting the visualization type (bar chart, line chart, table, etc.). Automatically updates to show recommended visualization types for the current data. + +Uses [Mantine Menu props](https://v6.mantine.dev/core/menu/?t=props) under the hood, as well as: + +| Prop | Type | Description | +| --------- | ------------------- | ----------------------------------------------- | +| className | string | Custom CSS class name for styling the component | +| style | React.CSSProperties | Inline styles to apply to the component | + +### `InteractiveQuestion.ChartTypeSelector` + +Detailed chart type selection interface with recommended visualization options. + +Uses [Mantine Stack props](https://v6.mantine.dev/core/stack/?t=props) under the hood, as well as: + +| Prop | Type | Description | +| --------- | ------------------- | ----------------------------------------------- | +| className | string | Custom CSS class name for styling the component | +| style | React.CSSProperties | Inline styles to apply to the component | + +### `InteractiveQuestion.Editor` + +Advanced query editor that provides full access to question configuration. Includes filtering, aggregation, custom expressions, and joins. + +_Replaces deprecated `InteractiveQuestion.Notebook`_ + +| Prop | Type | Description | +| ------- | ---------- | --------------------------------------------------- | +| onApply | () => void | Callback function executed when changes are applied | + +### `InteractiveQuestion.EditorButton` + +_Replaces deprecated `InteractiveQuestion.NotebookButton`_ + +Toggle button for showing/hiding the Editor interface. In custom layouts, the `EditorButton` _must_ have an `onClick` handler or the button won't do anything when clicked. + +Uses [Mantine ActionIcon props](https://v6.mantine.dev/core/action-icon/) under the hood, as well as: + +| Prop | Type | Description | +| --------- | ------------------- | ----------------------------------------------- | +| isOpen | boolean | Whether the editor is currently open | +| className | string | Custom CSS class name for styling the component | +| style | React.CSSProperties | Inline styles to apply to the component | + +### `InteractiveQuestion.Filter` + +A set of interactive filter badges that allow adding, editing, and removing filters. Displays current filters as badges with an "Add another filter" option. + +| Prop | Type | Description | +| ------------------ | ------- | ---------------------------------------------------- | +| withColumnItemIcon | boolean | Whether to show column icons in the filter interface | + +### `InteractiveQuestion.FilterDropdown` + +A dropdown button for the Filter component. + +| Prop | Type | Description | +| ------------------ | ------- | ---------------------------------------------------- | +| withColumnItemIcon | boolean | Whether to show column icons in the filter interface | + +### `InteractiveQuestion.QuestionSettings` + +Settings panel for configuring visualization options like axes, colors, and formatting. + +No props. Uses question context for settings. + +### `InteractiveQuestion.QuestionSettingsDropdown` + +Dropdown button that contains the QuestionSettings component. + +Uses [Popover props](https://v6.mantine.dev/core/popover/?t=props) except `onClose` and `opened` under the hood, as well as: + +| Prop | Type | Description | +| --------- | ----------------------------- | ----------------------------------------------- | +| height | React.CSSProperties["height"] | Height for the dropdown menu | +| className | string | Custom CSS class name for styling the component | +| style | React.CSSProperties | Inline styles to apply to the component | + +### `InteractiveQuestion.QuestionVisualization` + +The main visualization component that renders the question results as a chart, table, or other visualization type. + +| Prop | Type | Description | +| --------- | ------------------- | ----------------------------------------------- | +| height | number \| string | Height for visualization | +| width | number \| string | Width for visualization | +| className | string | Custom CSS class name for styling the component | +| style | React.CSSProperties | Inline styles to apply to the component | + +### `InteractiveQuestion.ResetButton` + +Button to reset question modifications. Only appears when there are unsaved changes to the question. + +Uses [Mantine Button props](https://v6.mantine.dev/core/button/?t=props) under the hood, as well as: + +| Prop | Type | Description | +| --------- | ------------------- | ----------------------------------------------- | +| className | string | Custom CSS class name for styling the component | +| style | React.CSSProperties | Inline styles to apply to the component | + +### `InteractiveQuestion.SaveButton` + +Button for saving question changes. Only enabled when there are unsaved modifications to the question. + +_Note_: Currently, in custom layouts, the `SaveButton` must have an `onClick` handler or the button will not do anything when clicked. + +Uses [Mantine Button props](https://v6.mantine.dev/core/button/?t=props) under the hood, as well as: + +| Prop | Type | Description | +| --------- | ------------------- | ----------------------------------------------- | +| className | string | Custom CSS class name for styling the component | +| style | React.CSSProperties | Inline styles to apply to the component | + +### `InteractiveQuestion.SaveQuestionForm` + +Form for saving a question, including title and description. When saved: + +- For new questions: Calls `onCreate` prop from InteractiveQuestion +- For existing questions: Calls `onSave` prop from InteractiveQuestion +- Both callbacks receive the updated question object +- Form can be cancelled via the `onCancel` prop + +| Prop | Type | Description | +| -------- | ---------- | ------------------------------------------------- | +| onCancel | () => void | Callback function executed when save is cancelled | + +### `InteractiveQuestion.Summarize` + +Interface for adding and managing data summaries (like counts, sums, averages). Displays as a set of badges. + +No props. Uses question context for summarization functionality. + +### `InteractiveQuestion.SummarizeDropdown` + +Dropdown button for the Summarize component. + +Uses [Popover props](https://v6.mantine.dev/core/popover/?t=props) except `onClose`, `children`, and `opened` under the hood, as well as: + +| Prop | Type | Description | +| --------- | ------------------- | ----------------------------------------------- | +| className | string | Custom CSS class name for styling the component | +| style | React.CSSProperties | Inline styles to apply to the component | + +### InteractiveQuestion.DownloadWidget + +Provides a UI widget for downloading data in different formats (`CSV`, `XLSX`, `JSON`, and `PNG` depending on the visualization). + +No props + +### InteractiveQuestion.DownloadWidgetDropdown + +Provides a button that contains a dropdown that shows the `DownloadWidget`. + +Uses [Popover props](https://mantine.dev/core/popover/?t=props) under the hood, as well as: + +| Prop | Type | Description | +| --------- | ------------------- | ----------------------------------------------- | +| className | string | Custom CSS class name for styling the component | +| style | React.CSSProperties | Inline styles to apply to the component | + +### `InteractiveQuestion.Title` + +Displays a title based on the question's state. Shows: + +- The question's display name if it's saved +- An auto-generated description for ad-hoc questions (non-native queries) +- "New question" as fallback or for new/native queries + +| Prop | Type | Description | +| --------- | ------------- | ----------------------------------------------- | +| className | string | Custom CSS class name for styling the component | +| style | CSSProperties | Inline styles to apply to the component | + +## Interactive question plugins + +You can use [plugins](./plugins) to add custom functionality to your questions. + +### `mapQuestionClickActions` + +This plugin allows you to add custom actions to the click-through menu of an interactive question. You can add and +customize the appearance and behavior of the custom actions. + +```typescript +{% include_file "{{ dirname }}/snippets/questions/interactive-question-plugins.tsx" snippet="example" %} +``` + +## Prevent people from saving changes to an `InteractiveQuestion` + +To prevent people from saving changes to an interactive question, or from saving changes as a new question, you can set `isSaveEnabled={false}`: + +```tsx +{% include_file "{{ dirname }}/snippets/questions/disable-question-save.tsx" %} +``` + +## Embedding the query builder for creating new questions + +![Query builder](../images/query-builder.png) + +You can embed the query builder for creating new questions by passing the `questionId="new"` prop to the `InteractiveQuestion` component. You can use the [`children` prop](#customizing-interactive-questions) to customize the layout for creating new questions. + +```tsx +{% include_file "{{ dirname }}/snippets/questions/new-question.tsx" %} +``` + +To customize the question editor's layout, use the `InteractiveQuestion` component [directly with a custom `children` prop](#customizing-interactive-questions). diff --git a/_docs/doc-update-detection/embedding/sdk/quickstart-cli.md b/_docs/doc-update-detection/embedding/sdk/quickstart-cli.md new file mode 100644 index 000000000..8029fc817 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/quickstart-cli.md @@ -0,0 +1,121 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - CLI quickstart' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/quickstart-cli.md' +--- + +# Embedded analytics SDK - CLI quickstart + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +We built a single command to spin up a Metabase and help you get an embedded dashboard in your app. This setup with API keys won't work in production; it's only intended for you to quickly try out the SDK on your local machine. A production setup requires a Pro/Enterprise license, and SSO with JWT. + +## Prerequisites + +- Docker (should be up and running on your machine) +- [Node.js 20.x LTS](https://nodejs.org/en) or higher. +- License (Optional - only if you want to try out multi-tenancy). +- Database (you can connect to your app's database). + +You don't need a running Metabase; the tool will set up a Metabase for you on Docker. + +## The quickstart CLI command + +Change into your React application and run: + +```sh +npx @metabase/embedding-sdk-react@latest start +``` + +The CLI tool will walk you through the setup. There are a fair number of pieces to put together, so here's an overview of what the command does: + +- [Prereq check](#prereq-check) +- [Database connection (optional)](#database-connection-optional) +- [Metabase setup](#metabase-setup) +- [Permissions setup with multi-tenancy (optional)](#permissions-setup-with-multi-tenancy-optional) +- [React components setup](#react-components-setup) +- [Behold: Metabase is embedded in your app](#behold-metabase-is-embedded-in-your-app) + +## Prereq check + +The tool will check for the following: + +- You've run the command in the top-level directory of your React application. +- You've installed the SDK (if you haven't, the CLI will install the SDK for you and add it as a dependency in your `package.json`). +- You have Docker up and running on your machine. + +## Database connection (optional) + +The tool will ask if you have a database to connect to. Use the arrow keys to select Yes or No. The tool will use this database to generate an embedded dashboard. + +If you answer no, the script will use the Sample Database that ships with Metabase to create a dashboard to embed. + +If you select Yes, the tool will prompt you to connect to a database. Pick your database's engine. You'll need to provide database's host, port, username, and password. The tool will connect to the database, and prompt you to select tables from your database to embed. Pick 1-3 tables. If you want to see multi-tenancy in action, pick a table with user IDs in it. Metabase will X-ray these tables to create a dashboard to embed. + +## Metabase setup + +The tool will ask you for an email address to create the first admin account in Metabase. Doesn't have to be a real email address (the tool doesn't set up a SMTP server); the email address is just required for logging in to the Metabase that the tool will set up. + +Next, the tool will spin up a Metabase on Docker. This takes a bit. To see the Docker container's status, use the `docker ps` command. Or use the time to reflect on good choices you've made recently. + +Once Metabase is up and running, the tool will create an admin user with the email you provided, and generate an [API key](../../people-and-groups/api-keys) for that Metabase. + +The tool will then prompt you to pick 1-3 tables to embed. You can press to select, to toggle all, to invert selection, and to proceed. + +## Permissions setup with multi-tenancy (optional) + +If you have a Pro/EE license, the tool can set up permissions. To get a license, sign up for a [free trial of self-hosted Metabase Pro](/pricing/). + +If you opted to set up multi-tenancy and connected to your own database, the tool will ask you for the column you want to use to sandbox the table (e.g., a user ID column). Metabase will [sandbox data](../../permissions/data-sandboxes) based on the values in that column. + +The tool will also set up a mock Express server to handle the JWTs. The tool will ask you where it should save the server code (default: `./mock-server`). It'll install the server's dependencies with `npm install`. + +You'll need to start the mock server in another terminal session. Change into the mock server's directory and run: + +```sh +npm run start +``` + +## React components setup + +Next, the tool will generate example React components files. By default, the tool will save them in `./src/components/metabase` in your React app, though the tool will prompt you to save them to a different directory if you want (e.g., `./src/analytics`). +It generates a couple of demo components for you to try out theming and user switching: + +- `AnalyticsDashboard` - a dashboard component that embeds a Metabase dashboard. +- `AnalyticsPage` - a page that embeds a dashboard with a wrapped provider. In a real application, you must add the `MetabaseProvider` separately to your app's root `App` component (or where you would've added your other providers). +- `ThemeSwitcher` - switch between light and dark themes. +- `UserSwitcher` - switch between fake users. +- `AnalyticsProvider` - a provider that adds the demo state for the example theme switcher and user switcher components. +- `EmbeddingProvider` - a provider that wraps the `MetabaseProvider` with demo themes and auth configuration. + +You can delete these files once you've played around with the tool, and are ready to setup your own theming and user management. + +## Add the Metabase/React components to your app + +You'll need to add the Metabase/React components to your app. Add an import to your client app, like so: + +```jsx +{% include_file "{{ dirname }}/snippets/quickstart-cli/example.tsx" snippet="imports" %} +``` + +Make sure the `from` path is valid (depending on your app, you may need to move the components to a new directory). + +Then you'll need to add the `` component to a page in your app. Something like: + +```jsx +{% include_file "{{ dirname }}/snippets/quickstart-cli/example.tsx" snippet="example" %} +``` + +## Behold: Metabase is embedded in your app + +Start your app, and visit the page where you added the `` component. You should see an embedded dashboard. + +You can also check out the Metabase the tool set up. The Metabase should be running at `http://localhost:3366`. You can find your login credentials at `METABASE_LOGIN.json`. + +## Further reading + +- [Quickstart with sample app and JWT](./quickstart) diff --git a/_docs/doc-update-detection/embedding/sdk/quickstart-with-sample-app.md b/_docs/doc-update-detection/embedding/sdk/quickstart-with-sample-app.md new file mode 100644 index 000000000..f21221a45 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/quickstart-with-sample-app.md @@ -0,0 +1,246 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - quickstart with sample app' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/quickstart-with-sample-app.md' +--- + +# Embedded analytics SDK - quickstart with sample app + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +This guide sets up the embedded analytics SDK with a [sample React app](https://github.com/metabase/metabase-nodejs-react-sdk-embedding-sample/tree/{{page.version | remove: "v0."}}-stable), but you can follow along with your own application. + +{% include youtube.html id='AtMn-G-Al80' %} + +## Prerequisites + +- [Node.js 20.x LTS or higher](https://nodejs.org/en) (for the sample application). +- [Metabase version v1.52 or higher](/docs/latest/releases). +- [A Metabase Pro or Enterprise license](/pricing/) (If you don't have a license, check out [this quickstart](./quickstart) that lacks the paid JWT SSO setup) +- (Optional): [Docker](https://www.docker.com/) + +## Two ways to set up the sample app with Metabase + +- [Quick setup with Docker](#quick-setup-with-docker) (includes a sample Metabase) +- [Walkthrough setup](#walkthrough-setup) (bring your own Metabase, or spin up a new one) + +## Quick setup with Docker + +This quick setup will run a Docker container with the sample app and a sample Metabase. + +1. Copy `.env.docker.example` to `.env.docker`. +2. In the `.env.docker` file, replace `` with your premium embedding token. +3. In the top-level directory, run: + ```bash + yarn start + ``` + +This script will: + +- Pull a Metabase Docker image and run it in a container. +- Set up JWT SSO in Metabase. +- Build and run the sample application with an embedded interactive question. + +The app will start on [http://localhost:4400](http://localhost:4400). + +That's it! You should be [up and running](#at-this-point-you-should-be-up-and-running). + +If you want to log in to the sample Metabase this command set up, visit [http://localhost:4300](http://localhost:4300). You can log in with email and password as Rene Descartes: + +- email: rene@example.com +- password: foobarbaz + +## Walkthrough setup + +We're going to do some setup in Metabase, and then in the sample application. You can also bring your own Metabase, in which case you can skip the installation step. + +Here's a quick overview of what you'll be doing: + +### Set up Metabase for embedding + +1. [Install Metabase Enterprise Edition](#install-metabase-enterprise-edition) (if you haven't already) +2. [Activate your license](#activate-your-license) +3. [Enable embedding](#enable-embedding-in-metabase) +4. [Enable SSO with JWT](#enable-sso-with-jwt) + +### Start up the sample application + +5. [Get the sample application](#set-up-the-sample-application). +6. [Set up the application environment](#set-up-the-application-environment). +7. [Run the app server](#set-up-the-application-server) to handle authentication with JWT and serve the embedded Metabase components. +8. [Run the client application](#set-up-the-client-application) that will contain Metabase components built with the SDK. + +And then fiddle around with styling. + +Let's go. + +## Install Metabase Enterprise Edition + +You can run Metabase Pro on a Cloud plan with a [free trial](/pricing/). + +Or run it locally. Here's a docker one-liner: + +```sh +docker run -d -p 3000:3000 --name metabase metabase/metabase-enterprise:latest +``` + +You can also [download the JAR](https://downloads.metabase.com/enterprise/latest/metabase.jar), and run it like so: + +```sh +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +By default, Metabase will run at `http://localhost:3000`. + +If you get stuck, check out our [installation docs](../../installation-and-operation/installing-metabase). + +## Activate your license + +To enable SSO with JWT when self-hosting, you'll need to [activate your license](/docs/latest/paid-features/activating-the-enterprise-edition). Metabase Pro plans on Cloud take care of this for you. + +## Enable embedding in Metabase + +From any Metabase page, click on the **gear** icon in the upper right and select **Admin Settings** > **Settings** > **Embedding**. + +Turn on: + +- Embedded analytics SDK +- Static embedding + +Otherwise, this whole thing is hopeless. + +## Enable SSO with JWT + +From any Metabase page, click on the **gear** icon in the upper right and select **Admin Settings** > **Settings** > **Authentication**. + +On the card that says **JWT**, click the **Setup** button. + +### JWT Identity provider URI + +In **JWT IDENTITY PROVIDER URI** field, paste + +```txt +localhost:9090/sso/metabase +``` + +Or substitute your Cloud URL for `localhost`. + +### String used by the JWT signing key + +Click the **Generate key** button. + +Copy the key and paste it in your `.env` file into the env var `METABASE_JWT_SHARED_SECRET`. + +The application server will use this key to sign tokens so Metabase knows the application's requests for content are authorized. + +## Save and enable JWT + +Be sure to hit the **Save and enable** button, or all is void. + +## Set up the sample application + +Clone the [Metabase Node JS React SDK embedding sample app](https://github.com/metabase/metabase-nodejs-react-sdk-embedding-sample/tree/{{page.version | remove: "v0."}}-stable). + +```sh +git clone git@github.com:metabase/metabase-nodejs-react-sdk-embedding-sample.git +``` + +### Check out the branch that corresponds to your Metabase version + +Check out the branch in the [metabase-nodejs-react-sdk-embedding-sample](https://github.com/metabase/metabase-nodejs-react-sdk-embedding-sample/tree/{{page.version | remove: "v0."}}-stable) repo that corresponds to your Metabase version. + +E.g., if you're running Metabase 1.53, make sure the sample app repo is on the `53-stable` branch. You can find your Metabase version in the Metabase UI by clicking on the gears icon in the upper right and selecting **About Metabase**. + +To switch to another branch, run `git checkout `, e.g.: + +``` +git checkout 52-stable +``` + +## Set up the application environment + +In the sample app's main directory, copy the `.env.example` template to `.env`. + +```sh +cp .env.example .env +``` + +In `.env`, make sure `VITE_METABASE_INSTANCE_URL` and `METABASE_INSTANCE_URL` point to your Metabase instance URL, e.g., `http://localhost:3000`. + +Your `.env` will look something like: + +```txt +# FRONTEND +CLIENT_PORT=3100 +VITE_METABASE_INSTANCE_URL="http://localhost:3000" +VITE_AUTH_PROVIDER_URI="http://localhost:9090/sso/metabase" + +# BACKEND +AUTH_PROVIDER_PORT=9090 +METABASE_INSTANCE_URL="http://localhost:3000" +METABASE_JWT_SHARED_SECRET="TODO" +``` + +## Set up the application server + +Change into the `server` directory: + +```sh +cd server +``` + +Install packages: + +```sh +npm install +``` + +Start the server: + +```sh +npm start +``` + +## Set up the client application + +In a different terminal, change into the `client` directory: + +```sh +cd client +``` + +Install dependencies: + +```sh +npm install +``` + +This command will install the [Metabase embedded analytics SDK](https://www.npmjs.com/package/@metabase/embedding-sdk-react), in addition to the application's other dependencies. + +You can also install a [different version of the SDK](./version). Just make sure that the major version of the SDK matches the major version of the Metabase you're using. + +Start the client app: + +```sh +npm start +``` + +Your browser should automatically open the app. By default, the app runs on [http://localhost:3100](localhost:3100). + +## At this point, you should be up and running + +In your app, you'll see an embedded `InteractiveQuestion` component. + +```javascript +{% include_file "{{ dirname }}/snippets/quickstart-with-sample-app/example.tsx" snippet="example" %} +``` + +![Embedded Metabase components](../images/interactive-question-sample-app.png) + +## Next steps + +To style the components, try changing some of the `theme` options in the client app at `client/src/App.jsx`. For more on theming, check out [Appearance](./appearance). diff --git a/_docs/doc-update-detection/embedding/sdk/quickstart.md b/_docs/doc-update-detection/embedding/sdk/quickstart.md new file mode 100644 index 000000000..97fd78d39 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/quickstart.md @@ -0,0 +1,88 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - quickstart' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/quickstart.md' +description: 'This guide walks you through how to set up the Embedded analytics SDK in your application with your Metabase.' +--- + +# Embedded analytics SDK - quickstart + +This guide walks you through how to set up the Embedded analytics SDK in your application with your Metabase using API keys. + +This setup: + +- Is only for evaluation (so you can see how the SDK works). +- Only works on localhost when developing your app (though your Metabase doesn't need to be running locally). +- Works with both the Enterprise and Open Source editions of Metabase, both self-hosted and on Metabase Cloud. + +If you want to use the SDK in production, however, you'll also need to [set up JWT SSO authentication](./authentication), which requires a [Pro or Enterprise plan](/pricing/). To enable JWT SSO when you're self-hosting Metabase, you'll need to run the Enterprise Edition Docker image or JAR, and [activate your license](../../installation-and-operation/activating-the-enterprise-edition). + +## Prerequisites + +- [Metabase](/docs/latest/releases) version 52 or higher (OSS or EE). See [Installing Metabase](../../installation-and-operation/installing-metabase). +- An application using React 17 or 18. (You could also use the [sample React app](https://github.com/metabase/metabase-nodejs-react-sdk-embedding-sample/tree/{{page.version | remove: "v0."}}-stable)) + +If you _don't_ have a Metabase up and running, check out the [Quickstart CLI](./quickstart-cli). + +If you _don't_ want to use your own application code, check out our [quickstart with a sample app](./quickstart-with-sample-app). + +## Overview + +To embed a dashboard in your app using the SDK, you'll need to: + +1. [Enable the SDK in Metabase](#1-enable-the-sdk-in-metabase) +2. [Create an API key in Metabase](#2-create-an-api-key-in-metabase) +3. [Install the SDK in your app](#3-install-the-sdk-in-your-app) +4. [Embed SDK components in your app](#4-embed-sdk-components-in-your-app) +5. [View your embedded Metabase dashboard](#5-view-your-embedded-metabase-dashboard) + +## 1. Enable the SDK in Metabase + +In Metabase, click on the gear icon in the upper right and navigate to **Admin Settings > Settings > Embedding** and enable the Embedded analytics SDK. + +## 2. Create an API key in Metabase + +Still in the Admin's Settings tab, navigate to the **Authentication** section in the sidebar and click on the **API keys** tab. [Create a new API key](../../people-and-groups/api-keys). + +- Key name: "Embedded analytics SDK" (just to make the key easy to identify). +- Group: select “Admin” (since this is only for local testing). + +## 3. Install the SDK in your app + +When installing the NPM package, it's critical to use the npm dist-tag that corresponds to the major version of your Metabase. For example, if your Metabase is version 1.53.x, you'd run `53-stable`. See [SDK versioning](./version). + +Via NPM: + +``` +npm install @metabase/embedding-sdk-react@53-stable +``` + +Via Yarn: + +``` +yarn add @metabase/embedding-sdk-react@53-stable +``` + +## 4. Embed SDK components in your app + +In your app, import the SDK components, like so: + + +```jsx +{% include_file "{{ dirname }}/snippets/quickstart/example.tsx" %} +``` + +## 5. View your embedded Metabase dashboard + +Run your app and visit the page with the embedded dashboard. + +![Embedded example dashboard](../images/embedded-example-dashboard.png) + +## Next steps + +- Explore [theming to change the look and feel](./appearance). +- Continue by [setting up JWT SSO in Metabase and your app](./authentication) in order to sign people in, manage permissions, and deploy your app in production. diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/appearance/customizing-loader-and-components.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/appearance/customizing-loader-and-components.tsx new file mode 100644 index 000000000..37abcf102 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/appearance/customizing-loader-and-components.tsx @@ -0,0 +1,25 @@ +import type { MetabaseAuthConfig } from "@metabase/embedding-sdk-react"; +// [] +import { + MetabaseProvider, + StaticDashboard, +} from "@metabase/embedding-sdk-react"; +// [] + +const authConfig = {} as MetabaseAuthConfig; + +const Example = () => { + return ( + // [] + ] + authConfig={authConfig} + // [] + loaderComponent={() =>
Analytics is loading...
} + errorComponent={({ message }) =>
There was an error: {message}
} + > + +
+ // [] + ); +}; diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/appearance/theme.ts b/_docs/doc-update-detection/embedding/sdk/snippets/appearance/theme.ts new file mode 100644 index 000000000..b8aa1460f --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/appearance/theme.ts @@ -0,0 +1,195 @@ +import { defineMetabaseTheme } from "@metabase/embedding-sdk-react"; + +const theme = defineMetabaseTheme({ + // Specify a font to use from the set of fonts supported by Metabase. + // You can set the font to "Custom" to use the custom font + // configured in your Metabase instance. + fontFamily: "Lato", + + // Override the base font size for every component. + // This does not usually need to be set, as the components + // inherit the font size from the parent container, such as the body. + fontSize: "16px", + + // Override the base line height for every component. + lineHeight: 1.5, + + // Match your application's color scheme + colors: { + // The primary color of your application + brand: "#9B5966", + + // Lighter variation of the brand color. Used for hover and accented elements. + "brand-hover": "#DDECFA", + + // Lightest variation of the brand color. Used for hover and accented elements. + "brand-hover-light": "#EEF6FC", + + // The color of text that is most prominent + "text-primary": "#4C5773", + + // The color of text that is less prominent + "text-secondary": "#696E7B", + + // The color of text that is least prominent + "text-tertiary": "#949AAB", + + // Default background color + background: "#FFFFFF", + + // Slightly muted background color. + "background-secondary": "#EDF2F5", + + // Slightly darker background color used for hover and accented elements + "background-hover": "#F9FBFC", + + // Muted background color used for disabled elements, such as disabled buttons and inputs. + "background-disabled": "#F3F5F7", + + // Color used for borders + border: "#EEECEC", + + // Color used for filters context + filter: "#7172AD", + + // Color used for aggregations and breakouts context + summarize: "#88BF4D", + + // Color used to indicate successful actions and positive values/trends + positive: "#BADC58", + + // Color used to indicate dangerous actions and negative values/trends + negative: "#FF7979", + + /** Color used for popover shadows */ + shadow: "rgba(0,0,0,0.08)", + + // Overrides the chart colors. Supports up to 8 colors + // Limitation: this does not affect charts with custom series color + charts: [ + // can either be a hex code + "#9B59B6", + + // or a color object. tint and shade represents lighter and darker variations + // only base color is required, while tint and shade are optional + { base: "#E74C3C", tint: "#EE6B56", shade: "#CB4436" }, + ], + }, + + components: { + // Dashboard + dashboard: { + // Background color for all dashboards + backgroundColor: "#2F3640", + + // Border color of the dashboard grid, shown only when editing dashboards. + // Defaults to `colors.border` + gridBorderColor: "#EEECEC", + + card: { + // Background color for all dashboard cards + backgroundColor: "#2D2D30", + + // Apply a border color instead of shadow for dashboard cards. + // Unset by default. + border: "1px solid #EEECEC", + }, + }, + + // Question + question: { + // Background color for all questions + backgroundColor: "#2E353B", + + // Toolbar of the default interactive question layout + toolbar: { + backgroundColor: "#F3F5F7", + }, + }, + + // Tooltips + tooltip: { + // Tooltip text color. + textColor: "#FFFFFF", + + // Secondary text color shown in the tooltip, e.g. for tooltip headers and percentage changes. + secondaryTextColor: "#949AAB", + + // Tooltip background color. + backgroundColor: "#2E353B", + + // Tooltip background color for focused rows. + focusedBackgroundColor: "#0A0E10", + }, + + // Data table + table: { + cell: { + // Text color of cells, defaults to `text-primary` + textColor: "#4C5773", + + // Default background color of cells, defaults to `background` + backgroundColor: "#FFFFFF", + + // Font size of cell values, defaults to ~12.5px + fontSize: "12.5px", + }, + + idColumn: { + // Text color of ID column, defaults to `brand` + textColor: "#9B5966", + + // Background color of ID column, defaults to a lighter shade of `brand` + backgroundColor: "#F5E9EB", + }, + }, + + // Number chart + number: { + // Value displayed on number charts. + // This also applies to the primary value in trend charts. + value: { + fontSize: "24px", + lineHeight: "21px", + }, + }, + + // Cartesian chart + cartesian: { + // Padding around the cartesian charts. + // Uses CSS's `padding` property format. + padding: "4px 8px", + }, + + // Pivot table + pivotTable: { + cell: { + // Font size of cell values, defaults to ~12px + fontSize: "12px", + }, + + // Pivot row toggle to expand or collapse row + rowToggle: { + textColor: "#FFFFFF", + backgroundColor: "#95A5A6", + }, + }, + + collectionBrowser: { + breadcrumbs: { + expandButton: { + textColor: "#8118F4", + backgroundColor: "#767D7C", + hoverTextColor: "#CE8C8C", + hoverBackgroundColor: "#69264B", + }, + }, + }, + + // Popover are used in components such as click actions in interactive questions. + popover: { + // z-index of the popover. Useful for embedding components in a modal. defaults to 4. + zIndex: 4, + }, + }, +}); diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-api-key.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-api-key.tsx new file mode 100644 index 000000000..ccc26238a --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-api-key.tsx @@ -0,0 +1,17 @@ +import { + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfigApiKey = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://metabase.example.com", + apiKey: "YOUR_API_KEY", +}); + +export default function App() { + return ( + + Hello World! + + ); +} diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-base.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-base.tsx new file mode 100644 index 000000000..d0e174f7e --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-base.tsx @@ -0,0 +1,8 @@ +import { defineMetabaseAuthConfig } from "@metabase/embedding-sdk-react"; + +// [] +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", // Required: Your Metabase instance URL + authProviderUri: "https://your-app.example.com/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session +}); +// [] diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-jwt.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-jwt.tsx new file mode 100644 index 000000000..ceb0d429e --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-jwt.tsx @@ -0,0 +1,20 @@ +import { defineMetabaseAuthConfig } from "@metabase/embedding-sdk-react"; + +const yourToken = "token"; + +// [] +// Pass this configuration to MetabaseProvider. +// Wrap the fetchRequestToken function in useCallback if it has dependencies to prevent re-renders. +const authConfig = defineMetabaseAuthConfig({ + fetchRequestToken: async url => { + const response = await fetch(url, { + method: "GET", + headers: { Authorization: `Bearer ${yourToken}` }, + }); + + return await response.json(); + }, + metabaseInstanceUrl: "http://localhost:3000", + authProviderUri: "http://localhost:9090/sso/metabase", +}); +// [] diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server-cors.ts b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server-cors.ts new file mode 100644 index 000000000..3fb221ed1 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server-cors.ts @@ -0,0 +1,41 @@ +import cors from "cors"; +import express from "express"; +import session from "express-session"; + +const PORT = 3000; +const SESSION_SECRET = "SECRET"; + +const app = express(); +const metabaseAuthHandler = () => {}; + +// [] +// Middleware + +// If your FE application is on a different domain from your BE, you need to enable CORS +// by setting Access-Control-Allow-Credentials to true and Access-Control-Allow-Origin +// to your FE application URL. +// +// Limitation: We currently only support setting one origin in Authorized Origins in Metabase for CORS. +app.use( + cors({ + credentials: true, + }), +); + +app.use( + session({ + secret: SESSION_SECRET, + resave: false, + saveUninitialized: true, + cookie: { secure: false }, + }), +); + +app.use(express.json()); + +// routes +app.get("/sso/metabase", metabaseAuthHandler); +app.listen(PORT, () => { + console.log(`API running at http://localhost:${PORT}`); +}); +// [] diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server.ts b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server.ts new file mode 100644 index 000000000..3971d5ce4 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server.ts @@ -0,0 +1,65 @@ +import express from "express"; +import cors from "cors"; +import session from "express-session"; +import jwt from "jsonwebtoken"; +import fetch from "node-fetch"; + +// Replace this with your Metabase URL +const METABASE_INSTANCE_URL = "YOUR_METABASE_URL_HERE"; +// Replace this with the JWT signing secret you generated when enabling +// JWT SSO in your Metabase. +const METABASE_JWT_SHARED_SECRET = "YOUR_SECRET_HERE"; + +const app = express(); + +app.get("/sso/metabase", async (req, res) => { + // Usually, you would grab the user from the current session + // Here it's hardcoded for demonstration purposes + // Example: + // const { user } = req.session; + const user = { + email: "rene@example.com", + firstName: "Rene", + lastName: "Descartes", + group: "Customer", + }; + + if (!user) { + console.log("no user"); + res.status(401).json({ + status: "error", + message: "not authenticated", + }); + + return; + } + + const token = jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + groups: [user.group], + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration + }, + METABASE_JWT_SHARED_SECRET, + ); + const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`; + console.log("Hitting MB SSO endpoint", ssoUrl); + + try { + const response = await fetch(ssoUrl, { method: "GET" }); + const session = await response.text(); + + console.log("Received session", session); + res.status(200).set("Content-Type", "application/json").end(session); + } catch (error) { + if (error instanceof Error) { + res.status(401).json({ + status: "error", + message: "authentication failed", + error: error.message, + }); + } + } +}); diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/authentication/get-auth-status.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/get-auth-status.tsx new file mode 100644 index 000000000..0c8db4349 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/authentication/get-auth-status.tsx @@ -0,0 +1,18 @@ +import { + InteractiveQuestion, + useMetabaseAuthStatus, +} from "@metabase/embedding-sdk-react"; + +const Example = () => { + // [] + const auth = useMetabaseAuthStatus(); + + if (auth.status === "error") { + return
Failed to authenticate: {auth.error.message}
; + } + + if (auth.status === "success") { + return ; + } + // [] +}; diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/collections/collection-browser.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/collections/collection-browser.tsx new file mode 100644 index 000000000..4b09f1563 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/collections/collection-browser.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { CollectionBrowser } from "@metabase/embedding-sdk-react"; + +export default function App() { + const collectionId = 123; // This is the collection ID you want to browse + const handleItemClick = item => { + console.log("Clicked item:", item); + }; + + return ( + + ); +} diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/config/config-base.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/config/config-base.tsx new file mode 100644 index 000000000..90d7d3522 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/config/config-base.tsx @@ -0,0 +1,25 @@ +import { + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const theme = {}; + +// [] +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL + authProviderUri: "https://app.example.com/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session +}); + +export default function App() { + return ( + + Hello World! + + ); +} +// [] diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/config/config-with-event-handlers.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/config/config-with-event-handlers.tsx new file mode 100644 index 000000000..85eda0eb1 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/config/config-with-event-handlers.tsx @@ -0,0 +1,30 @@ +import type { PropsWithChildren } from "react"; +import { + MetabaseProvider, + type SdkDashboardLoadEvent, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "", + authProviderUri: "", +}); + +const Example = ({ children }: PropsWithChildren) => { + // [] + const handleDashboardLoad: SdkDashboardLoadEvent = dashboard => { + /* do whatever you need to do - e.g. send analytics events, show notifications */ + }; + + const eventHandlers = { + onDashboardLoad: handleDashboardLoad, + onDashboardLoadWithoutCards: handleDashboardLoad, + }; + + return ( + + {children} + + ); + // [] +}; diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/config/config-with-theme.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/config/config-with-theme.tsx new file mode 100644 index 000000000..619e0d22a --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/config/config-with-theme.tsx @@ -0,0 +1,38 @@ +import React from "react"; +import { + MetabaseProvider, + defineMetabaseAuthConfig, + defineMetabaseTheme, +} from "@metabase/embedding-sdk-react"; + +// Configure authentication +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL + authProviderUri: "https://app.example.com/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session +}); + +// See the "Customizing appearance" section for more information +const theme = defineMetabaseTheme({ + // Optional: Specify a font to use from the set of fonts supported by Metabase + fontFamily: "Lato", + + // Optional: Match your application's color scheme + colors: { + brand: "#9B5966", + "text-primary": "#4C5773", + "text-secondary": "#696E7B", + "text-tertiary": "#949AAB", + }, +}); + +export default function App() { + return ( + + Hello World! + + ); +} diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/config/reload-metabase-provider.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/config/reload-metabase-provider.tsx new file mode 100644 index 000000000..6c9e3a8cf --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/config/reload-metabase-provider.tsx @@ -0,0 +1,37 @@ +import { useEffect, useState } from "react"; +import { InteractiveQuestion } from "@metabase/embedding-sdk-react"; +import { isEqual } from "underscore"; + +const yourQuestionId = 1; + +const Example = () => { + // [] + // Inside your application component + const [data, setData] = useState({}); + // This is used to force reloading Metabase components + const [counter, setCounter] = useState(0); + + // This ensures we only change the `data` reference when it's actually changed + const handleDataChange = newData => { + setData(prevData => { + if (isEqual(prevData, newData)) { + return prevData; + } + + return newData; + }); + }; + + useEffect(() => { + /** + * When you set `data` as the `useEffect` hook's dependency, it will trigger the effect + * and increment the counter which is used in a Metabase component's `key` prop, forcing it to reload. + */ + if (data) { + setCounter(counter => counter + 1); + } + }, [data]); + + return ; + // [] +}; diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/create-dashboard.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/create-dashboard.tsx new file mode 100644 index 000000000..24e22cd95 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/create-dashboard.tsx @@ -0,0 +1,41 @@ +import { useState } from "react"; +import { + CreateDashboardModal, + EditableDashboard, + type MetabaseDashboard, + useCreateDashboardApi, +} from "@metabase/embedding-sdk-react"; + +const ExampleHook = () => { + const props = { + name: "New dashboard", + description: null, + collectionId: 1, + }; + + // [] + const { createDashboard } = useCreateDashboardApi(); + + const handleDashboardCreate = async () => { + const dashboard = await createDashboard(props); + + // do something with created empty dashboard, e.g., use the dashboard in EditableDashboard component + }; + + return ; + // [] +}; + +const ExampleComponent = () => { + const handleClose = () => {}; + + // [] + const [dashboard, setDashboard] = useState(null); + + if (dashboard) { + return ; + } + + return ; + // [] +}; diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-drill-through-question-layout.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-drill-through-question-layout.tsx new file mode 100644 index 000000000..a5066bd2e --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-drill-through-question-layout.tsx @@ -0,0 +1,18 @@ +import { + InteractiveDashboard, + InteractiveQuestion, +} from "@metabase/embedding-sdk-react"; + +const Example = () => ( + // [] + + // [] +); + +// [] +// You can use namespaced components to build the question's layout. +const QuestionView = () => ; +// [] diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-height.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-height.tsx new file mode 100644 index 000000000..1957db5be --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-height.tsx @@ -0,0 +1,15 @@ +import { EditableDashboard } from "@metabase/embedding-sdk-react"; + +const dashboardId = 1; + +const Example = () => ( + // [] + + // [] +); diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/interactive-dashboard.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/interactive-dashboard.tsx new file mode 100644 index 000000000..4d7270549 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/interactive-dashboard.tsx @@ -0,0 +1,31 @@ +import React from "react"; +import { + InteractiveDashboard, + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", + authProviderUri: "https://your-app.example.com/sso/metabase", +}); + +export default function App() { + const dashboardId = 1; // This is the dashboard ID you want to embed + const initialParameters = {}; // Define your query parameters here + + // choose parameter names that are in your dashboard + const hiddenParameters = ["location", "city"]; + + return ( + + + + ); +} diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/plugins.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/plugins.tsx new file mode 100644 index 000000000..439e80a48 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/dashboards/plugins.tsx @@ -0,0 +1,105 @@ +import { + InteractiveDashboard, + type MetabasePluginsConfig, +} from "@metabase/embedding-sdk-react"; + +const dashboardId = 1; + +const ExampleBase1 = () => { + // [] + const plugins = { + dashboard: { + dashboardCardMenu: { + withDownloads: true, + withEditLink: true, + customItems: [], + }, + }, + }; + // [] + + return ; +}; + +const ExampleBase2 = () => ( + // [] + null, + }, + }} + /> + // [] +); + +const ExampleDefaultActions = () => { + // [] + const plugins = { + dashboard: { + dashboardCardMenu: { + withDownloads: false, + withEditLink: false, + customItems: [], + }, + }, + }; + // [] + + return ; +}; + +// [] +type DashCardMenuItem = { + iconName: string; + label: string; + onClick: () => void; + disabled?: boolean; +}; +// [] + +const ExampleCustomActions = () => { + // [] + const plugins: MetabasePluginsConfig = { + dashboard: { + dashboardCardMenu: { + customItems: [ + { + iconName: "chevronright", + label: "Custom action", + onClick: () => { + alert(`Custom action clicked`); + }, + }, + ({ question }) => { + return { + iconName: "chevronright", + label: "Custom action", + onClick: () => { + alert(`Custom action clicked ${question?.name}`); + }, + }; + }, + ], + }, + }, + }; + // [] + + return ; +}; + +const ExampleCustomActionsMenu = () => { + // [] + const plugins: MetabasePluginsConfig = { + dashboard: { + dashboardCardMenu: ({ question }) => ( + + ), + }, + }; + // [] + + return ; +}; diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/next-js/EmbeddingSdkProvider.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/EmbeddingSdkProvider.tsx new file mode 100644 index 000000000..02cc7ba8b --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/EmbeddingSdkProvider.tsx @@ -0,0 +1,2 @@ +// Required to properly resolve import in `manual-wrapping-entrypoint.tsx` snippet +export { EmbeddingSdkProvider } from "./manual-wrapping-embedded-sdk-provider"; diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/next-js/app-router-authentication-api-route.ts b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/app-router-authentication-api-route.ts new file mode 100644 index 000000000..2a4f1e140 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/app-router-authentication-api-route.ts @@ -0,0 +1,50 @@ +// [] +import jwt from "jsonwebtoken"; +// [] + +const user = { + email: "rene@example.com", + firstName: "Rene", + lastName: "Descartes", + group: "Customer", +}; + +// [] +const METABASE_JWT_SHARED_SECRET = process.env.METABASE_JWT_SHARED_SECRET || ""; +const METABASE_INSTANCE_URL = process.env.METABASE_INSTANCE_URL || ""; + +export async function GET() { + const token = jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + groups: [user.group], + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration + }, + // This is the JWT signing secret in your Metabase JWT authentication setting + METABASE_JWT_SHARED_SECRET, + ); + const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`; + + try { + const ssoResponse = await fetch(ssoUrl, { method: "GET" }); + const ssoResponseBody = await ssoResponse.json(); + + return Response.json(ssoResponseBody); + } catch (error) { + if (error instanceof Error) { + return Response.json( + { + status: "error", + message: "authentication failed", + error: error.message, + }, + { + status: 401, + }, + ); + } + } +} +// [] diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/next-js/authentication-auth-config.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/authentication-auth-config.tsx new file mode 100644 index 000000000..d1e0299a4 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/authentication-auth-config.tsx @@ -0,0 +1,6 @@ +import { defineMetabaseAuthConfig } from "@metabase/embedding-sdk-react/nextjs"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL + authProviderUri: "/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session +}); diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/next-js/declarations.d.ts b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/declarations.d.ts new file mode 100644 index 000000000..4b7134cba --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/declarations.d.ts @@ -0,0 +1,4 @@ +// Required to properly resolve the `import { StaticQuestion } from "@/metabase";` in `manual-wrapping-usage.tsx` snippet +declare module "@/metabase" { + export { StaticQuestion } from "@metabase/embedding-sdk-react/nextjs"; +} diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-embedded-sdk-provider.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-embedded-sdk-provider.tsx new file mode 100644 index 000000000..b65e5b8d4 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-embedded-sdk-provider.tsx @@ -0,0 +1,33 @@ +// [] +"use client"; + +import { + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: process.env.NEXT_PUBLIC_METABASE_INSTANCE_URL, + authProviderUri: process.env.NEXT_PUBLIC_METABASE_AUTH_PROVIDER_URI, +}); + +export const EmbeddingSdkProvider = ({ + children, +}: { + children: React.ReactNode; +}) => { + return ( + {children} + ); +}; +// [] + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace NodeJS { + interface ProcessEnv { + readonly NEXT_PUBLIC_METABASE_INSTANCE_URL: string; + readonly NEXT_PUBLIC_METABASE_AUTH_PROVIDER_URI: string; + } + } +} diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-entrypoint.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-entrypoint.tsx new file mode 100644 index 000000000..67a66ba53 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-entrypoint.tsx @@ -0,0 +1,52 @@ +// [] +"use client"; + +import dynamic from "next/dynamic"; + +import type React from "react"; + +// Lazy load the EmbeddingSdkProvider so and let it render children while it's being loaded +export const EmbeddingSdkProviderLazy = ({ + children, +}: { + children: React.ReactNode; +}) => { + const EmbeddingSdkProvider = dynamic( + () => + import("./EmbeddingSdkProvider").then(m => { + return { default: m.EmbeddingSdkProvider }; + }), + { + ssr: false, + loading: () => { + // render children while loading + return
{children}
; + }, + }, + ); + + return {children}; +}; + +// Wrap all components that you need like this: + +export const StaticQuestion = dynamic( + () => import("@metabase/embedding-sdk-react").then(m => m.StaticQuestion), + { + ssr: false, + loading: () => { + return
Loading...
; + }, + }, +); + +export const StaticDashboard = dynamic( + () => import("@metabase/embedding-sdk-react").then(m => m.StaticDashboard), + { + ssr: false, + loading: () => { + return
Loading...
; + }, + }, +); +// [] diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-usage.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-usage.tsx new file mode 100644 index 000000000..9e92b8417 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-usage.tsx @@ -0,0 +1,5 @@ +import { StaticQuestion } from "@/metabase"; // path to the folder created earlier + +export default function Home() { + return ; +} diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/next-js/pages-router-authentication-api-route.ts b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/pages-router-authentication-api-route.ts new file mode 100644 index 000000000..7566938c6 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/next-js/pages-router-authentication-api-route.ts @@ -0,0 +1,49 @@ +// [] +import type { NextApiRequest, NextApiResponse } from "next"; +import jwt from "jsonwebtoken"; +// [] + +const user = { + email: "rene@example.com", + firstName: "Rene", + lastName: "Descartes", + group: "Customer", +}; + +// [] +const METABASE_JWT_SHARED_SECRET = process.env.METABASE_JWT_SHARED_SECRET || ""; +const METABASE_INSTANCE_URL = process.env.METABASE_INSTANCE_URL || ""; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse, +) { + const token = jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + groups: [user.group], + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration + }, + // This is the JWT signing secret in your Metabase JWT authentication setting + METABASE_JWT_SHARED_SECRET, + ); + const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`; + + try { + const ssoResponse = await fetch(ssoUrl, { method: "GET" }); + const ssoResponseBody = await ssoResponse.json(); + + res.status(200).json(ssoResponseBody); + } catch (error) { + if (error instanceof Error) { + res.status(401).json({ + status: "error", + message: "authentication failed", + error: error.message, + }); + } + } +} +// [] diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/plugins/component-plugins.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/plugins/component-plugins.tsx new file mode 100644 index 000000000..9dc8e0c12 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/plugins/component-plugins.tsx @@ -0,0 +1,12 @@ +import { InteractiveQuestion } from "@metabase/embedding-sdk-react"; + +const Example = () => ( + // [] + [], + }} + /> + // [] +); diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/plugins/global-plugins.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/plugins/global-plugins.tsx new file mode 100644 index 000000000..a1dedccee --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/plugins/global-plugins.tsx @@ -0,0 +1,23 @@ +import type { PropsWithChildren } from "react"; +import { + type MetabaseAuthConfig, + MetabaseProvider, + type MetabaseTheme, +} from "@metabase/embedding-sdk-react"; + +const authConfig = {} as MetabaseAuthConfig; +const theme = {} as MetabaseTheme; + +const Example = ({ children }: PropsWithChildren) => ( + // [] + [], // Add your custom actions here + }} + > + {children} + + // [] +); diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/questions/customize-interactive-question.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/questions/customize-interactive-question.tsx new file mode 100644 index 000000000..9ff7afa7a --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/questions/customize-interactive-question.tsx @@ -0,0 +1,69 @@ +import { + InteractiveQuestion, + type MetabaseAuthConfig, + MetabaseProvider, + type MetabaseTheme, +} from "@metabase/embedding-sdk-react"; + +const authConfig = {} as MetabaseAuthConfig; +const theme = {} as MetabaseTheme; + +const ExampleDefaultInteractiveQuestion = () => ( + // [] + + // [] +); + +const ExampleCustomizedInteractiveQuestion = () => ( + // [] +
+ + +
+
+ + +
+
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+ // [] +); diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/questions/disable-question-save.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/questions/disable-question-save.tsx new file mode 100644 index 000000000..365a669ae --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/questions/disable-question-save.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { + InteractiveQuestion, + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", + authProviderUri: "https://your-app.example.com/sso/metabase", +}); + +export default function App() { + return ( + + + + ); +} diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/questions/initial-sql-parameters.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/questions/initial-sql-parameters.tsx new file mode 100644 index 000000000..5ef24b887 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/questions/initial-sql-parameters.tsx @@ -0,0 +1,12 @@ +import { StaticQuestion } from "@metabase/embedding-sdk-react"; + +const questionId = 1; + +const Example = () => ( + // [] + + // [] +); diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question-plugins.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question-plugins.tsx new file mode 100644 index 000000000..62e7331b9 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question-plugins.tsx @@ -0,0 +1,65 @@ +import { + InteractiveQuestion, + type MetabaseAuthConfig, + MetabaseProvider, +} from "@metabase/embedding-sdk-react"; + +const authConfig = {} as MetabaseAuthConfig; + +const Example = () => { + // [] + // You can provide a custom action with your own `onClick` logic. + const createCustomAction = clicked => ({ + buttonType: "horizontal", + name: "client-custom-action", + section: "custom", + type: "custom", + icon: "chevronright", + title: "Hello from the click app!!!", + onClick: ({ closePopover }) => { + alert(`Clicked ${clicked.column?.name}: ${clicked.value}`); + closePopover(); + }, + }); + + // Or customize the appearance of the custom action to suit your need. + const createCustomActionWithView = clicked => ({ + name: "client-custom-action-2", + section: "custom", + type: "custom", + view: ({ closePopover }) => ( + + ), + }); + + const plugins = { + /** + * You will have access to default `clickActions` that Metabase renders by default. + * So you could decide if you want to add custom actions, remove certain actions, etc. + */ + mapQuestionClickActions: (clickActions, clicked) => { + return [ + ...clickActions, + createCustomAction(clicked), + createCustomActionWithView(clicked), + ]; + }, + }; + + const questionId = 1; // This is the question ID you want to embed + + return ( + + + + ); + // [] +}; diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question.tsx new file mode 100644 index 000000000..2d564bc2b --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question.tsx @@ -0,0 +1,21 @@ +import React from "react"; +import { + InteractiveQuestion, + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", + authProviderUri: "https://your-app.example.com/sso/metabase", +}); + +export default function App() { + const questionId = 1; // This is the question ID you want to embed + + return ( + + + + ); +} diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/questions/new-question.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/questions/new-question.tsx new file mode 100644 index 000000000..a81f7c216 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/questions/new-question.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { + InteractiveQuestion, + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", + authProviderUri: "https://your-app.example.com/sso/metabase", +}); + +export default function App() { + return ( + + + + ); +} diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/questions/static-question.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/questions/static-question.tsx new file mode 100644 index 000000000..b309088b2 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/questions/static-question.tsx @@ -0,0 +1,21 @@ +import React from "react"; +import { + MetabaseProvider, + StaticQuestion, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", + authProviderUri: "https://your-app.example.com/sso/metabase", +}); + +export default function App() { + const questionId = 1; // This is the question ID you want to embed + + return ( + + + + ); +} diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/components/metabase/analytics-page.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/components/metabase/analytics-page.tsx new file mode 100644 index 000000000..58ce956a8 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/components/metabase/analytics-page.tsx @@ -0,0 +1 @@ +export const AnalyticsPage = () => null; diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/example.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/example.tsx new file mode 100644 index 000000000..b340c9a6b --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/example.tsx @@ -0,0 +1,15 @@ +// [] +import { AnalyticsPage } from "./components/metabase/analytics-page"; +// [] + +// [] +function App() { + return ( +
+ +
+ ); +} + +export default App; +// [] diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/quickstart-with-sample-app/example.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/quickstart-with-sample-app/example.tsx new file mode 100644 index 000000000..ed5393228 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/quickstart-with-sample-app/example.tsx @@ -0,0 +1,19 @@ +import { + InteractiveQuestion, + type MetabaseAuthConfig, + MetabaseProvider, + type MetabaseTheme, +} from "@metabase/embedding-sdk-react"; + +const authConfig = {} as MetabaseAuthConfig; +const theme = {} as MetabaseTheme; + +const questionId = 1; + +const Example = () => ( + // [] + + + + // [] +); diff --git a/_docs/doc-update-detection/embedding/sdk/snippets/quickstart/example.tsx b/_docs/doc-update-detection/embedding/sdk/snippets/quickstart/example.tsx new file mode 100644 index 000000000..4d332275f --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/snippets/quickstart/example.tsx @@ -0,0 +1,26 @@ +import { + InteractiveDashboard, + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +/** + * This creates an auth config to pass to the `MetabaseProvider` component. + * You'll need to replace the `metabaseInstanceUrl` and the `apiKey` values. + */ +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://metabase.example.com", + apiKey: "YOUR_API_KEY", +}); + +/** + * Now embed your first dashboard. In this case, we're embedding the dashboard with ID 1. + * On new Metabases, ID 1 will be the example dashboard, but feel free to use a different dashboard ID. + */ +export default function App() { + return ( + + + + ); +} diff --git a/_docs/doc-update-detection/embedding/sdk/version.md b/_docs/doc-update-detection/embedding/sdk/version.md new file mode 100644 index 000000000..ff3248026 --- /dev/null +++ b/_docs/doc-update-detection/embedding/sdk/version.md @@ -0,0 +1,48 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Embedded analytics SDK - versions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/sdk/version.md' +--- + +# Embedded analytics SDK - versions + +{% include plans-blockquote.html feature="Embedded analytics SDK" sdk=true %} + +The SDK stable version tracks with the Metabase version. + +So, for example, if you're on Metabase 53 (`0.53.x`, `1.53.x`), _any_ version 0.53.x of the @metabase/embedding-sdk-react npm package will be compatible. + +To simplify things, we publish dist-tags for each stable Metabase version. For example, to install the latest version of the SDK compatible with Metabase 53, run: + +```sh +npm install @metabase/embedding-sdk-react@53-stable +``` + +To grab the latest version of the SDK that works with Metabase nightly builds, use the `canary` dist-tag. + +## Minimum SDK version + +52 is the minimum version supported for the Embedded analytics SDK. + +## Version pinning when using the SDK with Metabase Cloud + +To pin your version of Metabase, go to **Admin settings > Settings > Embedding**. Go to the Embedded analytics SDK card and scroll to **Version pinning** and click **Request version pinning**. + +## Version pinning requirements + +To pin a version of Metabase, you must: + +- Be on Metabase Cloud (obviously) +- Be on the Pro or Enterprise plans + +## Why you'd want to pin your Metabase Cloud version + +Normally, Metabase Cloud upgrades your Metabase as new versions roll out so that you don't have to deal with upgrades. + +But if you're using the SDK with Metabase Cloud, you'll want to upgrade manually to make sure your embeds don't break when you upgrade both your Metabase and your SDK version. + +To upgrade manually, you can pin your Metabase version so that it stays in sync with the SDK version you're using. That way you can choose when to upgrade your Metabase. diff --git a/_docs/doc-update-detection/embedding/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts b/_docs/doc-update-detection/embedding/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts new file mode 100644 index 000000000..4398043b1 --- /dev/null +++ b/_docs/doc-update-detection/embedding/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts @@ -0,0 +1,116 @@ +import express from "express"; +// [] +import jwt from "jsonwebtoken"; +// [] + +const app = express(); + +const METABASE_INSTANCE_URL = "YOUR_METABASE_URL_HERE"; +const METABASE_JWT_SHARED_SECRET = "YOUR_SECRET_HERE"; + +type User = { + email: string; + firstName: string; + lastName: string; +}; + +declare module "express-session" { + interface SessionData { + user: User; + } +} + +// [] +function restrict(req, res, next) { + if (req.session.user) { + next(); + } else { + req.session.returnTo = req.originalUrl; + req.session.error = "Access denied!"; + res.redirect("/login"); + } +} +// [] + +// [] +const signUserToken = user => + jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration + }, + METABASE_JWT_SHARED_SECRET, + ); +// [] + +const userGroupsExample = () => { + // [] + const signUserToken = user => + jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + groups: ["Customer-Acme"], + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration + }, + METABASE_JWT_SHARED_SECRET, + ); + // [] +}; + +const userAttributeExample = () => { + // [] + const signUserToken = user => + jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + // hard-coded account ID added to this object + // just to test sandboxing with Metabase's Sample Database: Invoices table + account_id: 28, + groups: ["Customer-Acme"], + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration + }, + METABASE_JWT_SHARED_SECRET, + ); + // [] +}; + +// [] +app.get("/sso/metabase", restrict, (req, res) => { + const ssoUrl = new URL("/auth/sso", METABASE_INSTANCE_URL); + ssoUrl.searchParams.set("jwt", signUserToken(req.session.user)); + ssoUrl.searchParams.set("return_to", req.query.return_to?.toString() ?? "/"); + + res.redirect(ssoUrl.href); +}); +// [] + +app.get("/sso/metabase", restrict, (req, res) => { + const ssoUrl = new URL("/auth/sso", METABASE_INSTANCE_URL); + ssoUrl.searchParams.set("jwt", signUserToken(req.session.user)); + + // [] + ssoUrl.searchParams.set( + "return_to", + `${req.query.return_to ?? "/"}?logo=false&top_nav=false`, + ); + // [] + + res.redirect(ssoUrl.href); +}); + +// [] +app.get("/analytics", restrict, (req, res) => { + const METABASE_DASHBOARD_PATH = "/dashboard/entity/[Entity ID]"; // e.g., `/dashboard/1` or `/dashboard/entity/nXg0q7VOZJp5a3_hceMRk` + const iframeUrl = `/sso/metabase?return_to=${METABASE_DASHBOARD_PATH}`; + + res.send( + ``, + ); +}); +// [] diff --git a/_docs/doc-update-detection/embedding/start.md b/_docs/doc-update-detection/embedding/start.md new file mode 100644 index 000000000..17b354c58 --- /dev/null +++ b/_docs/doc-update-detection/embedding/start.md @@ -0,0 +1,43 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: Embedding +title: 'Embedding overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/start.md' +--- + +# Embedding overview + +## [Introduction](./introduction) + +What is embedding, and how does it work? + +## [Interactive embedding](./interactive-embedding) + +The solution to self-service customer analytics: embed the full Metabase app in your app. Interactive embedding integrates with your data permissions to let people slice and dice data on their own using Metabase's query builder. + +## [Interactive embedding quickstart](./interactive-embedding-quick-start-guide) + +You'll embed the full Metabase application in your app. Once logged in, people can view a Metabase dashboard in your web app, and be able to use the full Metabase application to explore their data, and only their data. + +## [Embedded analytics SDK](./sdk/introduction) + +With the Embedded analytics SDK, you can embed individual Metabase components with React (like standalone charts, dashboards, the query builder, and more). You can manage access and interactivity per component, and you have advanced customization for seamless styling. + +## [Embedded analytics SDK quickstart](./sdk/quickstart) + +Jump to a SDK quickstart with a sample React application. + +## [Static embedding](./static-embedding) + +Also known as Signed Embedding, Static embedding is a secure way to embed charts and dashboards. Static embeds are view only; people won't be able to drill-through charts and tables. + +## [Parameters for static embeds](./static-embedding-parameters) + +You can pass parameters between Metabase and your website via the embedding URL to specify how Metabase items should look and behave inside the iframe on your website. + +## [Public embeds](./public-links) + +Admins can also create unsecured public links or embeds of questions and dashboards. diff --git a/_docs/doc-update-detection/embedding/static-embedding-parameters.md b/_docs/doc-update-detection/embedding/static-embedding-parameters.md new file mode 100644 index 000000000..53e9b0f12 --- /dev/null +++ b/_docs/doc-update-detection/embedding/static-embedding-parameters.md @@ -0,0 +1,251 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Parameters for static embeds' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/static-embedding-parameters.md' +redirect_from: + - /docs/doc-update-detection/embedding/signed-embedding-parameters +--- + +# Parameters for static embeds + +Also known as: parameters for signed embeds, or standalone embeds. + +Parameters are pieces of information that are passed between Metabase and your website via the [embedding URL](./static-embedding#adding-the-embedding-url-to-your-website). You can use parameters to specify how Metabase items should look and behave inside the iframe on your website. + +{% include shared/in-page-promo-embedding-workshop.html %} + +## Types of parameters + +Parameters can be signed or unsigned. + +### Signed parameters + +Signed parameters, such as filter names and values, must be added to your server code. + +- [Editable parameters](#adding-a-filter-widget-to-a-static-embed) +- [Locked parameters](#restricting-data-in-a-static-embed-with-locked-parameters) + +### Unsigned parameters + +Unsigned parameters, such as appearance settings, should be added directly to your iframe's `src` attribute. + +- [Default values for editable parameters](#populating-an-embedded-filter-widget-with-a-default-value) +- [Visibility settings for editable parameters](#hiding-filter-widgets-from-a-static-embed) +- [Appearance settings](#customizing-the-appearance-of-a-static-embed) + +## Adding a filter widget to a static embed + +You can use **editable parameters** to add [filter widgets](/glossary/filter_widget) to embedded dashboards or SQL questions. + +1. Go to your dashboard or SQL question. Make sure you've set up a [dashboard filter](../dashboards/filters) or [SQL variable](../questions/native-editor/sql-parameters). +2. Click on the **sharing icon** > **Embed this item in an application**. +3. Under **Parameters**, you'll find the names of your dashboard filters or SQL variables. +4. Select **Editable** for each parameter that should get a filter widget on your embed. +5. Click **Publish** to save your changes. +6. Add or update the code on your server to [match the code generated by Metabase](./static-embedding#previewing-the-code-for-an-embed). + +Editable parameters are responsible for passing filter values from the embedded filter widget (displayed on the iframe) through to the filters on your original dashboard or SQL question (in your Metabase). + +### You can't disable parameters when the original question or dashboard requires a value + +If the filter on a dashboard or question is set to [Always require a value](../dashboards/filters), you won't be able to disable the parameter when embedding. + +## Populating an embedded filter widget with a default value + +If you want to set a default value for your [editable filter widget](#adding-a-filter-widget-to-a-static-embed), you can pass that default value to the corresponding parameter name in your iframe's `src` attribute: + +``` +your_embedding_url?parameter_name=value +``` + +Let's say your embedded dashboard has a filter connected to an editable parameter called "Breakfast". If you want to set the default value for the "Breakfast" filter to "Scrambled eggs": + +``` +your_embedding_url?breakfast=Scrambled_eggs +``` + +To specify default values for more than one filter, separate the filters with ampersands (&): + +``` +your_embedding_url?breakfast=Scrambled_eggs&lunch=Grilled_cheese +``` + +You can set multiple default values for a filter by separating the `key=value` pairs with ampersands (&): + +``` +your_embedding_url?breakfast=Scrambled_eggs&breakfast=Bacon +``` + +## Hiding filter widgets from a static embed + +If you have a lot of editable parameters (resulting in a lot of filter widgets), you can hide them from your static embed by adding `#hide_parameters` to the end of the URL in your iframe's `src` attribute: + +``` +your_embedding_url#hide_parameters=parameter_name +``` + +For example, if you want to hide a filter called "Breakfast" from your embedded dashboard: + +``` +your_embedding_url#hide_parameters=breakfast +``` + +You can hide multiple filter widgets by separating the parameter names with commas: + +``` +your_embedding_url#hide_parameters=breakfast,lunch +``` + +You can also simultaneously assign a parameter a default value _and_ hide its filter widget: + +``` +your_embedding_url?breakfast=Scrambled_eggs#hide_parameters=breakfast +``` + +## Unsigned parameter syntax + +Whenever you're adding a parameter to the embedding URL in your iframe's `src` attribute, note that: + +- Parameter _names_ are lowercase. +- Parameter _values_ are case-sensitive (the values must match your data). +- Spaces should be replaced by underscores. + +## Restricting data in a static embed with locked parameters + +If you want to restrict the data that's displayed in an embedded dashboard or SQL question, you can set up a **locked parameter**. A locked parameter filters the data in a dashboard or SQL question _before_ the results are displayed to people in a static embed. + +1. Go to your dashboard or SQL question. Make sure you've set up a [dashboard filter](../dashboards/filters) or [SQL variable](../questions/native-editor/sql-parameters). +2. Click on the **sharing icon** > **Embed this item in an application**. +3. Under **Parameters**, you'll find the names of your dashboard filters or SQL variables. +4. Select **Locked** for each parameter that you want to restrict your data with. +5. Optional: select a value under **Preview locked parameters** to see what the restricted data looks like. +6. Click **Publish** to save your changes. +7. Add or update the code on your server to [match the code generated by Metabase](./static-embedding#previewing-the-code-for-an-embed). + +You can use locked parameters to display filtered data based on attributes captured by your web server, such as a username or a tenant ID. For more examples, see the [reference apps repo](https://github.com/metabase/embedding-reference-apps). + +Locked parameters will apply the selected filter values to your original dashboard or SQL question, but they won't be displayed as filter widgets on your embed. Locked parameters may also limit the values that are shown in your [editable filter widgets](#adding-a-filter-widget-to-a-static-embed). + +If you just want to require a value for the parameter, you could set the filter as editable and configure the underlying question or dashboard to [always require a value](../dashboards/filters). + +## Updating a locked parameter + +Things to keep in mind if you need to make changes to your locked parameters. + +### Include all locked parameters in your server code + +Once you publish a chart or dashboard with a locked parameter, you _must_ include the name of the locked parameter in your server code. If you exclude the parameter name, the logs will gently remind you: `You must specify a value for :parameter in the JWT`. + +### To turn off a locked parameter, pass an empty array as its value in the JWT + +If you don't want the locked filter to apply, you can pass an empty array, `[]`, as the value for the parameter in the JWT. + +### Make sure the filter name matches the locked parameter name + +If you change the name of a query builder filter that's used as a locked parameter, make sure to update the parameter's name and value(s) in your server code as well. If your locked parameter is connected to a [SQL variable](../questions/native-editor/sql-parameters), you don't need to change the parameter's name and value(s). + +### Multiple locked parameters or multiple values + +The values for the locked parameter in your server code should match your filter's values exactly. The best way to set multiple locked parameters, or pass multiple values to a locked parameter, is to pick a filter value under **Preview locked parameters** and [preview the server code generated by Metabase](./static-embedding#previewing-the-code-for-an-embed). + +Using multiple locked parameters together will filter with `AND`, not `OR`. If you only want to apply a subset of the locked parameters, you must tell Metabase to [ignore the other locked parameters](#to-turn-off-a-locked-parameter-pass-an-empty-array-as-its-value-in-the-jwt). + +## Locked parameters limit the values available to other editable parameters + +Because locked parameters filter data _before_ the results are displayed in the embed, locked parameters limit the values available to other, editable filter widgets. + +For example, say you're embedding a dashboard with two filters, State and City. If you lock the State parameter with the value "Vermont", Metabase will only display the City filter widget on the dashboard, and the dropdown menu for that City filter widget will be limited to cities in Vermont. While you don't explicitly link the two filters, the two filters behave implicitly like [linked filters](../dashboards/filters#linking-filters). + +## Locked parameters on dashboards with SQL questions + +If your [locked parameter](#restricting-data-in-a-static-embed-with-locked-parameters) is linked to a dashboard filter that's in turn linked to a SQL question, you'll only be able to choose a _single_ value for your locked parameter. + +For example, let's say you have a dashboard filter called "Breakfast" with the values "Hash browns", "Muffin", and "Waffles". If the "Breakfast" filter is linked to _any_ SQL questions on the dashboard, you'll only be able to choose _one_ of the options for a locked parameter linked to the "Breakfast" filter. + +## Using locked parameters to power custom widgets in your app + +Because Metabase doesn't display locked parameters as filter widgets, you can use locked parameters to power custom filter widgets that you build in your app. You may want to build your own filter widget(s) to: + +- Make the widgets more consistent with the look and feel of your application. +- Include custom logic. For example, to have a filter widget remember recent values. +- Reuse one dashboard in different ways in different parts of your app. For example, you may have a dashboard with multiple locked parameters, and use one parameter in one case, and another parameter in another case. Like a sales dashboard that in one part of your app is locked by "region", in another by "team". + +## Customizing the appearance of a static embed + +![Look and feel: appearance settings on static embed](./images/04-preview.png) + +You can change the appearance of an embedded item by adding hash parameters (e.g., `#theme=night`) to the end of the URL in your iframe's `src` attribute. + +For example, the following embedding URL will display an embedded item in dark mode, without a border, and with its original title: + +``` +your_embedding_url#theme=night&bordered=false&titled=true +``` + +You can preview appearance settings from your question or dashboard's embedded appearance settings. + +| Parameter name | Possible values | +| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| `background` | true (default), false. Dashboards only. | +| `bordered` | true (default), false. | +| `locale\*` | E.g., `locale=ko`. See [list of locales](../configuring-metabase/localization#supported-languages) | +| `titled` | true (default), false. | +| `theme` | null (default), night. `theme=transparent` should work, but is deprecated (see [Transparent backgrounds](#transparent-backgrounds-for-embeds)) | +| `refresh` (dashboard only) | integer (seconds, e.g., `refresh=60`). | +| `font`\* | [font name](../configuring-metabase/fonts) | +| `downloads`\*\* | true (default), false. | + +\* Available on [Pro](/product/pro) and [Enterprise](/product/enterprise) plans + +\*\* Disabling downloads is available on [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +For global appearance settings, such as the colors and fonts used across your entire Metabase instance, see [Customizing Metabase's appearance](../configuring-metabase/appearance). + +## Setting the language for a static embed + +{% include plans-blockquote.html feature="Locales for static embeds" %} + +To change the UI language for a static embed, you can set its [locale](../configuring-metabase/localization#supported-languages). For example, to set a public link's language to Korean, you could append `#locale=ko`. + +``` +https://metabase.example.com/public/dashboard/7b6e347b-6928-4aff-a56f-6cfa5b718c6b?category=&city=&state=#locale=ko +``` + +If you have multiple params, separated them with an ampersand `&`: + +``` +category=Gadget&state=Vermont#theme=night&locale=ko +``` + +The `locale` param only changes the language for Metabase UI elements. The _content_'s language is defined by whomever created the item. So for example Metabase wouldn't translate the name of a question, but Metabase _would_ translate the UI text "Export to PDF". + +## Transparent backgrounds for embeds + +Making an embed transparent depends on the type of embed: + +- Dashboards: set `background=false`. The `background` parameter can be combined with the `theme` parameter (e.g., `background=false&theme=night`). +- Questions: set `theme=transparent` (deprecated, but still supported). + +## Disable downloads for an embedded question or dashboard + +{% include plans-blockquote.html feature="Disabling downloads" %} + +By default, Metabase will include a **Download** button on embedded questions, and an **Export to PDF** option on embedded dashboards. You can remove the option to download results by setting `downloads=false` in the embedding URL in the iframe's `src` attribute, see [customizing the appearance of static embeds](./static-embedding#customizing-the-appearance-of-static-embeds). + +If the download option is missing when you expected it to be available, check that the URL in the `src` attribute for your iframe has the parameter `downloads=true`. + +## Maximum request size + +The maximum length of a static embedding URL (including all parameters) is the value of your [`MB_JETTY_REQUEST_HEADER_SIZE`](../configuring-metabase/environment-variables#mb_jetty_request_header_size) environment variable. The default is 8192 bytes. + +If your static embedding URL exceeds the maximum header size, you'll see a log message like `URI too long`. You can update the environment variable to accept larger headers. If you're using a proxy server, you may need to set a corresponding property on the server as well. + +## Further reading + +- [Static embedding documentation](./static-embedding). +- [Strategies for delivering customer-facing analytics](/learn/metabase-basics/embedding/overview). +- [Publishing data visualizations to the web](/learn/metabase-basics/embedding/charts-and-dashboards). diff --git a/_docs/doc-update-detection/embedding/static-embedding.md b/_docs/doc-update-detection/embedding/static-embedding.md new file mode 100644 index 000000000..39eb908b4 --- /dev/null +++ b/_docs/doc-update-detection/embedding/static-embedding.md @@ -0,0 +1,205 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Embedding +title: 'Static embedding' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/embedding/static-embedding.md' +redirect_from: + - /docs/doc-update-detection/embedding/signed-embedding +--- + +# Static embedding + +Also known as: standalone embedding, or signed embedding. + +{% include shared/in-page-promo-embedding-workshop.html %} + +In general, embedding works by displaying a Metabase URL inside an iframe in your website. A **static embed** (or signed embed) is an iframe that's loading a Metabase URL secured with a signed JSON Web Token (JWT). Metabase will only load the URL if the request supplies a JWT signed with the secret shared between your app and your Metabase. The JWT also includes a reference to the resource to load, e.g., the dashboard ID, and any values for locked parameters. + +You can't use static embeds with [data sandboxes](../permissions/data-sandboxes), [drill-through](/learn/metabase-basics/querying-and-dashboards/questions/drill-through), and user-specific data isn't captured in [usage analytics](../usage-and-performance-tools/usage-analytics) because signed JWTs don't create user sessions (server-side sessions). For those features, check out [interactive embedding](./interactive-embedding). + +You can, however, restrict data in static embeds for specific people or groups by [locking parameters](./static-embedding-parameters#restricting-data-in-a-static-embed-with-locked-parameters). + +## How static embedding works + +If you want to set up interactive Metabase filters in your iframe, your web server will need to make requests to Metabase for updated data each time a website visitor updates the filter widget. + +To ask for updated data from Metabase, your web server will generate a new Metabase [embedding URL](#adding-the-embedding-url-to-your-website). For example, if a website visitor enters the value "true" in an [embedded filter widget](./static-embedding-parameters#adding-a-filter-widget-to-a-static-embed), your web server will generate a new embedding URL with an extra parameter: + +``` +your_metabase_embedding_url?filter=true +``` + +To prevent people from editing the embedding URL to get access to other parts of your Metabase (e.g., by changing the parameter to `filter=company_secrets`), your web server will add a signed JWT to the new embedding URL: + +``` +your_metabase_embedding_url/your_signed_jwt?filter=true +``` + +The signed JWT is generated using your [Metabase secret key](#regenerating-the-static-embedding-secret-key). The secret key tells Metabase that the request for filtered data can be trusted, so it's safe to display the results at the new embedding URL. Note that this secret key is shared for all static embeds, so whoever has access to that key will have access to all embedded artifacts. + +If you want to embed charts with additional interactive features, like [drill-down](/learn/metabase-basics/querying-and-dashboards/questions/drill-through) and [self-service querying](../questions/query-builder/editor), see [Interactive embedding](./interactive-embedding). + +## Turning on the embedding feature in Metabase + +1. Go to **Settings** > **Admin settings** > **Embedding**. +2. Toggle the **Enable embedding**. + +## Making a question or dashboard embeddable + +![Sharing button to embed dashboard](./images/sharing-embed.png) + +To create a static embed: + +1. Go to the question or dashboard that you want to embed in your website. +2. Click on the **sharing icon**. +3. Select **Embed**. +4. Select **Static embedding**. +5. Optional: [customize the appearance of the embed](./static-embedding-parameters#customizing-the-appearance-of-a-static-embed) +6. Optional: [Add parameters to the embed](./static-embedding-parameters). +7. Click **Publish**. + +![Preview](./images/04-preview.png) + +## Adding the embedding URL to your website + +The embedding URL for a question or dashboard is the Metabase URL that'll be displayed in your website's iframe. It's generated by your web server using your [Metabase site URL](../configuring-metabase/settings#site-url), [signed JWT](#how-static-embedding-works), and [parameters](./static-embedding-parameters): + +``` +metabase_site_url/embed/question/your_jwt_token?parameter_name=value +``` + +Once you've made a question or dashboard [embeddable](#making-a-question-or-dashboard-embeddable), you'll need to put the embedding URL for that question or dashboard on your website: + +1. Go to the question or dashboard > **sharing icon** > **Embed**. +2. Make any changes and copy the code. +3. [Preview the code](#previewing-the-code-for-an-embed) +4. Add the code to the server code that builds your website. +5. Add the frontend code to the code that generates the page where you want the embedded item to appear. + +For more examples, see our [reference apps repo](https://github.com/metabase/embedding-reference-apps). + +## Previewing the code for an embed + +1. Go to the question or dashboard > **sharing icon** > **Embed this item in an application**. +2. Click **Code**. +3. In the top code block, you'll find the sample code for your web server. You'll also find the iframe snippet to plug into your HTML template or single page app. + +When you make changes to the look and feel or parameter preview settings, Metabase will update the code and highlight the changes. Make sure to copy these changes to your actual server code. + +![Code samples for embedding](./images/05-code.png) + +Metabase generates server code for: + +- Clojure +- Node.js +- Python +- Ruby + +For iframe snippets: + +- ERB +- JSX +- Mustache +- Pug/Jade + +## If you serialize your Metabase, use Entity IDs in your static embeds + +Using [Entity IDs](../installation-and-operation/serialization#metabase-uses-entity-ids-to-identify-and-reference-metabase-items) in your static embeds will make sure that the IDs are stable when exporting from one Metabase and importing to another Metabase. + +To use an Entity ID in a static embed, all you need to do is edit the `resource` map in the `payload` used to sign your token. Replace the item's (autopopulated) ID with its Entity ID and you're done. + +So, in the code below you'd change the `{ question: }` to: + +```js +const payload = { + resource: { question: }, + params: {}, + exp: Math.round(Date.now() / 1000) + (10 * 60) // 10 minute expiration +}; +``` + +If you don't serialize your Metabase, don't worry about which ID you use; both will work just fine. + +## Editing an embedded question or dashboard + +If you change the [parameters](./static-embedding-parameters) of your embedded item: + +1. After making your changes, copy the code Metabase generates. +1. Click **Publish** again. +1. [Update the code](#adding-the-embedding-url-to-your-website) on your server so that it matches the code generated by Metabase. + +## Disabling embedding for a question or dashboard + +You can find a list of all static embeds of questions and dashboards from **Admin settings** > **Embedding** > **Static embedding** > **Manage**. + +1. Visit the embeddable question or dashboard. +2. Click on the **sharing icon** (square with an arrow pointing to the top right). +3. Select **Embed**. +4. Select **Static embedding** +5. Click **Unpublish**. + +## Customizing the appearance of static embeds + +See [Customizing appearance of static embeds](./static-embedding-parameters#customizing-the-appearance-of-a-static-embed) + +## Auto-refreshing the results of an embedded dashboard + +> Auto-refreshing is only available for dashboards, not questions. + +To refresh the results of a dashboard at a specific cadence, you can parameterize the embedded URL with `refresh`. For example, to set an embedded dashboard to refresh every 60 seconds, you would append `refresh=60` to the URL. + +For example, the following code for generating an iframe URL for a dashboard would display the dashboard's title and refresh its results every 60 seconds. + +```js +var iframeUrl = + METABASE_SITE_URL + "/embed/dashboard/" + token + "#titled=true&refresh=60"; +``` + +For the full list options you can parameterize, see [customizing the appearance of a static embed](./static-embedding-parameters#customizing-the-appearance-of-a-static-embed). + +## Removing the "Powered by Metabase" banner + +![Powered by Metabase](./images/powered-by-metabase.png) + +The banner appears on static embeds created with Metabase's open-source version. To remove the banner, you'll need to upgrade to a [Pro](/product/pro) or [Enterprise](/product/enterprise) plan. + +## Regenerating the static embedding secret key + +Your embedding secret key is used to sign JWTs for all of your [embedding URLs](#adding-the-embedding-url-to-your-website). + +1. Go to **Settings** > **Admin settings** > **Embedding**. +2. On the **Static embedding** card, click on **Manage**. +3. Under **Regenerate secret key**, click **Regenerate key**. + +This key is shared across all static embeds. Whoever has access to this key could get access to all embedded artifacts, so keep this key secure. If you regenerate this key, you'll need to update your server code with the new key. + +## Resizing dashboards to fit their content + +Dashboards are a fixed aspect ratio, so if you'd like to ensure they're automatically sized vertically to fit their contents you can use the [iFrame Resizer](https://github.com/davidjbradshaw/iframe-resizer) script. Metabase serves a copy for convenience: + +```html + + +``` + +Due to iframe-resizer's licensing changes, we recommend that you use iframe-resizer version 4.3.2 or lower. + +## Custom destinations on dashboards in static embeds + +You can only use the **URL** option for [custom destinations](../dashboards/interactive#custom-destinations) on dashboards with static embedding. External URLs will open in a new tab or window. + +You can propagate filter values into the external URL, unless the filter is locked. + +## Further reading + +- [Parameters for static embeds](./static-embedding-parameters). +- [Reference apps repo](https://github.com/metabase/embedding-reference-apps). +- [Strategies for delivering customer-facing analytics](/learn/metabase-basics/embedding/overview). +- [Publishing data visualizations to the web](/learn/metabase-basics/embedding/charts-and-dashboards). +- [Customizing Metabase's appearance](../configuring-metabase/appearance). diff --git a/_docs/doc-update-detection/embedding/tsconfig.json b/_docs/doc-update-detection/embedding/tsconfig.json new file mode 100644 index 000000000..fd6209b24 --- /dev/null +++ b/_docs/doc-update-detection/embedding/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "paths": { + "@metabase/embedding-sdk-react": ["../../resources/embedding-sdk"], + "@metabase/embedding-sdk-react/*": ["../../resources/embedding-sdk/dist/nextjs.d.ts"] + }, + "allowJs": true, + "checkJs": true, + "moduleDetection": "force", + "noEmit": true, + "noImplicitAny": false + }, + "include": ["./**/snippets"] +} diff --git a/_docs/doc-update-detection/exploration-and-organization/collections.md b/_docs/doc-update-detection/exploration-and-organization/collections.md new file mode 100644 index 000000000..f95382f50 --- /dev/null +++ b/_docs/doc-update-detection/exploration-and-organization/collections.md @@ -0,0 +1,126 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Exploration and Organization' +title: Collections +source_url: 'https://github.com/metabase/metabase/blob/master/docs/exploration-and-organization/collections.md' +redirect_from: + - /docs/doc-update-detection/users-guide/collections +--- + +# Collections + +After your team has been using Metabase for a while, you’ll probably end up with lots of saved questions and dashboards. + +![Our analytics](./images/our-analytics-page.png) + +Collections are the main way to organize questions, dashboards, and [models][models]. You can think of them like folders or directories. You can nest collections in other collections, and move collections around. One thing to note is that a single item, like a question or dashboard, can only be in one collection at a time (excluding parent collections). + +## Collection types + +### Regular collections + +They're like file-system folders. You can put stuff in them. + +### Official collections + +{% include plans-blockquote.html feature="Official collections" %} + +![Official collections](./images/official-collection.png) + +Metabase admins can designate collections as "official" with the following effects: + +- These collections have a yellow badge to let people know that the items in the collection are the ones people should be looking at (or whatever "official" means to you). +- Questions in Official collections added to Dashboards that are not in Official collections will show an Official badge next to their name on the Dashboard. +- Questions and dashboards in Official collections are also more likely to show up at the top of search results. + +Pairing Official badges with [verified items](./content-verification) can help everyone in your Metabase sort out which questions people can trust. + +To add an Official badge to a collection, an admin can visit the collection and click on the dot dot dot menu (**...**) and select **Make collection official**. Admins can also remove an Official badge in the same menu. Admins can also mark a collection as Official or not when they first create the collection. + +## Collection permissions + +[Administrators can give you different kinds of access](../permissions/collections) to each collection: + +- **View access:** you can see the collection and its contents, but you can't modify anything or put anything new into the collection. +- **Curate access:** you can edit, move, or delete the collection and its contents. You can also move or save new things in it and create new collections inside of it, and can also pin items in the collection to the top of the screen. Only administrators can edit permissions for collections, however. +- **No access:** you can't see the collection or its contents. If you have access to a dashboard, but it contains questions that are saved in a collection you don't have access to, those questions will show a permissions notification instead of the chart or table. + +## Your personal collection + +In addition to the collections you and your teammates have made, you'll also always have your own personal collection that only you and administrators can see. To find it, click on the "browse all items" button on the homepage and click on "my personal collection" in the list of collections. + +You can use your personal collection as a scratch space to put experiments and explorations that you don't think would be particularly interesting to the rest of your team, or as a work-in-progress space where you can work on things and then move them to a shared place once they're ready. + +To share items in your personal collection, for example to add a question in your personal collection to a dashboard in a public collection, you'll first need to move that item to a public collection. + +## Pinned items + +In each collection, you can pin important or useful dashboards, models, and questions to make them stick to the top of the screen. Pinned items will also be displayed as large cards to make them stand out well. + +![Pins](./images/pinned-items.png) + +To pin and un-pin things in a collection, you need to have **Curate** permissions for that collection. + +- To pin an item, find the item on the collection page, go into the three dot menu (**...**), and select **Pin this**. + +- To unpin a pinned item, hover over the pinned card, go to the three dot menu (**...**), and select **Unpin**. + +For pinned questions, you can also choose whether to display the visualization from the three dot menu (**...**). + +![Show pinned viz](./images/pinned-show-viz.png) + +Pinned items will appear pinned for all people looking at the collection. If you just want to organize _your_ favorite items, you should [bookmark them](./exploration#bookmarks) (only you can see your bookmarks). + +## Moving items from collection to collection + +To move an item from one collection to another, just click and drag it onto the collection where you want it to go. You can also click on the the three dot menu (**...**) menu to the right of the item and pick the **Move** action. + +If you're trying to move several things at once, click on the checkboxes next to the items' icons to select them, then click the Move action that pops up at the bottom of the screen. + +![Selecting questions](./images/question-checkbox.png) + +Note that you have to have Curate permission for the collection that you're moving a question into _and_ the collection you're moving the question out of. Metabase admins can move items into (and out of) anyone's [personal collection](#your-personal-collection). + +## Moving questions into dashboards + +You can move any question from a collection to a dashboard (and vice versa). Visit a question, click on the three-dot menu (**...**) and select **Move**. Pick a destination and your question will enjoy its new home. + +### Bulk-moving questions into dashboards + +If a collection has questions that have been added to dashboards in that collection, you can move the questions into their dashboards to declutter the collection. + +To bulk-move questions into their dashboards, visit a collection page, click on the three-dot menu (**...**), and select **Move questions into their dashboards**. Metabase will pop up a modal to let you know what's going on: + +- If a question only appears in a single dashboard in this collection, it'll be moved into that dashboard to declutter the collection. +- Permissions won't change. + +You can preview the changes before initiating the move. Hit the preview button to see which questions will be moved into which dashboards. No questions will be moved into dashboards they weren't already added to. All this move does is "save" the questions to the dashboard rather than the collection. + +In general, you want to save questions to dashboards unless you know people will want to re-use that question in multiple dashboards. + +## Cleaning up collections + +{% include plans-blockquote.html feature="Collection cleanup" %} + +It's possible to ask too many questions. Fortunately, you can clean up collections by [trashing items](./delete-and-restore) that people haven't even looked at for a period of time. Cleaning up old questions and dashboards can keep your Metabase from getting too cluttered, and you can always resurrect items from the trash if you need to. + +On a collection page, click on the three-dot menu (**...**) and select **Clear out unused items**. Metabase will pull up a modal where you can select unused items to move to the trash. You can set how long items need to go unnoticed before they're culled by setting **Not used in over**, which you can set to trash items from one month ago to over two years ago. There's also a toggle to include/exclude items in sub-collections. + +## Events and timelines + +You can add events to collections, and organize those events into timelines. See [Events and timelines](events-and-timelines). + +## Uploading data + +You can upload data to collections. See [Uploading data](./uploads)] + +## Further reading + +- [Keeping your analytics organized](/learn/metabase-basics/administration/administration-and-operation/same-page) +- [Multiple environments](/learn/metabase-basics/administration/administration-and-operation/multi-env#one-collection-per-environment) + +[dashboards]: ../dashboards/introduction +[models]: ../data-modeling/models diff --git a/_docs/doc-update-detection/exploration-and-organization/content-verification.md b/_docs/doc-update-detection/exploration-and-organization/content-verification.md new file mode 100644 index 000000000..4c70ebdbc --- /dev/null +++ b/_docs/doc-update-detection/exploration-and-organization/content-verification.md @@ -0,0 +1,60 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Exploration and Organization' +title: 'Content verification' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/exploration-and-organization/content-verification.md' +--- + +# Content verification + +{% include plans-blockquote.html feature="Content verification" %} + +![Verified icon](./images/verified-icon.png) + +Admins can verify items to let others know that the content is accurate and up to date. + +## Benefits of verifying an item + +- Verified items get a fancy blue checkmark next to them. +- They show up higher in search suggestions and results. +- The models and metrics browsers allow you to filter for verified items. + +![Verified models toggle](./images/verified-only.png) + +## Verifying items + +To verify an item, an admin can click on the three-dot menu (**...**) in the upper right when viewing that item and select: **Verify this item**. + +![Verify this dashboard](./images/verify-this-dashboard.png) + +## Removing verification status + +To remove verification from an item, admins can: + +1. Visit the item. +2. Click on the three-dot menu (**...**). +3. Select **remove verification**. + +## Changes to queries require re-verification + +If anyone makes any changes to a question, metric, or model's _query_, Metabase will remove the verification status (the check mark will disappear). The logic here is that changing the results in any way should require re-verification. + +Dashboards verification works a little differently (since there's no underlying query). Dashboard verification is sticky; you can modify a verified dashboard and it'll retain its verified status. + +## Verifiable items + +Admins can verify the following items: + +- [Questions](../questions/start) +- [Models](../data-modeling/models) +- [Metrics](../data-modeling/metrics) +- [Dashboards](../dashboards/introduction) + +Dashboard verification status has no affect on its questions. Questions must be verified independently. + +## Further reading + +- [Official collections](./collections#official-collections) diff --git a/_docs/doc-update-detection/exploration-and-organization/data-model-reference.md b/_docs/doc-update-detection/exploration-and-organization/data-model-reference.md new file mode 100644 index 000000000..ac1e7f7cd --- /dev/null +++ b/_docs/doc-update-detection/exploration-and-organization/data-model-reference.md @@ -0,0 +1,44 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Exploration and Organization' +title: 'Data reference' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/exploration-and-organization/data-model-reference.md' +redirect_from: + - /docs/doc-update-detection/users-guide/12-data-model-reference + - /docs/doc-update-detection/questions/native-editor/data-model-reference +--- + +# Data reference + +You can open the data reference from: + +- The Metabase sidebar > **Browse** > **Databases** > **Learn about our data**. +- Hovering over a table in the data browser and clicking on the book icon that appears. +- The native/SQL > **Book** icon. + +## Browse data reference + +The data reference is a collection of pages organized by database, then tables in that database (the same structure you use to [pick data](../questions/query-builder/editor#picking-data)). The data reference section is a great place to find information about the [data types](/learn/grow-your-data-skills/data-fundamentals/data-types-overview) of columns in your data. + +## Data reference in the native editor + +Sometimes when you're writing a query, you might forget the exact names of different tables or columns, or which table contains what. That’s where the **Data reference** comes in handy. + +To bring up the data reference panel in the native/SQL editor, click on the open book icon. + +This panel lists all the databases you have access to, and the [models](../data-modeling/models) and tables, and the fields inside of them. + +![Data reference sidebar](./images/DataReference.png) + +Click on the model or table you would like to explore further to see a description of it and a list of all the columns it has. Each table or column will only contain a description if your admin wrote something in the Table Metadata section of the Admin Panel. + +If you click on a column you’re interested in, you’ll see a description of its contents, as well as a list of sample values for columns that don't have a huge number of distinct values. + +## Connections + +In the data reference sidebar, under **Connections**, you can find a list of table relationships (defined by [foreign keys](/glossary/foreign_key)). + +If a foreign key relationship exists in your database, but doesn't show up in your Metabase, your Metabase admin will need to update your [Metabase Table Metadata](../data-modeling/metadata-editing). diff --git a/_docs/doc-update-detection/exploration-and-organization/delete-and-restore.md b/_docs/doc-update-detection/exploration-and-organization/delete-and-restore.md new file mode 100644 index 000000000..ed2608091 --- /dev/null +++ b/_docs/doc-update-detection/exploration-and-organization/delete-and-restore.md @@ -0,0 +1,152 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Exploration and Organization' +title: 'Delete and restore' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/exploration-and-organization/delete-and-restore.md' +--- + +# Delete and restore + +Sometimes your questions, dashboards, models, or collections outlive their usefulness. You can send outdated items to **Trash**. + +![Move to trash](./images/move-to-trash.png) + +Items in **Trash** won't show up in search (unless you use [advanced search filters](./exploration)), and you won't be able to use them to create new questions and dashboards. + +Moving items to Trash isn't permanent; you'll be able to restore them to their original parent collection, or move them to another collection. But if you'd like to delete items permanently, [you can do that too](#permanently-deleting-items). + +Deleting an item will affect any [dashboards](../dashboards/introduction), [subscriptions](../dashboards/subscriptions), or [SQL questions](../questions/native-editor/referencing-saved-questions-in-queries) that depend on that item, so be careful! + +## See items in Trash + +You can find Trash at the bottom of the left navigation sidebar below all the collections: + +![Trash](./images/trash.png) + +You can think of Trash as a special type of collection. In **Trash**, you can see deleted items from the collections that you have [Curate permissions](../permissions/collections#collection-permission-levels) on. You can order deleted items by type (questions, dashboards, etc), time it was deleted, and who deleted it. + +You;'ll be able to see the contents of deleted dashboards, questions, and models in Trash, but you won't be able to modify them. + +## Search in Trash + +To find items in Trash, you can use [advanced search](./exploration) with a "Search items in trash" toggle. + +## Deleting and restoring items + +To move an item (question, dashboard, model, or collection) to Trash: + +1. Go to the question you want to delete; +2. Click on the three dots menu; +3. Select "Move to trash". + +When a collection is moved to the trash, Metabase moves all items in the collection to the trash as well. + +You'll still be able to see the contents of the items in Trash, but you won't be able to modify them or use them as a source for other questions. + +If you need to delete multiple items from the same collection, you can delete them in bulk: + +1. Go to the collection containing items you want to delete; +2. Click the checkboxes next to the items to select them; +3. Select "Move to trash" + +To restore an item: + +1. Go to Trash; +2. Find the item you'd like to delete. You can sort deleted items to make it easier to find the item, or [search for your question in Trash](#search-in-trash); +3. Click on the checkbox next to the item to select it; +4. Select "Restore". + +> Restoring a collection will also restore all the items from that collection. + +If the item's original parent collection has been deleted as well, you won't see an option to **Restore**. You'll still be able to move the it from Trash to a different collection. + +### Cleaning up collections + +To move older, unused items in bulk to the trash, check out [cleaning up collections](./collections#cleaning-up-collections). + +## How deleting an item affects related items + +Deleting or restoring an item will affect other items that depend on that item. + +### Questions + +What happens to related items when you delete a question? + +| Related item | In Trash | Permanently deleted | Restored | +| ---------------------------------- | -------------- | ---------------------------------- | -------------- | +| Dashboard | Card removed | Card removed | Card restored | +| Question based on deleted question | Works normally | Breaks with `Card not found` error | Works normally | +| Alerts | Removed | Removed | Not restored | + +### Dashboards + +What happens to related items when you delete a dashboard? + +| Related item | In Trash | Permanently deleted | Restored | +| ------------------------------------- | -------------------------- | -------------------------- | -------------- | +| Questions saved to that dashboard | Moved to trash | Deleted | Restored | +| Questions not saved to that dashboard | Works normally | Works normally | Works normally | +| Subscriptions | Deactivated | Deactivated | Restored | +| Custom homepage | Revert to default homepage | Revert to default homepage | Restored | + +### Model + +What happens to related items when you delete a model? + +| Related item | In Trash | Permanently deleted | Restored | +| ---------------------------------- | -------------- | ---------------------------------- | -------------- | +| Question based on deleted question | Works normally | Breaks with `Card not found` error | Reactivated | +| Dashboard | Card removed | Card removed | Card restored | +| Action | Works normally | Deleted | Works normally | + +## Collections + +What happens to related items when you delete a collection? + +| Related item | In Trash | Permanently deleted | Restored | +| ---------------------------------------------- | -------- | ------------------- | -------- | +| All items and subcollections in the collection | In Trash | N/A | Restored | + +> You can't permanently delete collections + +## Permanently deleting items + +Moving an item to Trash doesn't delete the item completely: you'll be able to restore the item from the Trash. + +To permanently delete an item: + +1. Go to Trash; +2. Find the item you'd like to delete; +3. Click on the checkbox next to the item to select it; +4. Select "Permanently delete". If you click this button, you won't be able to recover the item. It'll be lost to the void. + +> You can't permanently delete collections + +## Deleting and restoring events and timelines + +Events and timelines can be archived and unarchived. See [Archiving Events and timelines](events-and-timelines#archiving-timelines). + +You won't see archived Events and Timelines in Trash. To see archived events and timelines, you need to [access them from the collection's page](events-and-timelines#view-archived-events-and-timelines). + +## Deleting and restoring Snippets + +Snippets can be archived and unarchived. See [Archiving Snippets](../questions/native-editor/snippets#archiving-snippets). + +You won't see archived Snippets in Trash. To see archived Snippets, you need to [access them from the Snippet menu](../questions/native-editor/snippets#snippet-menu). + +## Deleting segments + +Segments can be retired. See [Retiring Segments](../data-modeling/segments#editing-and-retiring-segments). + +You won't see retired Segments in Trash. + +## Deleting subscriptions and alerts + +See [Deleting a subscription](../dashboards/subscriptions#deleting-a-subscription) and [Deleting alerts](../questions/alerts#editing-and-deleting-alerts). + +## Deleting databases + +See [Deleting databases](../databases/connecting#deleting-databases). diff --git a/_docs/doc-update-detection/exploration-and-organization/events-and-timelines.md b/_docs/doc-update-detection/exploration-and-organization/events-and-timelines.md new file mode 100644 index 000000000..b397f52ea --- /dev/null +++ b/_docs/doc-update-detection/exploration-and-organization/events-and-timelines.md @@ -0,0 +1,133 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Exploration and Organization' +title: 'Events and timelines' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/exploration-and-organization/events-and-timelines.md' +redirect_from: + - /docs/doc-update-detection/users-guide/events-and-timelines +--- + +# Events and timelines + +A lot of discussions around data have a moment when someone asks a question related to a specific point in time: "Wait, what's the spike in March again?", or "When did the new widget launch?" + +Events and timelines are a way to capture that chronological knowledge and make it available when you need it, in context (that is, when you're viewing a chart). Events are a great way to store institutional knowledge about what happened and when, so people (including yourself three months from now) won't have to figure out (again) why the line chart spiked back in March. + +## Events + +![An event on a time series](./images/event-on-a-time-series.png) + +An event is basically a date + a title + a description + an icon. You can add events to Metabase to show important milestones, launches, or anything else, right alongside your data. + +Metabase will only display events on time series charts when viewing an individual question. Metabase won't display events on charts in dashboard cards. + +## Timelines + +Timelines are groups of events associated with a [collection](collections). + +![Timeline sidebar](./images/timeline-sidebar.png) + +For example, you may want to have a timeline that contains important email or sales dates, or an outages timeline that tracks downtime. You can move events between timelines, and move timelines from collection to collection. + +Collections can have timelines, and timelines can contain events. In practice what this means is that events you've added to a timeline will show up on time series questions stored in the same collection as that timeline. + +- If you don't explicitly create a timeline yet, but you do create events, Metabase will automatically create a timeline for you (which acts as the default timeline for the collection). +- You can have multiple timelines for the same collection. +- Timelines associated with collections do not apply to that collection's sub-collections. + +### Adding events when viewing a collection + +When viewing a [collection](collections), you can view, add, or edit events by clicking on the **calendar** icon in the upper right. + +![In a collection, view or add events by clicking on the calendar icon](./images/event-calendar.png) + +Once you create an event, the event will show up in charts in the collection, provided: + +- The date of the event falls within the chart's time range. +- The timeline is visible (more on that [below](#adding-events-when-viewing-a-question)). + +You'll see an icon along the x-axis that plots the event. A vertical line will extend from the event to show when the data plotted on the chart intersects with the event. + +![An event on a chart](./images/example-event.png) + +## Adding events when viewing a question + +If your question is a time series, you can click on the **Calendar** in the bottom right of the question, and Metabase will open the timeline sidebar. Metabase will list any timelines and their events that fall in the range of your time series. You can: + +- Toggle timeline visibility (including timelines from other collections) +- Add a new event (even if you haven't saved the question yet). +- Edit, move, or archive an event. + +## Viewing events and timelines on a chart from a different collection + +If you're viewing a question with a time series chart from a _different_ collection, you can temporarily apply a timeline to the chart by clicking on the **calendar** icon in the bottom right of the question and selecting the timeline and events you want to display. + +These selections are temporary; if you reload the question, Metabase will drop the events from the chart. + +### To hide the timeline and its events on a chart + +To temporarily hide the events from a chart: + +1. Click on the **calendar** icon in the bottom right. +2. Uncheck the timeline or event. + +Your selections will reset on reload. + +To permanently hide the timeline and its events, you'll need to [archive the timeline](#archiving-timelines). Alternatively, you could move the question to a different collection. + +## Edit an event + +![Edit an event](./images/edit-an-event.png) + +To edit an event: + +1. Click the calendar icon in the top right of a collection. +2. Go to the timeline that contains the event, click on the event's three-dot menu (**...**). +3. Select: + - **Edit event**: its title, description, and icon. + - **Move event**: to another timeline. + - **Archive event**: to hide the event from charts. + +## Archiving timelines + +To archive a timeline: + +1. Go to the timeline's collection and click on the **calendar** icon in the top right. +2. Select the timeline, then click on the three-dot menu (**...**). If the collection only has one timeline, click on the three-dot menu (**...**). +3. Select **Edit timeline details**. +4. Click on the red **Archive timeline and all events**. + +### View archived events and timelines + +> Archived events and timelines can only be viewed from the collection. They don't show up in the [Trash](../exploration-and-organization/delete-and-restore). + +To view (and resurrect) archived timelines and events: + +1. Click on the **Calendar** icon in the relevant collection. +2. Click on the three-dot menu **...** menu. +3. Select **View archived timelines**. Metabase will display archived events or timelines. +4. If you want to unarchive an item, click on the three-dot menu **...** next to the event or timeline and select the **Unarchive** option. + +To permanently delete an archived event or timeline, click on the three-dot menu (**...**) and select **Delete**. + +Then you can delete the archived events from the **View archived events** modal, or timelines from the **View archived timelines** modal. + +## Event and timeline permissions + +Event and timeline permissions depend on your [collection permissions](../permissions/collections). + +- **View access**: you can view the collection's events and timelines. You can also temporarily apply timelines and events to time series in other collections. +- **Curate access**. Anyone with curate access to a collection can add events and timelines to that collection. + +### Make a timeline and its events available for everyone + +If you want the event and timeline to be available to everyone, create the timeline in a collection that the [All Users group](../people-and-groups/managing#all-users) has access to, as by default everyone is in the All Users group. + +Note that for questions outside of that collection, you can only temporarily apply those timelines to charts. The timelines won't appear automatically when you reload the chart. + +## Further reading + +- [Keeping your Metabase organized](/learn/metabase-basics/administration/administration-and-operation/same-page) diff --git a/_docs/doc-update-detection/exploration-and-organization/exploration.md b/_docs/doc-update-detection/exploration-and-organization/exploration.md new file mode 100644 index 000000000..797a57305 --- /dev/null +++ b/_docs/doc-update-detection/exploration-and-organization/exploration.md @@ -0,0 +1,133 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Exploration and Organization' +title: 'Basic exploration' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/exploration-and-organization/exploration.md' +redirect_from: + - /docs/doc-update-detection/users-guide/03-basic-exploration +--- + +# Basic exploration + +## See what your teammates have made + +As long as you're not the very first user in your team's Metabase, the easiest way to start exploring your data is by looking at dashboards, charts, and lists that your teammates have already created. The best place to start is by checking out any dashboards that might be pinned on your home page, or in [collections][collections] you have access to. + +## Command palette + +The command palette lets you create new things, search your content, or jump to anywhere in your Metabase. + +To bring up the command palette, hit cmd/ctrl + k. That's `cmd + k` for Macs, or `ctrl + k` for Windows PCs. + +You can use the command palette to: + +- Create new things (like new questions and dashboards) +- Find things (saved questions, dashboards, models, etc.) +- Find and jump to Admin and account settings. + +So anytime you want to do or find anything in Metabase, just hit `cmd/ctrl + k` and start typing what you want to do. + +> The command palette is currently unavailable in [interactive embedding](../embedding/interactive-embedding) contexts. + +## Advanced search + +To filter your search results, hit `cmd/ctrl + k` to bring up the command palette and enter your search term. The first result is a link to "Search and filter all X results". + +![Search results](./images/search-results.png) + +Searches take into account items’ titles, descriptions, and other metadata — you can even search the contents of your SQL queries. For example, you can search for things like `SELECT escape_pod FROM mothership` and find that one question you worked on six months ago. The results will display which collection each item is saved in, what kind of object it is, and whether it’s pinned. Note that you'll only ever see items in that are in collections you have permission to view. + +You can search by: + +- **Content type**: dashboard, question, model, collection, database, table. +- **Creator**: who made the thing. +- **Last editor**: who made the last saved change on the thing. +- **Creation date**: when the thing entered our universe. +- **Last edit date**: when someone last cared enough to update the thing. +- **Verified items only**. Only show items that [have been verified](./content-verification). +- **Search the contents of native queries**: search through the SQL/native code in questions. +- **Search items in trash**: include the depths of oblivion in your search. + +## Browse your databases + +> Whether a group has access to the database browser depends on the group's [Create queries permission](../permissions/data#create-queries-permissions). + +![Browse databases](./images/browse-data.png) + +The left sidebar lists your databases, [models](../data-modeling/models), and [metrics](../data-modeling/metrics). + +[Pro](/product/pro) and [Enterprise](/product/enterprise) plans include the ability to filter for [verified models and metrics](./content-verification). + +The database browser will list all the databases connected to your Metabase. Hover over a table and click on the **bolt** icon to [X-ray](x-rays) the table, or click on the **book** icon to view more info about the table: its fields and their descriptions (if any), what questions are based on that table, and more. + +To learn more, see [Exploring data with Metabase's data browser](/learn/metabase-basics/querying-and-dashboards/data-browser). + +## Exploring collections + +[Collections][collections] in Metabase are a lot like folders. They're where Metabase keeps all your team's dashboards and charts. + +![A collection](./images/collection-detail.png) + +Your teammates might have pinned some items to the top of your collection. + +- [dashboards](../dashboards/introduction) +- [models](../data-modeling/models) +- [metrics](../data-modeling/metrics) +- [questions](../questions/start) + +Collections have a list of any other items that are saved within them, and you can see what other collections are saved inside of the current one by checking out the navigation sidebar. + +## Exploring dashboards + +[Dashboards][dashboards] are a set of questions and text cards that you want to be able to refer to regularly. + +If you click on a part of a chart, such as a bar in a bar chart, or a dot on a line chart, you'll see the **Action menu**, with actions you can take to dive deeper into that result, branch off from it in a different direction, or see automatic insights to [X-ray](x-rays) the data. + +![Drill-through menu](images/automatic-insights.png) + +In this example of orders by product category per month, clicking on a data point on this line chart gives us the ability to: + +- **See these Orders**: See a list of the orders for a particular month. +- **See this month by week**. +- **Break out by ...**: See things like the Gizmo orders in June 2023 broken out by the status of the customer (e.g., `new` or `VIP`). Different charts will have different breakout options, such as **Location** and **Time**. +- **Automatic insights**: See orders for a particular category over a shorter time range. +- **Filter by this value**: update the chart based on the value you clicked: equal to, less than, greater than, or not equal to. + +> Note that while charts created with SQL currently only have [limited drill-through menu](../questions/native-editor/writing-sql#drill-though-in-sql-questions), you can add SQL questions to a dashboard and customize their click behavior. You can send people to a [custom destination](/learn/metabase-basics/querying-and-dashboards/dashboards/custom-destinations) (like another dashboard or an external URL), or have the clicked value [update a dashboard filter](/learn/metabase-basics/querying-and-dashboards/dashboards/cross-filtering). + +Clicking on a table cell will often allow you to filter the results using a comparison operator, like =, >, or <. For example, you can click on a table cell, and select the less than operator `<` to filter for values that are less than the selected value. + +![Comparison operator filters](images/comparison-operator-filters.png) + +Lastly, clicking on the ID of an item in a table gives you the option to go to a detail view for that single record. For example, you can click on a customer's ID to see the profile view for that customer. + +![Detail view](images/detail-view.png) + +When you add questions to a dashboard, you can have even more control over what happens when people click on your chart. In addition to the default drill-through menu, you can add a [custom destination](/learn/metabase-basics/querying-and-dashboards/dashboards/custom-destinations) or [update a filter](/learn/metabase-basics/querying-and-dashboards/dashboards/cross-filtering). Check out [interactive dashboards](../dashboards/interactive). + +## Bookmarks + +**Bookmarks** are a way to quickly get back to things you visit frequently (or have been working on recently). Bookmarked items show up in the main navigation sidebar above [collections][collections]. + +To bookmark an item, look for the **ribbon** icon in the upper right corner of the item's page. You can bookmark: + +- Questions +- Models +- Dashboards +- Collections + +To add or remove a bookmark from an item, click on the three-dot menu (**...**) next to the item in the collection. + +Some things to remember with bookmarks: + +- Bookmarks are personal; other people can't see your bookmarks. If you want to highlight something for everyone, you'll want to put it in an official collection and/or pin the item in the collection (see [collections][collections]). +- If you end up bookmarking a lot of items, you can collapse the bookmarks section in the sidebar (or remove the bookmarks that are just getting in your way). +- Items that you bookmark will get a boost in your search results (but not the search results of other people). +- To reorder bookmarks, simply drag and drop them in the sidebar. + +[collections]: ./collections +[dashboards]: ../dashboards/start +[models]: ../data-modeling/models diff --git a/_docs/doc-update-detection/exploration-and-organization/history.md b/_docs/doc-update-detection/exploration-and-organization/history.md new file mode 100644 index 000000000..3031827a3 --- /dev/null +++ b/_docs/doc-update-detection/exploration-and-organization/history.md @@ -0,0 +1,29 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Exploration and Organization' +title: History +source_url: 'https://github.com/metabase/metabase/blob/master/docs/exploration-and-organization/history.md' +--- + +# History + +For questions, dashboards, and models, Metabase keeps a version history for the previous fifteen versions of that item. You can view changes, and revert to previous versions. + +## Viewing tracked changes + +1. Go to your question, dashboard, or model. +2. Click the info icon. +3. Click on the **History** tab. +4. The History tab will display the item's history of up to 15 versions. + +Metabase will keep track of a version each time you save, move, revert, [move to Trash](./delete-and-restore), or [verify](./content-verification) an item. + +## Reverting to previous versions + +1. Go to your question, dashboard, or model. +2. Click the info icon (an **i** in a circle). +3. A sidebar will appear with up to fifteen previous versions. +4. Click on the **back arrow** beside a version to revert your item to that point in time. diff --git a/_docs/doc-update-detection/exploration-and-organization/images/DataReference.png b/_docs/doc-update-detection/exploration-and-organization/images/DataReference.png new file mode 100644 index 000000000..9912bd827 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/DataReference.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/append-data.png b/_docs/doc-update-detection/exploration-and-organization/images/append-data.png new file mode 100644 index 000000000..df5046c6b Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/append-data.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/automatic-insights.png b/_docs/doc-update-detection/exploration-and-organization/images/automatic-insights.png new file mode 100644 index 000000000..24cb911ca Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/automatic-insights.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/browse-data-x-ray.png b/_docs/doc-update-detection/exploration-and-organization/images/browse-data-x-ray.png new file mode 100644 index 000000000..c1c8a8380 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/browse-data-x-ray.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/browse-data.png b/_docs/doc-update-detection/exploration-and-organization/images/browse-data.png new file mode 100644 index 000000000..47b9e402e Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/browse-data.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/collection-detail.png b/_docs/doc-update-detection/exploration-and-organization/images/collection-detail.png new file mode 100644 index 000000000..f54c9f844 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/collection-detail.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/comparison-operator-filters.png b/_docs/doc-update-detection/exploration-and-organization/images/comparison-operator-filters.png new file mode 100644 index 000000000..e43d51fe3 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/comparison-operator-filters.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/data-reference.png b/_docs/doc-update-detection/exploration-and-organization/images/data-reference.png new file mode 100644 index 000000000..cfca7fa3b Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/data-reference.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/detail-view.png b/_docs/doc-update-detection/exploration-and-organization/images/detail-view.png new file mode 100644 index 000000000..2f5ed3f84 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/detail-view.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/edit-an-event.png b/_docs/doc-update-detection/exploration-and-organization/images/edit-an-event.png new file mode 100644 index 000000000..5ba8358f3 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/edit-an-event.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/event-calendar.png b/_docs/doc-update-detection/exploration-and-organization/images/event-calendar.png new file mode 100644 index 000000000..00659553c Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/event-calendar.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/event-on-a-time-series.png b/_docs/doc-update-detection/exploration-and-organization/images/event-on-a-time-series.png new file mode 100644 index 000000000..ba472e324 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/event-on-a-time-series.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/example-event.png b/_docs/doc-update-detection/exploration-and-organization/images/example-event.png new file mode 100644 index 000000000..440199cd8 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/example-event.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/move-to-trash.png b/_docs/doc-update-detection/exploration-and-organization/images/move-to-trash.png new file mode 100644 index 000000000..71f39c267 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/move-to-trash.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/official-collection.png b/_docs/doc-update-detection/exploration-and-organization/images/official-collection.png new file mode 100644 index 000000000..f882ac1e8 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/official-collection.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/our-analytics-page.png b/_docs/doc-update-detection/exploration-and-organization/images/our-analytics-page.png new file mode 100644 index 000000000..2be512d7e Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/our-analytics-page.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/pinned-items.png b/_docs/doc-update-detection/exploration-and-organization/images/pinned-items.png new file mode 100644 index 000000000..cb03f09de Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/pinned-items.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/pinned-show-viz.png b/_docs/doc-update-detection/exploration-and-organization/images/pinned-show-viz.png new file mode 100644 index 000000000..e6e06dfd6 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/pinned-show-viz.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/question-checkbox.png b/_docs/doc-update-detection/exploration-and-organization/images/question-checkbox.png new file mode 100644 index 000000000..ad9371b3a Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/question-checkbox.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/search-results.png b/_docs/doc-update-detection/exploration-and-organization/images/search-results.png new file mode 100644 index 000000000..b2efa426d Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/search-results.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/timeline-sidebar.png b/_docs/doc-update-detection/exploration-and-organization/images/timeline-sidebar.png new file mode 100644 index 000000000..cb96cd016 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/timeline-sidebar.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/trash.png b/_docs/doc-update-detection/exploration-and-organization/images/trash.png new file mode 100644 index 000000000..c7f581a8e Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/trash.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/verified-icon.png b/_docs/doc-update-detection/exploration-and-organization/images/verified-icon.png new file mode 100644 index 000000000..1b6ccf96f Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/verified-icon.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/verified-only.png b/_docs/doc-update-detection/exploration-and-organization/images/verified-only.png new file mode 100644 index 000000000..d07d696f8 Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/verified-only.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/verify-this-dashboard.png b/_docs/doc-update-detection/exploration-and-organization/images/verify-this-dashboard.png new file mode 100644 index 000000000..a1887a5df Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/verify-this-dashboard.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/images/x-ray-example.png b/_docs/doc-update-detection/exploration-and-organization/images/x-ray-example.png new file mode 100644 index 000000000..393680d0d Binary files /dev/null and b/_docs/doc-update-detection/exploration-and-organization/images/x-ray-example.png differ diff --git a/_docs/doc-update-detection/exploration-and-organization/start.md b/_docs/doc-update-detection/exploration-and-organization/start.md new file mode 100644 index 000000000..4f3e5ba41 --- /dev/null +++ b/_docs/doc-update-detection/exploration-and-organization/start.md @@ -0,0 +1,45 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: 'Exploration and Organization' +title: 'Organization overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/exploration-and-organization/start.md' +--- + +# Organization overview + +Tools for finding things and keeping your Metabase organized. + +## [Basic exploration](./exploration) + +Find data, explore questions and dashboards, and bookmark your favorites. + +## [Collections](./collections) + +Organize questions, dashboards, and models with collections. + +## [History](./history) + +View changes to a question, dashboard or model and revert to previous versions. + +## [Delete and restore items](./delete-and-restore) + +Move outdated outdated questions, models, and dashboards to trash, or delete them permanently. + +## [Data reference](./data-model-reference) + +Documentation that helps you understand your data sources: tables, columns, metrics, and more. + +## [Events and timelines](./events-and-timelines) + +Add events to timelines to annotate charts. + +## [X-ray your data](./x-rays) + +X-rays are a fast and easy way to get automatic insights and explorations of your data. + +## [Content verification](./content-verification) + +Admins can verify items to let people know the data is accurate and up to date. diff --git a/_docs/doc-update-detection/exploration-and-organization/uploads.md b/_docs/doc-update-detection/exploration-and-organization/uploads.md new file mode 100644 index 000000000..efbac0eb8 --- /dev/null +++ b/_docs/doc-update-detection/exploration-and-organization/uploads.md @@ -0,0 +1,53 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Exploration and Organization' +title: 'Uploading data' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/exploration-and-organization/uploads.md' +--- + +# Uploading data + +If an admin has [set up uploads](../databases/uploads), you can upload CSV data by clicking on the **Upload** icon in the top right of the collection page. + +![Upload CSV data](../databases/images/upload-icon.png). + +## Create, append, or replace models with uploads + +When you upload a CSV file, Metabase may ask to select a destination for that upload (depending on whether there are other uploads). + +If your CSV has the same columns as a model from a previously uploaded file, you can append data to that model. Otherwise, you can create a new [model](../data-modeling/models). if you want to: + +- Create a new model +- [Append to an existing model created by an upload](#appending-to-a-model-created-by-an-upload) +- [Replace the data for an existing model created by an upload](#replacing-the-data-of-an-uploaded-model) + +Metabase will create a [model](../data-modeling/models) that contains that CSV data, as well as the model's underlying table. + +Uploads will only be available if your admin has enabled uploads for your Metabase, and you're in a group with Unrestricted access to the schema used to store those uploads. See [Uploading data](../databases/uploads). + +## Appending to a model created by an upload + +You can upload additional CSV data to an existing model created by a previous CSV upload. + +![Append data to existing upload model](./images/append-data.png) + +The uploaded CSV must have the same column name, order, and type as the columns in the model. Metabase will look for a header row to check that the column names are the same. So if you split a large CSV into multiple CSVs, make sure to include header rows for all of the files. + +When appending, Metabase will simply insert the rows into the underlying table, which will update the model that sits on top of that table. If you have duplicate rows from one upload to the next, Metabase will preserve those duplicate rows. + +The upload icon will only be visible on models created by uploads. + +## Replacing the data of an uploaded model + +Instead of deleting a model and recreating it, you can replace the underlying data with an updated spreadsheet. + +Like appending to uploaded models, replacing the uploaded CSV data with a new CSV file requires the columns and headings to match. + +If you [delete the uploaded table](../databases/uploads#deleting-tables-created-by-uploads), you won't be able to replace the model's data. + +## Further reading + +- [Enabling uploads](../databases/uploads) diff --git a/_docs/doc-update-detection/exploration-and-organization/x-rays.md b/_docs/doc-update-detection/exploration-and-organization/x-rays.md new file mode 100644 index 000000000..6679af353 --- /dev/null +++ b/_docs/doc-update-detection/exploration-and-organization/x-rays.md @@ -0,0 +1,73 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Exploration and Organization' +title: X-rays +source_url: 'https://github.com/metabase/metabase/blob/master/docs/exploration-and-organization/x-rays.md' +redirect_from: + - /docs/doc-update-detection/users-guide/14-x-rays +--- + +# X-rays + +X-rays are a way to get automatic insights and explorations of your data. + +## Get automatic insights when clicking on a chart + +One great way to explore your data in general in Metabase is to click on points of interest in charts and selecting **Automatic insights**. + +![Automatic insights in the drill-through menu](./images/automatic-insights.png) + +Metabase will give you some options: + +- **X-ray** +- **Compare to the rest** + +In both cases, Metabase will take a look at the fields in that table or model, and automatically generate charts that summarize the data based on the data types it finds. + +Here's an example X-ray: + +![Example X-ray of the products table](./images/x-ray-example.png) + +## X-raying models and tables + +![Browse data X-ray](./images/browse-data-x-ray.png) + +Another great way to get to know your data is by X-raying your models and tables. + +- **Table X-rays**: From the left nav, click on **Browse Data**, pick a database, hover over a table card, and click the lightning bolt icon table to view an X-ray of the table. +- **Model X-rays**: Click on the ellipses for a model and select **X-ray this**. + +## X-rays in the data reference + +You can also view an X-ray by browsing to a table and clicking on the lightning bolt icon. Click on the **Browse Data** button in the top navigation, select a database, and hover over a table to see the icon. + +From the Browse Data page, you can also click on `Learn about our data` to view the Data Reference section. From here you can navigate through databases, tables, columns, metrics, or segments, and you can click on the X-ray link in the left sidebar to see an X-ray of the item you're currently viewing. + +![Data Reference X-ray](./images/data-reference.png) + +## Exploring newly added data sources + +If you're an administrator, when you first connect a database to Metabase, Metabot will offer to show you some automatic explorations of your newly connected data. + +## Browsing through suggested X-rays + +Depending on the X-ray you're currently viewing, you'll see suggestions that will let you: + +- **Zoom out**: view an X-ray of the table the current X-ray is based on. +- **Zoom in**: see a more detailed X-ray about a field or dimension of the current X-ray. +- **Related**: X-ray some related data, like a metric based on the current table, or a different table related to the current one. + +## Saving X-rays + +If you come across an X-ray that's particularly interesting, you can save its cards and filters as a dashboard by clicking the green **Save this** button. Metabase will create a new dashboard and save it to the Automatically generated dashboards collection (though you can move the dashboard to any collection you have curate access to). + +## Disabling X-rays + +If for some reason X-rays aren't a good fit for your team or your data, administrators can turn them off completely by clicking on the gear icon in the upper right and going to **Admin settings** > **Settings** > **General** and toggling the option to **Enable X-ray features**. + +If you pin any dashboards in the "Our Analytics" collection, Metabase will hide the X-ray suggestions that appear on the homepage. + +Admins can also manually remove these suggestions by clicking on the **Customize** button in the upper right and selecting a dashboard as your homepage. [Changing the home page](../configuring-metabase/settings#custom-homepage) won't disable the X-ray features in the rest of Metabase. diff --git a/_docs/doc-update-detection/images/metabase-logo.svg b/_docs/doc-update-detection/images/metabase-logo.svg new file mode 100644 index 000000000..c34b2a063 --- /dev/null +++ b/_docs/doc-update-detection/images/metabase-logo.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_docs/doc-update-detection/images/metabase-product-screenshot.png b/_docs/doc-update-detection/images/metabase-product-screenshot.png new file mode 100644 index 000000000..1d150efa0 Binary files /dev/null and b/_docs/doc-update-detection/images/metabase-product-screenshot.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/accessibility.md b/_docs/doc-update-detection/installation-and-operation/accessibility.md new file mode 100644 index 000000000..d92b171dd --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/accessibility.md @@ -0,0 +1,35 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Accessibility in Metabase' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/accessibility.md' +redirect_from: + - /docs/doc-update-detection/accessibility + - /docs/doc-update-detection/people-and-groups/accessibility +--- + +# Accessibility in Metabase + +While we're working to make a product that is easy to use and inclusive to all, we're not yet fully compliant with [the U.S. federal government's Section 508 standards](https://www.section508.gov/) or the [Web Content Accessibility Guidelines (WCAG) 2.1](https://www.w3.org/TR/WCAG21/) at Level AA. We expect to build on our current state in the future, and as of today these are some general notes on our state of compliance: + +- **Navigation and screen readers:** Most information is presented in a way to ensure it can be accessed by screen readers. Metabase lacks a mechanism to allow screen readers to bypass repetitive navigation elements efficiently. Many interactive elements, functionalities, tooltip content, non-modal dialogs and custom form controls are not operable for screen reader users. +- **Non-text content:** While Metabase provides text alternatives for most non-text elements, some functional images either lack descriptions or have incomplete alt text. +- **Keyboard navigation:** Most form elements are keyboard-accessible, but certain interactive components, such as custom controls and non-modal dialogs, may lack full keyboard operability. +- **Focus management:** In some cases, keyboard focus does not follow a logical order, and certain interactive elements lack a visible focus indicator. +- **Tables and data visualization:** Data tables do not consistently include programmatically defined row and column headers, impacting screen reader interpretation. +- **Motion and animations:** Metabase includes minimal transition animations. If the [prefers-reduced-motion CSS setting](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion#user_preferences) is enabled in the OS, Metabase disables animations. However, we have not yet conducted full testing to confirm that all animations meet the recommended flicker rate threshold (between 2 Hz and 55 Hz). +- **Language and labels:** Some form elements lack explicit labels, and primary language settings do not update programmatically when changed. +- **Assistive technology compatibility:** Metabase is a React-based web application, which means it requires JavaScript to function and may not be fully operable with all assistive technologies. +- **Error handling and form validation:** Some form fields do not provide clear error messages, and required fields are not always programmatically marked as mandatory. This may impact users relying on screen readers or other assistive technologies. +- **Contrast and visual accessibility:** While most UI elements meet contrast requirements, some text and interactive elements have insufficient color contrast, making them difficult to read for users with low vision or color blindness. +- **Resizing and responsive behavior:** Most content can be resized up to 200% without loss of information, but some elements do not reflow properly, potentially causing overlap or cutoff content when text spacing is adjusted. +- **Hover and tooltip behavior:** Some tooltips and additional information elements appear on hover but are not easily dismissible using a keyboard, which may present challenges for keyboard-only users and screen readers. +- **Status messages and notifications:** While some dynamically generated status messages are accessible, others are not consistently conveyed to assistive technologies like screen readers, which could make it difficult for users to receive important system feedback. +- **Consistent page titles and headings:** Some pages lack descriptive or unique titles, which may make navigation more challenging for screen reader users who rely on clear page identification. + +If you're interested in helping us address these gaps, check out [our developers' guide](../developers-guide/start). + +To request a copy of our VPAT, contact us at [help@metabase.com](mailto:help@metabase.com). diff --git a/_docs/doc-update-detection/installation-and-operation/activating-the-enterprise-edition.md b/_docs/doc-update-detection/installation-and-operation/activating-the-enterprise-edition.md new file mode 100644 index 000000000..6285e19f3 --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/activating-the-enterprise-edition.md @@ -0,0 +1,116 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Activating your Metabase commercial license' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/activating-the-enterprise-edition.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/activating-the-enterprise-edition + - /docs/doc-update-detection/paid-features/activating-the-enterprise-edition +--- + +# Activating your Metabase commercial license + +The [paid Pro and Enterprise editions](/pricing/) of Metabase are distinct from the free [Open Source edition](../installation-and-operation/running-the-metabase-jar-file) and the [Starter version of Metabase Cloud](/cloud/). + +## If you're running on Metabase Cloud + +If you've signed up for or upgraded to a Pro or Enterprise plan on Metabase Cloud, all of this will be taken care of for you. + +## If you're self-hosting Metabase + +To use your Pro/Enterprise features, you’ll need to do two things: + +- Download Metabase Enterprise Edition +- Enter your license. + +You can get a license by signing up for a free trial of the [Pro or Enterprise edition plans](/pricing/), both of which can be self-hosted or hosted on Metabase Cloud. + +### Download the Enterprise edition + +- [Enterprise Docker image](https://hub.docker.com/r/metabase/metabase-enterprise/) at `metabase/metabase-enterprise:latest`. (RECOMMENDED) +- [Enterprise JAR](https://downloads.metabase.com/enterprise/latest/metabase.jar). + +You'll also need to set up a dedicated [application database](../installation-and-operation/configuring-application-database) to store your Metabase data. + +### Activate your license + +There are two ways to activate your license when self-hosting Metabase: + +- **When Metabase is running**: go to **Settings** > **Admin settings**, and click **License and Billing** in the lefthand sidebar. Paste in your license token under **License** and click **Activate**. + +OR + +- **Before you start Metabase**: you can also set the license token with the [`MB_PREMIUM_EMBEDDING_TOKEN` environment variable](/docs/latest/configuring-metabase/environment-variables#mb_premium_embedding_token). This environment variable must be set _before_ you start your Metabase. + +## Upgrading from a self-hosted Metabase Open Source Edition to a Pro or Enterprise plan + +To get all the features available when upgrading to a _self-hosted_ [Pro or Enterprise plan](/pricing/), you'll need to: + +1. Change to the Metabase Enterprise Edition (that goes for both the Pro and Enterprise plans). +2. Activate your license. + +Assuming you've been using a [production application database](../installation-and-operation/configuring-application-database), you'll want to: + +1. [Back up your application database](./backing-up-metabase-application-data). +2. Download the Enterprise Edition version that corresponds with your current Metabase version. So if you're running the Docker image for {{site.data.latest_version}}, you should switch to the Docker image for {{site.data.latest_enterprise}}. To see a list of available versions for both the Open Source and Enterprise Editions, check out [Metabase releases](https://github.com/metabase/metabase/releases). +3. Stop your current Metabase Open Source edition. +4. Swap in the Enterprise Edition Docker image or jar that you downloaded. +5. Start your Metabase like you normally would using the new Enterprise Edition image or jar. You don't need to do anything with your application database (which you've backed up in step one, right?). +6. [Activate your license](#activate-your-license). You won't be able to use any of the new features until you've activated your license. + +Migrating to the Enterprise Edition will keep all of your questions, dashboards, people, settings — everything in your existing Metabase. + +And don't stress. You won't lose any of your work, and if you get stuck, we're [here to help](/help/premium). + +## Validating your token + +To validate your token and maintain access to Pro/Enterprise features, your Metabase needs to be able to access the Internet, specifically: + +``` +https://token-check.metabase.com/api/[token-id]/v2/status +``` + +(substituting `[token-id]` with your token ID). + +If your Metabase can't validate the token, it'll disable the Pro/Enterprise features, but will continue to work normally as if you were running the Open Source edition. + +If you can't expose your Metabase to the internet, talk to us about our [air-gapped Metabase](/product/air-gapping). + +## Routing outbound Metabase traffic through a proxy + +In case you need to route outbound Metabase traffic through a proxy on your network, use the following command when starting Metabase: + +``` +java -Dhttps.proxyHost=[your proxy's hostname or ip] -Dhttps.proxyPort=[your proxy's port] -jar metabase.jar +``` + +or if you're using containers, then you need to use the `JAVA_TOOL_OPTIONS` environment variable: + +``` +JAVA_TOOL_OPTIONS=-Dhttps.proxyHost=[your proxy's hostname or ip] -Dhttps.proxyPort=[your proxy's port] +``` + +Depending on your organization’s setup, you may need to take additional configuration steps. If the command above doesn't work for you, we recommend reaching out to your internal infrastructure or dev ops teams for assistance. + +## IP addresses to whitelist + +If you're hosting Metabase behind a firewall that blocks outgoing connections, **you must allow outbound stateful connections to port 443 on the all of the following IP addresses**: + +``` +23.23.111.13 +44.199.18.109 +44.212.138.188 +``` + +To verify your license with a token check to `token-check.metabase.com`, your Metabase will make GET HTTP requests to these IP addresses and parse their responses. If you can't allow outbound connections for security reasons, please [contact us](/help/premium). + +## Note about Zscaler deployments + +When Metabase is deployed inside infrastructure that uses Zscaler, you should do the following: + +1. Contact your networking team and let them know that Metabase will need to perform token checks in order for paid features to work. If you need an air-gapped version of Metabase, [contact us](/help/premium). +2. Make sure Zscaler isn't acting as a proxy or DNS for the server where Metabase is running. Metabase needs a direct connection to the token check service without any gateway acting as a proxy. +3. Make sure the server where Metabase is running isn't using Zscaler root CA certificates for all websites. Otherwise, the Java virtual machine where Metabase runs will determine that the certificate authority is incorrect. diff --git a/_docs/doc-update-detection/installation-and-operation/backing-up-metabase-application-data.md b/_docs/doc-update-detection/installation-and-operation/backing-up-metabase-application-data.md new file mode 100644 index 000000000..cbbcbd513 --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/backing-up-metabase-application-data.md @@ -0,0 +1,56 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Backing up Metabase' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/backing-up-metabase-application-data.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/backing-up-metabase-application-data +--- + +# Backing up Metabase + +Avoid losing your application data (all of your questions, dashboards, collections and so on) by backing up your data. + +Metabase uses a single SQL database for all of its runtime application data, so all you need to do is back up that database and you're good to go. You can use that backup to restore your Metabase installation if anything goes wrong (like during an upgrade). + +## Backing up the default H2 database + +If you didn't specify an application database using environment variables when you launched Metabase, Metabase will have created an embedded H2 database in its directory. + +But if you're at the point where you have questions and dashboards that you want to keep, you should consider migrating to a [production-ready database](migrating-from-h2) before you upgrade. + +If you're just using Metabase for personal use and want to keep your application data, here's what you'll need to do. + +### If you're running the Metabase Docker image + +If you're running Docker, you should already have switched to a [production-ready database](migrating-from-h2). + +Before migrating to a production application database, you should copy the H2 app db file out of the Docker container. For example, if the container is called metabase, you'd run: + +``` +docker cp metabase:/metabase.db/metabase.db.mv.db ./ +``` + +The above command would copy the database file to the directory you ran the command from. You can also create a copy of this H2 file and use it to migrate the data to a production-ready database. See [Migrating from H2](migrating-from-h2). + +### If you're running the Metabase JAR + +1. Navigate to your Metabase directory. +2. If your Metabase is running, stop the Metabase process. You can either close the terminal or kill the process with CTRL-C. If you are running the process as a service, then stop the service. +3. Copy the application database file (called `metabase.db.mv.db`) and keep that copy somewhere safe. That's it. +4. Restart Metabase: `java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar` or start the service again. + +## Amazon RDS for the application database + +Amazon has its own best practices on how to backup and restore RDS databases, so we'll defer to them. We recommend that you enable automated RDS Backups. + +Instructions can be found in the [Amazon RDS User Guide](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithAutomatedBackups.html). + +## Self-hosted PostgreSQL database + +If you're hosting your own PostgreSQL database, simply follow PostgreSQL's instructions for [backing up your database](https://www.postgresql.org/docs/current/backup.html). + +As long as you have a dump of the Metabase database, you should be good to go. diff --git a/_docs/doc-update-detection/installation-and-operation/commands.md b/_docs/doc-update-detection/installation-and-operation/commands.md new file mode 100644 index 000000000..84269f5e4 --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/commands.md @@ -0,0 +1,145 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Metabase CLI' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/commands.md' +--- + +# Metabase CLI + +Metabase ships with some handy CLI commands. To view a list of commands, run the Metabase jar followed by `help`. + +``` +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar help +``` + +Metabase will print out the help text for available commands. + +## `api-documentation` + +Generate a markdown file containing documentation for all API endpoints. This is written to a file called `docs/api.html`. + +## `driver-methods` | `driver-methods _docs` + +Print a list of all multimethods available for a driver to implement. Add `_docs` to include their docstrings. + +## `config-template` + +Generates a Markdown file with documentation and an example configuration file in YAML. The YAML template includes Metabase settings and their defaults. Metabase will save the file as `docs/configuring-metabase/config-template.md`. + +## `drop-entity-ids` + +Drop Entity IDs for instances of serializable models. Useful for migrating from v1 serialization (x.46 and earlier) to v2 (x.47+). + +## `dump path & options` + +**Note: this command is deprecated. Use `export` instead.** + +Serializes Metabase instance into directory `path`. + +Options: + +- `-u, --user EMAIL` - Export collections owned by the specified user +- `-s, --state (active|all)` - When set to `active`, do not dump archived entities. Default behavior is `all` +- `--include-entity-id` - Include entity_id property in all dumped entities. Default: false + +## `dump-to-h2 h2-filename & opts` + +Transfer data from existing database to newly created H2 DB with specified filename. Target H2 file is deleted before dump, unless the --keep-existing flag is given. + +Options: + +- `-k, --keep-existing` - Do not delete target H2 file if it exists +- `-p, --dump-plaintext` - Do not encrypt dumped contents + +## `environment-variables-documentation` + +Generates a markdown file containing documentation for environment variables relevant to configuring Metabase. The command only includes environment variables registered as defsettings. For a full list of environment variables, see https://www.metabase.com/docs/latest/configuring-metabase/environment-variables. + +## `export path & options` + +{% include plans-blockquote.html feature="Serialization" self-hosted-only="true" %} + +Serialize Metabase instance into directory at `path`. + +Options: + +- `-c, --collection ID` - Export only specified ID(s). Use commas to separate multiple IDs. You can pass Entity IDs with `eid:<...>` as a prefix +- `-C, --no-collections` - Do not export any content in collections +- `-S, --no-settings` - Do not export settings.yaml +- `-D, --no-data-model` - Do not export any data model entities; useful for subsequent exports +- `-f, --include-field-values` - Include field values along with field metadata +- `-s, --include-database-secrets` - Include database connection details (in plain text; use caution) +- `-e, --continue-on-error` - Do not break execution on errors +- `--full-stacktrace` - Output full stacktraces on errors + +## `help command-name` | `help` + +Show this help message listing valid Metabase commands. Use `help command-name` for specific command details. + +## `import path & options` + +{% include plans-blockquote.html feature="Serialization" self-hosted-only="true" %} + +Load serialized Metabase instance as created by the `export` command from directory `path`. + +Options: + +- `-e, --continue-on-error` - Do not break execution on errors +- `--full-stacktrace` - Output full stacktraces on errors + +## `load path & options` + +**Note: this command is deprecated. Use `import` instead.** + +Load serialized Metabase instance as created by `dump` command from directory `path`. + +Options: + +- `-m, --mode (skip|update)` - Update or skip on conflicts. Default: skip +- `-e, --on-error (continue|abort)` - Abort or continue on error. Default: continue + +## `load-from-h2` | `load-from-h2 h2-connection-string` + +Transfer data from existing H2 database to the newly created MySQL or Postgres DB specified by env vars. + +## `migrate direction` + +Run database migrations. Valid options for `direction` are `up`, `force`, `down`, `print`, or `release-locks`. + +## `profile` + +Start Metabase the usual way and exit. Useful for profiling Metabase launch time. + +## `reset-password email-address` + +Reset the password for a user with `email-address`. + +## `rotate-encryption-key new-key` + +Rotate the encryption key of a metabase database. The MB_ENCRYPTION_SECRET_KEY environment variable has to be set to the current key, and the parameter `new-key` has to be the new key. `new-key` has to be at least 16 chars. + +## `remove-encryption` + +Decrypts data in the metabase database. The MB_ENCRYPTION_SECRET_KEY environment variable has to be set to the current key. + +## `seed-entity-ids` + +Add Entity IDs for instances of serializable models that don't already have them. + +## `version` + +Print version information about Metabase and the current system. + +## Additional useful commands + +### H2 SQL Shell + +Open an SQL shell for the Metabase H2 DB: + +```sh +java -cp metabase.jar org.h2.tools.Shell -url jdbc:h2:/path/to/metabase.db +``` diff --git a/_docs/doc-update-detection/installation-and-operation/configuring-application-database.md b/_docs/doc-update-detection/installation-and-operation/configuring-application-database.md new file mode 100644 index 000000000..431ee84fd --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/configuring-application-database.md @@ -0,0 +1,184 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Configuring the Metabase application database' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/configuring-application-database.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/configuring-application-database +--- + +# Configuring the Metabase application database + +The application database is where Metabase stores information about user accounts, questions, dashboards, and any other data needed to run the Metabase application. This app DB is distinct from the database where you store your data, also known as your data warehouse. For connecting to your data warehouse, see [Connecting to a supported database](../databases/connecting). + +For production, we recommend using PostgreSQL as your Metabase application database. + +- [PostgreSQL](#postgresql) (recommended for production) +- [MySQL or MariaDB](#mysql-or-mariadb) (also works for production) +- [H2](#h2-application-database) (default for local demos - AVOID in production) + +Metabase will read the connection configuration information when the application starts up. You can't change the application database while the application is running. + +## PostgreSQL + +We recommend that you use [PostgreSQL](https://www.postgresql.org/) for your Metabase application database. Metabase supports the oldest supported version of PostgreSQL through the latest stable version. See [PostgreSQL versions](https://www.postgresql.org/support/versioning/). + +You can use [environment variables](../configuring-metabase/environment-variables) to set a Postgres database as Metabase's application database. For example, the following commands tell Metabase to use a Postgres database as its application database: + +```sh +export MB_DB_TYPE=postgres +export MB_DB_DBNAME=metabase +export MB_DB_PORT=5432 +export MB_DB_USER= +export MB_DB_PASS= +export MB_DB_HOST=localhost +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +Metabase will not create a Postgres database for you. Example command to create the database: + +```sh +createdb --encoding=UTF8 -e metabase +``` + +If you have additional parameters, Metabase also supports providing a full JDBC connection string: + +```sh +export MB_DB_CONNECTION_URI="jdbc:postgresql://localhost:5432/metabase?user=&password=" +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +If you want to pass the connection URI, user, and password credentials separately from the JDBC connection string (useful if the password contains special characters), you can use the `MB_DB_CONNECTION_URI` [environment variable](../configuring-metabase/environment-variables) in combination with `MB_DB_USER` and `MB_DB_PASS` variables: + +```sh +export MB_DB_CONNECTION_URI="jdbc:postgresql://localhost:5432/metabase" +export MB_DB_USER= +export MB_DB_PASS= +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +## MySQL or MariaDB + +We recommend [PostgreSQL](#postgresql), but you can also use [MySQL](https://www.mysql.com/) or [MariaDB](https://www.mariadb.org/). + +The minimum recommended version is MySQL 8.0.17 or MariaDB 10.2.2. The `utf8mb4` character set is required. + +We don't support ApsaraDB MySQL. You can instead use ApsaraDB PostgreSQL. + +You can change the application database to use MySQL using environment variables like so: + +```sh +export MB_DB_TYPE=mysql +export MB_DB_DBNAME=metabase +export MB_DB_PORT=3306 +export MB_DB_USER= +export MB_DB_PASS= +export MB_DB_HOST=localhost +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +Metabase won't create this database for you. Example SQL statement to create the database: + +```sh +CREATE DATABASE metabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +``` + +The following command will tell Metabase to look for its application database using the supplied MySQL connection information. Metabase also supports providing a full JDBC connection string if you have additional parameters: + +```sh +export MB_DB_CONNECTION_URI="jdbc:mysql://localhost:3306/metabase?user=&password=" +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +As with Postgres, `MB_DB_CONNECTION_URI` can also be used in combination with `MB_DB_USER` and/or `MB_DB_PASS` if you +want to pass one or both separately from the rest of the JDBC connection string: + +```sh +export MB_DB_CONNECTION_URI="jdbc:mysql://localhost:5432/metabase" +export MB_DB_USER= +export MB_DB_PASS= +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +## H2 application database + +> **For production installations of Metabase we recommend that people [replace the default H2 database with PostgreSQL](./migrating-from-h2)**. Postgres offers a greater degree of performance and reliability. + +By default, Metabase ships with an [H2 database](https://www.h2database.com/) to make it easy to demo Metabase on your local machine. **Avoid using this default database in production**. + +If when launching Metabase you don't provide environment variables that specify connection details for a production database, Metabase will attempt to create a new H2 database in the same directory as the Metabase JAR. + +H2 is a file-based database, and you can see these H2 database files from the terminal: + +```sh +ls metabase.* +``` + +You should see the following files: + +```sh +metabase.db.h2.db # Or metabase.db.mv.db depending on when you first started using Metabase. +metabase.db.trace.db +``` + +If you want to use an H2 database file in a particular directory, use the `MB_DB_TYPE` and `MB_DB_FILE` environment variables: + +```sh +export MB_DB_TYPE=h2 +export MB_DB_FILE=/the/path/to/my/h2.db +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +Note that H2 automatically appends `.mv.db` or `.h2.db` to the path you specify; exclude those extensions in your path! In other words, `MB_DB_FILE` should be something like `/path/to/metabase.db`, rather than something like `/path/to/metabase.db.mv.db` (even though the latter is the file that Metabase will create). + +## Migrating from H2 + +If you've started out using the default, H2 database, but you want to preserve the content you've created and move to a production application database, Metabase provides limited support for [migrating from H2 to PostgreSQL](migrating-from-h2). + +## Upgrading from a Metabase version pre-0.38 + +If you’re upgrading from a previous version of Metabase, note that for Metabase 0.38 we've removed the use of the PostgreSQL `NonValidatingFactory` for SSL validation. It’s possible that you could experience a failure either at startup (if you're using a PostgreSQL application database) or when querying a PostgreSQL data warehouse. + +You can resolve this failure in one of two ways: + +1. Configuring the PostgreSQL connection to use SSL certificate validation, +2. Or manually enabling the `NonValidatingFactory`. WARNING: this method is insecure. We're including it here only to assist in troubleshooting, or for situations in which security is not a priority. + +How you configure your connection depends on whether you're using Postgres as Metabase's application database or as a data warehouse connected to Metabase: + +### SSL certificate validation for Postgres _application_ databases + +To use SSL certificate validation, you'll need to use the `MB_DB_CONNECTION_URI` environment variable to configure your database connection. Here's an example: + +```sh +export MB_DB_CONNECTION_URI="postgres://localhost:5432/metabase?user=&password=&sslmode=verify-ca&sslrootcert=" +``` + +If you can't enable certificate validation, you can enable the `NonValidatingFactory` for your application database: + +```sh +export MB_DB_CONNECTION_URI="postgres://localhost:5432/metabase?user=&password=&ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory" +``` + +### SSL certificate validation for Postgres _data warehouse_ databases + +Add the following to the end of your JDBC connection string for your database: + +```sh +&sslmode=verify-ca&sslrootcert= +``` + +If that fails, you can enable `NonValidatingFactory` by adding the following to the end of your connection URI for your database: + +```sh +&ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory +``` + +For more options to further tune the SSL connection parameters, see the [PostgreSQL SSL client documentation](https://jdbc.postgresql.org/documentation/ssl/#configuring-the-client). + +## Further reading + +- [Environment variables](../configuring-metabase/environment-variables) diff --git a/_docs/doc-update-detection/installation-and-operation/creating-RDS-database-on-AWS.md b/_docs/doc-update-detection/installation-and-operation/creating-RDS-database-on-AWS.md new file mode 100644 index 000000000..165c13cc7 --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/creating-RDS-database-on-AWS.md @@ -0,0 +1,82 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Creating an RDS database on AWS' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/creating-RDS-database-on-AWS.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/creating-RDS-database-on-AWS +--- + +# Creating an RDS database on AWS + +If you want to move from using Metabase just for testing to something that is ready for the big time, you should use PostgreSQL for your application database. Here's a high-level view of Metabase deployed with a dedicated application database. + +![high level architecture diagram](images/Metabase-AWS-SI.png) + +## Create a database + +In AWS, enter RDS in the search box or select RDS from the dropdown button on the top left of the page. Once inside RDS, click on the **Create database** button. + +Select PostgreSQL as the engine type. We'll choose the latest version available in AWS at the time of writing (12.4-R1). + +Templates: you can leave "Production" selected, or choose any other option that better suits your needs. + +Settings: type a unique **DB instance identifier** for your database. You'll need the username and master password to configure the environment variables in Metabase. + +![RDS Templates Section](images/RDSPostgresSettings.png) + +Instance size: the sizing of the RDS instance depends on the number of Metabase instances that will be connected to this database, the number of simultaneous users who are using Metabase, and the number of questions, dashboards, and configurations that are saved. To start, a `t3.small` is a good choice. + +![RDS Instance size](images/RDSInstanceSize.png) + +Availability & Durability: on production deployments, you **should** be using a Multi-AZ (Availability Zone) cluster, as this will ensure that the database does not goes down in case there is an issue on a single availability zone. + +![RDS MultiAZ](images/RDSMultiAZ.png) + +Connectivity: + +- Ensure that you are deploying the database in the same VPC as the one you deployed the Metabase instance/s, otherwise they won't be able to see each other. +- Create a **VPC security group**, as you will need to grant access from the Metabase instance/s to the database on the port that listens for connections. + ![RDS VPC Security Groups](images/RDSVPCSecurityGroup.png) + +Additional configuration: + +- Enter `metabase` as the **Initial database name**. Metabase will use this database for all of its configurations. +- You can also configure the backup window in case you need to restore the backups at some point in time. + +![RDS Initial Database](images/RDSInitialDatabase.png) + +When you've completed all these configurations, click on the **Create database** button on the lower right part of the page and wait for the database to be created (which can take several minutes). + +## Set up security + +Once the database status is `Available`, you need to click on the DB identifier: + +![RDS DB Identifier](images/RDSDBIdentifier.png) + +On the page that appears after you click on the database identifer, you will see on the center of the page the **Connectivity & Security** section. This section will provide you with the **Endpoint** that Metabase needs to connect to the application database we just created. + +![RDS Connection Data](images/RDSConnectionData.png) + +In the **Security group rules** section, you'll see the Security Group that was created, but the group will have a rule that allows only one IP address to access the database. + +![RDS Security Group Rules](images/RDSSecurityGroupRules.png) + +To configure the rule for the database, select the **CIDR/IP - Inbound** rule, then click on the **Inbound rules** tab on the lower part of the page. + +![RDS Security Group Rules](images/RDSInboundRule.png) + +When you click on Inbound Rules, you need to click on **Edit Inbound Rules** button that appears on the right side of the section. + +![RDS Edit Inbound Rule](images/RDSEditInboundRule.png) + +On the edit page, you need to delete the IP address that appears as default, then add the security group for the server you're running Metabase on (the Security group name will have the keyword AWSEBSecurityGroup in its name). Once you add this security group, click the **Save rules** button. + +![RDS Edit Inbound Rule](images/RDSEditInboundRuleSG.png) + +## Add the RDS instance as the application database with environment variables + +After having finished all the previous steps, go to the your Metabase deployment and add the RDS instance as the Application Database with [Environment variables](../configuring-metabase/environment-variables). diff --git a/_docs/doc-update-detection/installation-and-operation/images/AZDatabase.png b/_docs/doc-update-detection/installation-and-operation/images/AZDatabase.png new file mode 100644 index 000000000..b2383ac3f Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/AZDatabase.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/AZMarketPlaceVnet.png b/_docs/doc-update-detection/installation-and-operation/images/AZMarketPlaceVnet.png new file mode 100644 index 000000000..9fe107d43 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/AZMarketPlaceVnet.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/AZMarketplaceWebApp.png b/_docs/doc-update-detection/installation-and-operation/images/AZMarketplaceWebApp.png new file mode 100644 index 000000000..ead574eec Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/AZMarketplaceWebApp.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/AZNetworks.png b/_docs/doc-update-detection/installation-and-operation/images/AZNetworks.png new file mode 100644 index 000000000..00b9cc802 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/AZNetworks.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/AZPostgreSQLMain.png b/_docs/doc-update-detection/installation-and-operation/images/AZPostgreSQLMain.png new file mode 100644 index 000000000..fecc71c27 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/AZPostgreSQLMain.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/AZPrivateLink.png b/_docs/doc-update-detection/installation-and-operation/images/AZPrivateLink.png new file mode 100644 index 000000000..0bc61a67f Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/AZPrivateLink.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/AZResource_group_Add.png b/_docs/doc-update-detection/installation-and-operation/images/AZResource_group_Add.png new file mode 100644 index 000000000..eaff1c643 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/AZResource_group_Add.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/AZVNETPublicSubnet.png b/_docs/doc-update-detection/installation-and-operation/images/AZVNETPublicSubnet.png new file mode 100644 index 000000000..44894a4dd Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/AZVNETPublicSubnet.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/AZVNETintegration.png b/_docs/doc-update-detection/installation-and-operation/images/AZVNETintegration.png new file mode 100644 index 000000000..6479865c8 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/AZVNETintegration.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/AZVnet.png b/_docs/doc-update-detection/installation-and-operation/images/AZVnet.png new file mode 100644 index 000000000..6aebb71ca Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/AZVnet.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/AddRemoteHost.png b/_docs/doc-update-detection/installation-and-operation/images/AddRemoteHost.png new file mode 100644 index 000000000..3d03da05e Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/AddRemoteHost.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/ClickAddJMXHost.png b/_docs/doc-update-detection/installation-and-operation/images/ClickAddJMXHost.png new file mode 100644 index 000000000..7c2786386 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/ClickAddJMXHost.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/EBDatabaseEndpoint.png b/_docs/doc-update-detection/installation-and-operation/images/EBDatabaseEndpoint.png new file mode 100644 index 000000000..231a2313d Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/EBDatabaseEndpoint.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/EBTerminateEnvironment.png b/_docs/doc-update-detection/installation-and-operation/images/EBTerminateEnvironment.png new file mode 100644 index 000000000..5d6655afe Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/EBTerminateEnvironment.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/EnterJMXPort.png b/_docs/doc-update-detection/installation-and-operation/images/EnterJMXPort.png new file mode 100644 index 000000000..7fbf02add Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/EnterJMXPort.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/HeapDump.png b/_docs/doc-update-detection/installation-and-operation/images/HeapDump.png new file mode 100644 index 000000000..0fa623ed6 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/HeapDump.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/LocalProcessVisualVM.png b/_docs/doc-update-detection/installation-and-operation/images/LocalProcessVisualVM.png new file mode 100644 index 000000000..f2bee0d07 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/LocalProcessVisualVM.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/Metabase-AWS-SI.png b/_docs/doc-update-detection/installation-and-operation/images/Metabase-AWS-SI.png new file mode 100644 index 000000000..94faf3ba6 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/Metabase-AWS-SI.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/OpenRemoteInstance.png b/_docs/doc-update-detection/installation-and-operation/images/OpenRemoteInstance.png new file mode 100644 index 000000000..a35bccaa8 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/OpenRemoteInstance.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSConnectionData.png b/_docs/doc-update-detection/installation-and-operation/images/RDSConnectionData.png new file mode 100644 index 000000000..9c94871b3 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSConnectionData.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSDBIdentifier.png b/_docs/doc-update-detection/installation-and-operation/images/RDSDBIdentifier.png new file mode 100644 index 000000000..bf9886e6f Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSDBIdentifier.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRule.png b/_docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRule.png new file mode 100644 index 000000000..e53f86468 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRule.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRuleSG.png b/_docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRuleSG.png new file mode 100644 index 000000000..a4956deaa Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRuleSG.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSInboundRule.png b/_docs/doc-update-detection/installation-and-operation/images/RDSInboundRule.png new file mode 100644 index 000000000..3b0516c43 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSInboundRule.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSInitialDatabase.png b/_docs/doc-update-detection/installation-and-operation/images/RDSInitialDatabase.png new file mode 100644 index 000000000..98384786d Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSInitialDatabase.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSInstanceSize.png b/_docs/doc-update-detection/installation-and-operation/images/RDSInstanceSize.png new file mode 100644 index 000000000..d924d2355 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSInstanceSize.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSMultiAZ.png b/_docs/doc-update-detection/installation-and-operation/images/RDSMultiAZ.png new file mode 100644 index 000000000..88f5775a9 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSMultiAZ.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSPostgresSettings.png b/_docs/doc-update-detection/installation-and-operation/images/RDSPostgresSettings.png new file mode 100644 index 000000000..35b346e1e Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSPostgresSettings.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSSecurityGroupRules.png b/_docs/doc-update-detection/installation-and-operation/images/RDSSecurityGroupRules.png new file mode 100644 index 000000000..55ecc7f1d Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSSecurityGroupRules.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSSnapshotsMenu.png b/_docs/doc-update-detection/installation-and-operation/images/RDSSnapshotsMenu.png new file mode 100644 index 000000000..262dc05e2 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSSnapshotsMenu.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSTakeSnapshot.png b/_docs/doc-update-detection/installation-and-operation/images/RDSTakeSnapshot.png new file mode 100644 index 000000000..03e61b343 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSTakeSnapshot.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/RDSVPCSecurityGroup.png b/_docs/doc-update-detection/installation-and-operation/images/RDSVPCSecurityGroup.png new file mode 100644 index 000000000..3326f4f57 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/RDSVPCSecurityGroup.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/SetRemoteHostName.png b/_docs/doc-update-detection/installation-and-operation/images/SetRemoteHostName.png new file mode 100644 index 000000000..82b43dacb Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/SetRemoteHostName.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/ThreadDump.png b/_docs/doc-update-detection/installation-and-operation/images/ThreadDump.png new file mode 100644 index 000000000..f88a97ac6 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/ThreadDump.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/images/prometheus.png b/_docs/doc-update-detection/installation-and-operation/images/prometheus.png new file mode 100644 index 000000000..6c511afd2 Binary files /dev/null and b/_docs/doc-update-detection/installation-and-operation/images/prometheus.png differ diff --git a/_docs/doc-update-detection/installation-and-operation/information-collection.md b/_docs/doc-update-detection/installation-and-operation/information-collection.md new file mode 100644 index 000000000..0c10c005a --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/information-collection.md @@ -0,0 +1,52 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'About the anonymous usage data we collect' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/information-collection.md' +redirect_from: + - /docs/doc-update-detection/information-collection +--- + +# About the anonymous usage data we collect + +If you're self-hosting Metabase and you've opted in to provide us with anonymous usage data (thank you!), Metabase will phone home some data collected via Snowplow. + +**[We only collect anonymous Metabase data; we don't collect any of your data](/security).** We don't collect any usernames, emails, server IPs, database details of any kind, or any personally identifiable information (PII). + +This anonymous data helps us understand how people are actually using Metabase, which in turn helps us prioritize what to work on next. + +## Examples of the anonymous data we collect and how we use it + +In a nutshell: we track some basic events to find opportunities for improving the product and evaluating project outcomes. We _don't_ use the data for sales or advertising (and the data's anonymous, so we couldn't use it for that anyway). + +We collect things like: + +- Events in the product (for example, when people create models) +- Some performance data +- The number and types of DBs you've connected to your Metabase +- The number of questions and dashboards and other items you've created + +This anonymous data helps us figure out things like: + +- Which features you're using +- Where people get stuck +- How performance for key workflows (like querying or loading) changes over time + +## Opting out of anonymous usage data collection for self-hosted Metabases + +If you're self-hosting Metabase, you can opt out of providing us with your anonymous usage data: + +1. Click on the gear icon. +2. Select **Admin settings**. +3. Go to the **Settings** tab. +4. Click **General** +5. Toggle the **Anonymous tracking** option. + +If you're in the process of setting up your Metabase, you can also toggle off tracking during the `Usage Data Preferences` onboarding step. We collect a few anonymous events before that point, but won't do so anymore if you choose to opt out. + +## Further reading + +Check out our page on [data privacy and security](/security). diff --git a/_docs/doc-update-detection/installation-and-operation/installing-metabase.md b/_docs/doc-update-detection/installation-and-operation/installing-metabase.md new file mode 100644 index 000000000..fbee469ca --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/installing-metabase.md @@ -0,0 +1,64 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Installing Metabase' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/installing-metabase.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/installing-metabase +--- + +# Installing Metabase + +Metabase is built and packaged as a Java JAR file and can be run anywhere that Java is available. + +## Metabase Cloud (Recommended) + +[Metabase Cloud](/cloud/) is the easiest way to run Metabase. All you need to do is [sign up for a free trial](https://store.metabase.com/checkout), and you're off to the races. + +## Self-hosting Metabase + +For an overview on how to self-host Metabase, check out [how to run Metabase in production](/learn/metabase-basics/administration/administration-and-operation/metabase-in-production). + +### Running on Docker (Recommended for self-hosting) + +Run Metabase in a [Docker container](./running-metabase-on-docker). + +### Running the Jar file + +If you're self-hosting but don’t use Docker, the JAR is the easiest way to get started, but it might make it more challenging to move to production. See [running the Metabase Jar](./running-the-metabase-jar-file). + +## Air-gapped Metabase + +If you're self-hosting because you need an air-gapped environment, check out the [air-gapped edition of Metabase](/product/air-gapping). + +## Professional services from the Metabase team + +If you want help with: + +- Set up +- Training +- Data stack +- Embedding +- Data modeling + +Check out our [professional services](/product/professional-services). + +## Upgrading Metabase + +See [Upgrading Metabase](upgrading-metabase). + +## Other installation options + +- [Running on Podman](running-metabase-on-podman) +- [Building Metabase from source](../developers-guide/start) +- [Running on Azure Web Apps](running-metabase-on-azure) +- [Running on Debian as a service](running-metabase-on-debian) + +We currently do not distribute Metabase on AWS Marketplace or Azure Marketplace. + +## Connect with a Metabase Expert + +If you’d like more technical resources to set up your data stack with Metabase, connect with a [Metabase Expert](/partners/). diff --git a/_docs/doc-update-detection/installation-and-operation/migrating-from-h2.md b/_docs/doc-update-detection/installation-and-operation/migrating-from-h2.md new file mode 100644 index 000000000..ffea0b381 --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/migrating-from-h2.md @@ -0,0 +1,209 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Migrating to a production application database' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/migrating-from-h2.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/migrating-from-h2 + - /docs/doc-update-detection/operations-guide/running-migrations-manually +--- + +# Migrating to a production application database + +This page covers how to convert a Metabase that's been using the built-in application database, H2, to a production-ready instance PostgreSQL. For more on why you should use Postgres as your app DB, check out [How to run Metabase in production](/learn/metabase-basics/administration/administration-and-operation/metabase-in-production). + +If you'd rather move to Metabase Cloud, check out [Migrate to Metabase Cloud](/docs/latest/cloud/migrate/guide). + +## Metabase's application database + +The main difference between a local installation and a production installation of Metabase is the application database. This application database keeps track of all of your Metabase data: your questions, dashboards, collections, and so on. + +Metabase ships with an embedded H2 application database that you should avoid using in production. The reason Metabase ships with the H2 database is because we want people to spin up Metabase on their local machine and start playing around with asking questions. + +If you want to run Metabase in production, you'll need to use a production-ready application database to store your application data. You can switch from using the default H2 application database at any time, but if you're planning on running Metabase in production, the sooner you migrate to a production application database, the better. If you keeping running Metabase with the default H2 application database, and you don't regularly back it up, the application database could get corrupted, and you could end up losing all of your questions, dashboards, collections, and other Metabase data. + +The migration process is a one-off process. You can execute the migration script from any computer that has the H2 application database file. + +### Avoid migrating and upgrading at the same time + +One important thing here is that the version of Metabase you use during the migration process must be the same. Meaning, the Metabase you use to run the migration command must be the same one that was last used to create or update H2 file, which must be the same version you'll be using in production. Only _after_ completing the migration should you consider upgrading. + +You could also choose to run Metabase on a [Metabase Cloud](/pricing/) plan, which takes care of all of this stuff for you. If you have an existing Metabase, here's how you can [migrate to Metabase Cloud](/cloud/docs/migrate/guide). + +## Supported databases for storing your Metabase application data + +We recommend using PostgreSQL for your application database. + +- [PostgreSQL](https://www.postgresql.org/). Minimum version: `12`. Postgres is our preferred choice for Metabase's application database. +- [MySQL](https://www.mysql.com/). Minimum version: `8.0.17`. Required settings (which are the default): `utf8mb4_unicode_ci` collation, `utf8mb4` character set, and `innodb_large_prefix=ON`. +- [MariaDB](https://mariadb.org/). Minimum version: `10.4.0`. Required settings (which are the default): `utf8mb4_unicode_ci` collation, `utf8mb4` character set, and `innodb_large_prefix=ON`. + +## JAR: How to migrate from H2 to your production application database + +> You must use the same version of Metabase throughout the migration process. + +Metabase provides a custom migration command for migrating to a new application database. Here's what you'll do: + +- [1. Confirm that you can connect to your target application database](#1-confirm-that-you-can-connect-to-your-target-application-database) +- [2. Shut down your Metabase instance](#2-shut-down-your-metabase-instance) +- [3. Back up your H2 application database](#3-back-up-your-h2-application-database) +- [4. Run the Metabase data migration command](#4-run-the-metabase-data-migration-command) +- [5. Start your Metabase](#5-start-your-metabase) + +### 1. Confirm that you can connect to your target application database + +You must be able to connect to the target application database in whatever environment you're running this migration command in. So, if you're attempting to move the data to a cloud database, make sure you can connect to that database. + +### 2. Shut down your Metabase instance + +You don't want people creating new stuff in your Metabase while you're migrating. Ideally, if you're running the Metabase JAR in production, you're [running Metabase as a service](./running-metabase-on-debian). + +### 3. Back up your H2 application database + +Safety first! See [Backing up Metabase Application Data](backing-up-metabase-application-data). + +### 4. Run the Metabase data migration command + +Run the migration command, `load-from-h2`, using the appropriate [environment variables](../configuring-metabase/environment-variables) for the target database you want to migrate to. + +You can find details about specifying databases at [Configuring the application database](configuring-application-database). + +Here's an example command for migrating to a Postgres database: + +``` +export MB_DB_TYPE=postgres +export MB_DB_CONNECTION_URI="jdbc:postgresql://:5432/metabase?user=&password=" +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar load-from-h2 /path/to/metabase.db # do not include .mv.db +``` + +Here's an example command for migrating to a MySQL database using Java parameter instead of environment variables: + +``` +java -DMB_DB_TYPE=mysql -DMB_DB_CONNECTION_URI="jdbc:mysql://:3306/metabase?user=&password=" -jar metabase.jar load-from-h2 metabase.db +``` + +Note that the file name of the database file itself might be `/path/to/metabase.db.mv.db`, but when running the `load-from-h2` command, you need to truncate the path to `/path/to/metabase.db`. + +Metabase expects that you'll run the command against a brand-new (empty) database; it'll create the database schema and migrate the data for you. + +### 5. Start your Metabase + +Start your Metabase (with the db connection info, but without the `load-from-h2` and H2 file migration command), and you should be good to go. For example, if you're using Postgres, your command to start Metabase would look something like: + +``` +export MB_DB_TYPE=postgres +export MB_DB_CONNECTION_URI="jdbc:postgresql://:5432/metabase?user=&password=" +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +You should, however, keep your old H2 file just for safe-keeping, or as a heirloom, or talisman, or whatever. + +## Docker: how to migrate from H2 to your production application database + +> You must use the same version of Metabase throughout the migration process. + +Metabase provides a custom migration command for migrating to a new application database. Here's what you'll do: + +- [1. Confirm that you can connect to your target application database](#1-confirm-that-you-can-connect-to-your-target-application-database-1) +- [2. Back up your H2 application database](#2-back-up-your-h2-application-database) +- [3. Stop the existing Metabase container](#3-stop-the-existing-metabase-container) +- [3. Download the JAR](#3-download-the-jar) +- [4. Run the migration command](#4-run-the-migration-command) +- [5. Start a new Docker container that uses the new app db](#5-start-a-new-docker-container-that-uses-the-new-app-db) +- [7. Remove the old container that was using the H2 database](#7-remove-the-old-container-that-was-using-the-h2-database) + +### 1. Confirm that you can connect to your target application database + +You must be able to connect to the target application database in whatever environment you're running this migration command in. So, if you're attempting to move the data to a cloud database, make sure you can connect to that database. + +### 2. Back up your H2 application database + +Safety first! See [Backing up Metabase Application Data](backing-up-metabase-application-data). + +If you don't back up your H2 database, and you replace or delete your container, you'll lose all of your questions, dashboards, and other Metabase data, so be sure to back up before you migrate. + +### 3. Stop the existing Metabase container + +You don't want people creating new stuff in your Metabase while you're migrating. + +### 3. Download the JAR + +In the directory where you saved your H2 file (that is, outside the container), [download the JAR](https://github.com/metabase/metabase/releases) for your current version. + +Make sure you use the same version of Metabase you've been using. If you want to upgrade, perform the upgrade after you've confirmed the migration is successful. + +### 4. Run the migration command + +Create another copy of your H2 file that you extracted from the container when you backed up your app db (step 2). + +From the directory with your H2 file and your Metabase JAR, run the migration command, `load-from-h2`. Use the appropriate connection string or [environment variables](../configuring-metabase/environment-variables) for the target database you want to migrate to. The command would look something like: + +``` +export MB_DB_TYPE=postgres +export MB_DB_CONNECTION_URI="jdbc:postgresql://:5432/metabase?user=&password=" +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar load-from-h2 /path/to/metabase.db # do not include .mv.db +``` + +Metabase will start up, perform the migration (meaning, it'll take the data from the H2 file and put it into your new app db, in this a Postgres db), and then exit. + +See [Configuring the application database](configuring-application-database). + +### 5. Start a new Docker container that uses the new app db + +With your new application database populated with your Metabase data, you can start a new container and tell the Metabase in the container to connect to the appdb. The command will looks something like this: + +``` +docker run -d -p 3000:3000 \ + -e "MB_DB_TYPE=postgres" \ + -e "MB_DB_DBNAME=" \ + -e "MB_DB_PORT=5432" \ + -e "MB_DB_USER=" \ + -e "MB_DB_PASS=" \ + -e "MB_DB_HOST=" \ + --name metabase metabase/metabase +``` + +### 7. Remove the old container that was using the H2 database + +If you have your H2 file backed up somewhere safe, go ahead and remove the old container. See [Docker docs](https://docs.docker.com/engine/reference/commandline/rm/) for removing containers. + +## Running Metabase application database migrations manually + +When Metabase is starting up, it will typically attempt to determine if any changes are required to the application database, and, if so, will execute those changes automatically. If for some reason you wanted to see what these changes are and run them manually on your database then we let you do that. + +Simply set the following environment variable before launching Metabase: + + export MB_DB_AUTOMIGRATE=false + +When the application launches, if there are necessary database changes, you'll receive a message like the following which will indicate that the application cannot continue starting up until the specified upgrades are made: + + 2015-12-01 12:45:45,805 [INFO ] metabase.db :: Database Upgrade Required + + NOTICE: Your database requires updates to work with this version of Metabase. Please execute the following sql commands on your database before proceeding. + + -- ********************************************************************* + -- Update Database Script + -- ********************************************************************* + -- Change Log: migrations/liquibase.yaml + -- Ran at: 12/1/15 12:45 PM + -- Against: @jdbc:h2:file:/Users/agilliland/workspace/metabase/metabase/metabase.db + -- Liquibase version: 3.4.1 + -- ********************************************************************* + + -- Create Database Lock Table + CREATE TABLE PUBLIC.DATABASECHANGELOGLOCK (ID INT NOT NULL, LOCKED BOOLEAN NOT NULL, LOCKGRANTED TIMESTAMP, LOCKEDBY VARCHAR(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID)); + + ... + + Once your database is updated try running the application again. + + 2015-12-01 12:46:39,489 [INFO ] metabase.core :: Metabase Shutting Down ... + +You can then take the supplied SQL script and apply it to your database manually. Once that's done just restart Metabase and everything should work normally. + +## Troubleshooting migration issues + +Check out [this troubleshooting guide](../troubleshooting-guide/loading-from-h2). diff --git a/_docs/doc-update-detection/installation-and-operation/monitoring-metabase.md b/_docs/doc-update-detection/installation-and-operation/monitoring-metabase.md new file mode 100644 index 000000000..063b699d9 --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/monitoring-metabase.md @@ -0,0 +1,98 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Monitoring your Metabase' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/monitoring-metabase.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/jmx-monitoring + - /docs/doc-update-detection/operations-guide/enable-jmx +--- + +# Monitoring Your Metabase + +Diagnosing performance-related issues can be a challenge. Luckily, the JVM ships with tools that can help diagnose many common issues. Enabling JMX and using a tool like VisualVM can help diagnose issues related to running out of memory, a stalled Metabase, or slow response times. + +This guide assumes that you have the VisualVM tool installed locally. VisualVM is included with OpenJDK and the Oracle JDK. You can find VisualJVM in the `bin` directory of the JDK installation. Some Linux distributions separate VisualVM from the JDK, in which case it's a separate `visualvm` package. + +## Connecting to a local Metabase + +If you have VisualVM installed on your Metabase server and are able to run VisualVM there, this is the easiest path as there is no need to setup remote communication with your metabase instance. In this scenario, start Metabase like you would normally and separately start VisualVM. + +![localprocess](images/LocalProcessVisualVM.png) + +## Connecting to a remote Metabase + +Monitoring a remote Metabase instance (or a local instance running in a docker container) is probably more common, but requires a more setup. First we need to specify some system properties that lets the JVM know that we want to allow remote monitoring. Assuming we are running Metabase using `java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar`, we'd need change the invocation to the below command, which includes the properties: + +```sh +java --add-to-start=jmx,jmx-remote \ + -Dcom.sun.management.jmxremote \ + -Dcom.sun.management.jmxremote.port=1099 \ + -Dcom.sun.management.jmxremote.rmi.port=1099 \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=false \ + -Dcom.sun.management.jmxremote.local.only=false \ + -Djava.rmi.server.hostname= \ + -jar metabase.jar +``` + +Port `1099` is a typical RMI/JMX port, but it can be any accessible port. + +The above command opens up your application to monitoring by anyone and should only be used when on a trusted network for a short period of time. Securing this connection is possible, see [the Oracle +docs](https://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html). + +If you're running Metabase in a `docker` container, you'll need to specify the system properties detailed above and will also need to ensure the port is open. Docker allows specifying environment variables via a separate file that can be passed into the `docker run` invocation. You can create a file called `metabase-vars.env` with `JAVA_OPTS` specified: + +``` +JAVA_OPTS=-Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.rmi.port=1099 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false -Djava.rmi.server.hostname= +``` + +This file expects to have each environment variable on its own line with no line breaks: + +```sh +docker run --env-file=metabase-vars.env -d -p 3000:3000 -p 1099:1099 -h --name metabase metabase/metabase +``` + +The addition `-p 1099:1099` opens the JMX port for monitoring and the `--env-file=metabase-vars.env` passes in the extra JMX related environment variables. With the instance started, VisualVM needs to know how to connect to the running instance. First add a new remote instance: + +![addremotehost](images/AddRemoteHost.png) + +Then use the hostname you specified above: + +![sethostname](images/SetRemoteHostName.png) + +Your local machine must to be able to refer to the hostname you specified (which might require a hosts entry): + +![addjmxhost](images/ClickAddJMXHost.png) + +If you're using Docker, the port specified for the JMX host needs to match the system property and the exposed port: + +![jmxport](images/EnterJMXPort.png) + +Next open the new remote JMX process: + +![jmxinstance](images/OpenRemoteInstance.png) + +## Runtime information + +Connecting to a running Metabase with VisualVM makes a lot of runtime information available. Here are some highlights: + +### Heap dump + +When running into memory-related issues, typically the first question to ask is: what is consuming extra memory? A heap dump will take a snapshot of everything in memory at that specific point of time. That memory snapshot can be analyzed later by tools like the [Eclipse Memory Analyzer Tool](https://www.eclipse.org/mat/). Create a heap dump from the "Monitor" tab: + +![heapdump](images/HeapDump.png) + +### Thread dump + +Another useful picture of a running Metabase system is a Thread Dump. In cases when Metabase appears stalled or extremely slow, a thread dump will indicate what each thread is executing (or blocked on) for that specific point in time Collect a thread dump via the "Threads" tab: + +![threaddump](images/ThreadDump.png) + +## Further reading + +- [Running Metabase](../troubleshooting-guide/running) +- [Observability with Prometheus](./observability-with-prometheus) diff --git a/_docs/doc-update-detection/installation-and-operation/observability-with-prometheus.md b/_docs/doc-update-detection/installation-and-operation/observability-with-prometheus.md new file mode 100644 index 000000000..eaf93e095 --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/observability-with-prometheus.md @@ -0,0 +1,175 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Observability with Prometheus' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/observability-with-prometheus.md' +--- + +# Observability with Prometheus + +You can export metrics in [Prometheus](https://prometheus.io/) format from your Metabase. + +## Running Metabase and Prometheus locally + +To give you an idea of how Metabase and Prometheus would work in your production environment, we'll walk through how to set up Metabase and Prometheus locally. + +## Start up Metabase with `MB_PROMETHEUS_SERVER_PORT` + +Download the latest [Metabase JAR](/start/oss/), and run Metabase using an environment variable to specify the Prometheus server port: + +```sh +MB_PROMETHEUS_SERVER_PORT=9191 java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +The `MB_PROMETHEUS_SERVER_PORT=9191` specifies which port (`9191`) Metabase will use to send data to Prometheus. To clarify the ports that will be involved here: + +- Port `3000` is the port Metabase uses to serve the Metabase app. You can set another port with `MB_JETTY_PORT` (e.g., `MB_JETTY_PORT=3001`). +- Port `9191` (or whichever port you specified with the `MB_PROMETHEUS_SERVER_PORT` environment variable) is the port Prometheus uses to scrape metrics from Metabase. +- Port `9090` is the port Prometheus uses to serve the Prometheus application. + +When you start Metabase, the Metabase logs will tell you that Metabase is starting the `prometheus metrics collector` and `prometheus metrics web-server`. + +```sh +(truncated logs) +2022-09-01 17:47:38,808 INFO metabase.util :: Database setup took 3.4 s +2022-09-01 17:47:38,826 INFO metabase.core :: Setting up prometheus metrics +2022-09-01 17:47:38,827 INFO metabase.prometheus :: Starting prometheus metrics collector +2022-09-01 17:47:38,839 INFO metabase.prometheus :: Starting prometheus metrics web-server on port 9,191 +(truncated logs) +``` + +You can view your locally running Metabase at `http://localhost:3000`. + +## Download and configure Prometheus + +[Download Prometheus](https://prometheus.io/download), and extract the files. + +Change into the Prometheus directory, add the following YAML file to configure your Prometheus: + +## Prometheus configuration file example + +```yaml +global: + scrape_interval: 15s # By default, scrape targets every 15 seconds. + + # Attach these labels to any time series or alerts when communicating with + # external systems (federation, remote storage, Alertmanager). + external_labels: + monitor: "codelab-monitor" + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + # The job name is added as a label `job=` to any timeseries scraped from this config. + - job_name: "prometheus" + + # Override the global default and scrape targets from this job every 5 seconds. + scrape_interval: 5s + # use whatever port here that you set for MB_PROMETHEUS_SERVER_PORT + static_configs: + - targets: ["localhost:9191"] +``` + +You need to change the "target" to where Metabase is, for this particular example, Metabase resides in the same host where Prometheus is running ("localhost"). + +## Running Prometheus Locally + +In a new terminal process in the Prometheus directory, run: + +```sh +./prometheus --config.file=prometheus.yml +``` + +Then check `http://localhost:9090`. You should see the Prometheus app, and be able to search for various metrics emitted by Metabase. + +![Prometheus page showing `jvm_thread_state` graph](./images/prometheus.png) + +## Sample metrics output + +Here is some sample output from Metabase: + +```yaml +'# HELP jvm_threads_current Current thread count of a JVM +'# TYPE jvm_threads_current gauge +jvm_threads_current 81.0 +'# HELP jvm_threads_daemon Daemon thread count of a JVM +'# TYPE jvm_threads_daemon gauge +jvm_threads_daemon 36.0 +'# HELP jvm_threads_peak Peak thread count of a JVM +'# TYPE jvm_threads_peak gauge +jvm_threads_peak 81.0 +'# HELP jvm_threads_started_total Started thread count of a JVM +'# TYPE jvm_threads_started_total counter +jvm_threads_started_total 104.0 +'# HELP jvm_threads_deadlocked Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers +'# TYPE jvm_threads_deadlocked gauge +jvm_threads_deadlocked 0.0 +``` + +## Exported metrics + +Metrics exported by Metabase include: + +- `c3p0_max_pool_size` +- `c3p0_min_pool_size` +- `c3p0_num_busy_connections` +- `c3p0_num_connections` +- `c3p0_num_idle_connections` +- `c3p0_num_threads_awaiting_checkout_default_user` +- `jetty_async_dispatches_total` +- `jetty_async_requests_total` +- `jetty_async_requests_waiting` +- `jetty_async_requests_waiting_max` +- `jetty_dispatched_active` +- `jetty_dispatched_active_max` +- `jetty_dispatched_time_max` +- `jetty_dispatched_time_seconds_total` +- `jetty_dispatched_total` +- `jetty_expires_total` +- `jetty_request_time_max_seconds` +- `jetty_request_time_seconds_total` +- `jetty_requests_active` +- `jetty_requests_active_max` +- `jetty_requests_total` +- `jetty_responses_bytes_total` +- `jetty_responses_total` +- `jetty_stats_seconds` +- `jvm_gc_collection_seconds_count` +- `jvm_gc_collection_seconds_sum` +- `jvm_memory_bytes_committed` +- `jvm_memory_bytes_init` +- `jvm_memory_bytes_max` +- `jvm_memory_bytes_used` +- `jvm_memory_objects_pending_finalization` +- `jvm_memory_pool_bytes_committed` +- `jvm_memory_pool_bytes_init` +- `jvm_memory_pool_bytes_max` +- `jvm_memory_pool_bytes_used` +- `jvm_memory_pool_collection_committed_bytes` +- `jvm_memory_pool_collection_init_bytes` +- `jvm_memory_pool_collection_max_bytes` +- `jvm_memory_pool_collection_used_bytes` +- `jvm_threads_current` +- `jvm_threads_daemon` +- `jvm_threads_deadlocked` +- `jvm_threads_deadlocked_monitor` +- `jvm_threads_peak` +- `jvm_threads_started_total` +- `jvm_threads_state` +- `process_cpu_seconds_total` +- `process_max_fds` +- `process_open_fds` +- `process_start_time_seconds` +- `process_virtual_memory_bytes` +- `metabase_email_messages_total` +- `metabase_email_messages_created` +- `metabase_email_message_errors_total` +- `metabase_email_message_errors_created` + +## Further reading + +- [Running Metabase](../troubleshooting-guide/running) +- [Monitoring Metabase](./monitoring-metabase) diff --git a/_docs/doc-update-detection/installation-and-operation/privacy.md b/_docs/doc-update-detection/installation-and-operation/privacy.md new file mode 100644 index 000000000..fe997244e --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/privacy.md @@ -0,0 +1,25 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: Privacy +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/privacy.md' +redirect_from: + - /docs/doc-update-detection/privacy +--- + +# Privacy + +## Do you need a Data Processing Agreement with Metabase to comply with GDPR? + +### Self-hosted + +If you self-host your Metabase instance, we have no access to any of your data, UNLESS you opted in to give us [anonymized usage stats][information-collection]. Even in that case, Metabase doesn't gather any personally-identifiable data. As such, if you're self-hosting, we are not a data processor for the purposes of GDPR. + +### Metabase Cloud + +If you're a [Metabase Cloud](/pricing/) customer, your [Terms of Service](/license/hosting) include a Data Processing Agreement (DPA). + +[information-collection]: information-collection diff --git a/_docs/doc-update-detection/installation-and-operation/running-metabase-on-azure.md b/_docs/doc-update-detection/installation-and-operation/running-metabase-on-azure.md new file mode 100644 index 000000000..0dd912304 --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/running-metabase-on-azure.md @@ -0,0 +1,206 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Running Metabase on Microsoft Azure' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/running-metabase-on-azure.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/running-metabase-on-azure +--- + +# Running Metabase on Microsoft Azure + +This guide covers the basics for running your Metabase instance in Microsoft Azure using Docker. + +## Step 1: Create the resource group (resource grouping) + +On the Azure management console, click on the **Resource Groups** icon at the top of the page (or just search for Resource Groups). If you already have a resource group, you can go straight to [Step 2](#step-2-create-the-vnet-virtual-network). + +On the resource group page, click on the **+ Add** button in the top bar to create a new resource group. On the **Create a resource group** page, select your valid Azure Subscription, enter the name of your resource group, and select a region. + +![Create a Resource Group](images/AZResource_group_Add.png) + +Click **Next** until you see the **Create** button, then click it. + +When selecting the region for your Metabase, you should consider the location of your users and your data warehouse, as well as the infrastructure costs and privacy laws that might restrict cross-border data transfers. + +## Step 2: Create the VNET (virtual network) + +At the center of the page, click on the **Create resources** button. Search for **VNET**: + +![VNET Marketplace](images/AZMarketPlaceVnet.png) + +Select the VNET product from Microsoft, and click **Create**: + +![VNET Product](images/AZVnet.png) + +Enter a name for the virtual network and select the same region you used for the resource group. Click on **Next: IP Addresses** button at the bottom. + +Here we'll create a secure network composed of a public subnet (a network that is exposed to the internet), and a private network that will contain your application database. + +In the IPv4 address, you should have a default value of 10.0.0.0/16 (otherwise add that network space to the box). Next, add two subnets: + +- one subnet named public, with the subnet address range of 10.0.1.0/24, and +- one subnet named private with the subnet range of 10.0.2.0/24. + +![Azure network configuration](images/AZNetworks.png) + +Click **Next** until you get to the **Review and create** page, then click on the **Create** button at the bottom to create your network. + +## Step 3: Create the Application Database (PostgreSQL) + +From the Azure Management console homepage, create a new resource. This time search for **Azure Database for PostgreSQL**. You can also find this database in the Marketplace menu under **Databases**. + +![Azure PostgreSQL](images/AZDatabase.png) + +In the next page you will have to select the way you will use the service. Choose **Single server** for now, which is a good starting point, but take into account that this will create just one instance of PostgreSQL that will be your single point of failure. + +On the next screen, select or enter the following: + +- **Resource group**: the one you are including all your components. +- **Server name**: a unique name for your database. +- **Data Source**: can be left as `None`. +- **Location**: the same one you used for your Resource Group and VNET. +- **Version**: use the latest one you can. +- **Compute + Storage**: you can re-dimension your database, but you must select the `General Purpose` tier, as it's the only tier that provides a Private Link. + +Then choose an admin username and password of your choice. + +Click **Next** until you get to the final page, then click **Create**. It'll take some time for Azure to create the database. Once the creation is complete, click on the **Go to resource** button. + +## Step 4: Create the private endpoint connection + +On the properties page for the Azure for PostgreSQL database, you can manage parameters for your database. You'll create the **Private Endpoint** to the database, so all traffic from the web application is routed internally through Azure's network. + +On the left menu, click on **Private endpoint connection** which is situated under **Security** + +![Azure Database for PostgreSQL](images/AZPostgreSQLMain.png) + +Now click on the button of the top bar with a plus sign that says **Private endpoint**. In the page that opens: + +1. Provide a name for this link (any name that describes what you are trying to do is fine, like `metabase_link`). Select the region where the database lives, click **Next**. +2. On the **Resource** section of the configuration, ensure that **Resource type** is set to `Microsoft.DBforPostgreSQL/servers` which will enable you to select in the dropdown below the server created in the previous step, and leave **Target sub-resource** with the default value +3. On the **Configuration** section, the only value that needs to be changed is the **Subnet** one, where you need to select the **private** subnet that you created on the first step of this guide, and leave everything else as it is. + +![Azure PrivateLink config](images/AZPrivateLink.png) + +Now go to the last step and click **Create**. Once the endpoint is created, you will need do two things before proceeding: + +1. In the page of database server you just created go to the database **Connection Security** item and **deny all public network access**. +2. In the page of the VNET you created in the previous step, go to **Connected devices** setting and you should see a device connected to the network. Take note of the IP address, as you'll need it in Step 5 (this is the IP address that the network has given to the database server). + +## Step 5: Create web application (deploy Metabase) + +At last, the step where all the magic comes together: go to your resource group and add a new resource, or search for **Web App** in the Marketplace (blue globe icon). +![Azure web app](images/AZMarketplaceWebApp.png) + +Now set up the following values on the page (resource group should be the same as in the first step): + +- **Name**: The name must be unique, as the subdomain is shared across all Azure deployments. +- **Publish**: Docker Container. +- **Operating System**: Linux. +- **Region**: Use the same region as the previous steps. +- **App Service Plan**: If you don't have one a service plan, Azure will create a new one automatically. +- **SKU and Size**: Set a Production level plan with **AT LEAST** 200 total ACU and 3.5GB of memory, and click **Apply**. + +Now go to the next step where you will select: + +- **Options**: Single container. +- **Image source**: DockerHub. +- **Access Type**: Public. +- **Image and tag**: metabase/metabase:latest (or choose any other docker image tag of your preference, like our Enterprise Edition). To find the latest version, check our [Community Edition Dockerhub repository](https://hub.docker.com/r/metabase/metabase/tags?page=1&ordering=last_updated) and also our [Enterprise Edition Dockerhub Repository](https://hub.docker.com/r/metabase/metabase-enterprise/tags?page=1&ordering=last_updated). +- **Startup command**: Leave this field empty. + +Click **Next** until you get to the last section, then click **Create**, and wait while your application initializes. + +Now go to the application configuration page and click on **Settings** -> **Networking** on the left side of the page. On the next page, click on **Click here to configure** under **VNET integration**. + +![Azure VNET integration](images/AZVNETintegration.png) + +Now click on the huge plus sign next to **Add VNET** and select the VNET that you created, and the public subnet. Click **OK**. + +![Azure VNET public subnet](images/AZVNETPublicSubnet.png) + +Return to the application configuration page and click on **Settings** -> **Configuration** on the left side of the page. You should see a few Application Settings already configured. + +You'll need to add the [environment Variables](../configuring-metabase/environment-variables) for connecting Metabase to its [PostgreSQL Application Database](../installation-and-operation/configuring-application-database#postgresql). Make sure that you use the full **MB_DB_CONNECTION_URI**. + +Also, take into account that the username in Azure PostgreSQL is `user@name_of_your_database_engine` so in this case the entire connection uri would be as follows: + +``` +postgresql://databasePrivateIPAddress:port/postgres?user=user@name_of_your_database_engine&password=configuredpassword&ssl=true&sslmode=required +``` + +For example, if your values are: + +1. **database private IP address**: 10.0.2.4 +2. **database port**: 5432 (in the case of Postgres, MySQL/MariaDB default port is 3306) +3. **name of the database server**: metabase-app-database +4. **username of the database**: metabase +5. **password**: Password1! + +then your connection string would be: + +``` +postgresql://10.0.2.4:5432/postgres?user=metabase%40metabase-app-database&password=Password1!&ssl=true&sslmode=require +``` + +Note: the "@" character has been replaced for "%40", as the "@" will no longer work in versions > 43 + +Click **Save** and the instance will restart. + +Once it finishes, you should be able to visit your Metabase at the URL shown in the "Overview" tab in the web app (under the URL section). + +## Additional configurations + +### How to enable Health checks + +Enabling health checking in Metabase is a good practice. Go to your **web app** -> **Monitoring** -> **Health Check** -> **Enable health check**, and include in the path `/api/health`. + +### How to upgrade + +Go to the Metabase web app you created and click on **Deployment** -> **Deployment Center**. + +Change the version of the container to the new version in the **Full Image Name and Tag** text field under **Registry settings**, and click on **Save**. Available versions of the Metabase Docker image can be found on [Docker Hub](https://hub.docker.com/r/metabase/metabase/tags?page=1&ordering=last_updated). + +**Important**: always ensure you have backed up the Metabase application database before upgrading, _especially_ when doing so between major versions. Metabase also doesn't officially support downgrading versions. + +### How to see the logs + +Visit your web app in Azure, and navigate to **Monitoring -> Log stream**. + +You should be able to see the logs as well inside Metabase by going to Settings -> Admin -> Troubleshooting -> Logs. + +### Performance tuning + +- Disable FTP State +- Change HTTP version to 2.0 +- Enable WebSockets +- ARR Affinity enabled + +### Custom domains + +In your Azure web app, visit **Settings** -> **Custom domains** to use a custom domain with your own certificates. + +### Scale-up vs Scale-out + +Azure provides an easy way to increase the server's capacity by doing a Scale-up. Simply choose a pricing tier with more RAM and CPU count and restart the instance. This approach is easier than scaling out and you should choose this option first before scaling out. + +For a highly-available Metabase deployment, you can tell your web app to scale-out (more servers serving the application in parallel). Simply go to Scale-out and use the slider to ask for more instances, or use a custom autoscaling policy (like using more servers during your work hours and fewer during off hours). + +### CORS + +In case you're embedding Metabase, you might need to enable CORS in **Settings** -> **CORS** in the web application. You'll need to fill the origin domains for the app with the embedded Metabase, so Azure knows to enable cross requests from those domains. + +### Database name + +Azure does not let users create a database upon service creation, that's the reason why we used `postgres` as the database to install Metabase. Although this shouldn't be a problem, a good practice would be to install the database in a separate database named `metabase`. If you are not in a hurry to try the product, you should create a database named `metabase` as soon as you create the database and then use the appropriate connection string when deploying the docker container. +In the example above the connection string would be + +``` +postgresql://10.0.2.4:5432/metabase?user=metabase@metabase-app-database&password=Password1!&ssl=true&sslmode=require +``` + +If you have trouble connecting, refer to the [postgres configuration instructions](../installation-and-operation/configuring-application-database#postgresql) as you may run into a problem with an `@` symbol in the username portion of the connection string. Using a combination of `MB_DB_CONNECTION_URI` with separate `MB_DB_USER` and `MB_DB_PASSWORD` fields also works. diff --git a/_docs/doc-update-detection/installation-and-operation/running-metabase-on-debian.md b/_docs/doc-update-detection/installation-and-operation/running-metabase-on-debian.md new file mode 100644 index 000000000..bdbd3261b --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/running-metabase-on-debian.md @@ -0,0 +1,178 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Running Metabase on Debian as a service with nginx' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/running-metabase-on-debian.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/running-metabase-on-debian +--- + +# Running Metabase on Debian as a service with nginx + +For those people who don't (or can't) use Docker in their infrastructure, there's still a need to easily setup and deploy Metabase in production. On Debian-based systems, this means registering Metabase as a service that can be started/stopped/uninstalled. + +**Note:** This is just a _bare-bones recipe_ to get you started. Anyone can take it from here to do what they need to do on their systems, and should follow best practices for setting up and securing the rest of their server. + +## Assumptions + +The core assumption in this guide: + +- You will run Metabase using the `metabase.jar` file +- You already have `nginx` and `postgres` (or another supported database) running on your server +- You will use environment variables to configure your Metabase instance +- You have `sudo` access on your server + +## Create an unprivileged user to run Metabase and give the user access to app and logs + +For security reasons we want to have Metabase run as an unprivileged user. We will call the user simply `metabase`. Further we will create the files we will need later for logging and configuration of Metabase, and apply the correct security settings for our unprivileged user. + +``` +sudo groupadd -r metabase +sudo useradd -r -s /bin/false -g metabase metabase +sudo chown -R metabase:metabase +sudo touch /var/log/metabase.log +sudo chown syslog:adm /var/log/metabase.log +sudo touch /etc/default/metabase +sudo chmod 640 /etc/default/metabase +``` + +## Create a Metabase Service + +Every service needs a script that tells `systemd` how to manage it, and what capabilities it supports. Services are typically registered at `/etc/systemd/system/`. So, a Metabase service should live at `/etc/systemd/system/metabase.service`. + +### The Metabase service file + +Create the `/etc/systemd/system/metabase.service` service file and open it in your editor: + +``` +sudo touch /etc/systemd/system/metabase.service +sudo /etc/systemd/system/metabase.service +``` + +In `/etc/systemd/system/metabase.service`, replace configurable items (they look like ``) with values sensible for your system. The Metabase script below has extra comments to help you know what everything is for. + +``` +[Unit] +Description=Metabase server +After=syslog.target +After=network.target + +[Service] +WorkingDirectory= +ExecStart=/usr/bin/java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +EnvironmentFile=/etc/default/metabase +User=metabase +Type=simple +StandardOutput=syslog +StandardError=syslog +SyslogIdentifier=metabase +SuccessExitStatus=143 +TimeoutStopSec=120 +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +## Create syslog conf + +Next we need to create a syslog conf to make sure systemd can handle the logs properly. + +``` +sudo touch /etc/rsyslog.d/metabase.conf +sudo /etc/rsyslog.d/metabase.conf + +if $programname == 'metabase' then /var/log/metabase.log +& stop +``` + +Restart the syslog service to load the new config. + +``` +sudo systemctl restart rsyslog.service +``` + +## Environment variables for Metabase + +[Environment variables](../configuring-metabase/environment-variables) provide a good way to customize and configure your Metabase instance on your server. On Debian systems, services typically expect to have accompanying configs inside `etc/default/`. + +### The Metabase config file + +Open your `/etc/default/metabase` environment config file in your editor: + +``` +sudo /etc/default/metabase +``` + +In `/etc/default/metabase`, replace configurable items (they look like ``) with values sensible for your system. Some Metabase configs have available options, some of which are shown below, separated by `|` symbols: + +``` +MB_PASSWORD_COMPLEXITY= +MB_PASSWORD_LENGTH=<10> +MB_JETTY_HOST=<0.0.0.0> +MB_JETTY_PORT=<12345> +MB_DB_TYPE= +MB_DB_DBNAME= +MB_DB_PORT=<5432> +MB_DB_USER= +MB_DB_PASS= +MB_DB_HOST= +MB_EMOJI_IN_LOGS= +# any other env vars you want available to Metabase +``` + +## Final steps + +The best part of setting up Metabase as a service on a Debian-based system is to be confident it will start up at every system boot. We only have a few more quick steps to finish registering our service and having Metabase up and running. + +### Ensure your database is ready + +If you're running `postgres` or some other database, you need to ensure you've already followed the instructions for your database system to create a database for Metabase, as well as a user that can access that database. These values should match what you've set in your Metabase config for the `MB_DB_TYPE`, `MB_DB_DBNAME`, `MB_DB_USER`, and `MB_DB_PASS` environment variables. If you don't have your database properly configured, Metabase won't be able to start. + +### Ensure `nginx` is setup to proxy requests to Metabase + +Getting into too much detail about configuring `nginx` is well outside the scope of this guide, but here's a quick `nginx.conf` file that will get you up and running. + +**Note:** The `nginx.conf` below assumes you are accepting incoming traffic on port 80 and want to proxy requests to Metabase, and that your Metabase instance is configured to run on `localhost` at port `3000`. There are several proxy directives you may care about, so you should check those out further in the [Official `nginx` docs](https://nginx.org/en/docs/). + +``` +# sample nginx.conf +# proxy requests to Metabase instance +server { + listen 80; + listen [::]:80; + server_name your.domain.com; + location / { + proxy_pass http://127.0.0.1:3000; + } +} +``` + +### Register your Metabase service + +Now, it's time to register our Metabase service with `systemd` so it will start up at system boot. We'll also ensure our log file is created and owned by the unprivileged user our service runs the `metabase.jar` as. + +``` +sudo systemctl daemon-reload +sudo systemctl start metabase.service +sudo systemctl status metabase.service +``` + +Once we are ok here, enable the service to startup during boot. + +``` +sudo systemctl enable metabase.service +``` + +## Start, stop, or restart Metabase + +Now, whenever you need to start, stop, or restart Metabase, all you need to do is: + +``` +sudo systemctl start metabase.service +sudo systemctl stop metabase.service +sudo systemctl restart metabase.service +``` diff --git a/_docs/doc-update-detection/installation-and-operation/running-metabase-on-docker.md b/_docs/doc-update-detection/installation-and-operation/running-metabase-on-docker.md new file mode 100644 index 000000000..19c591ee2 --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/running-metabase-on-docker.md @@ -0,0 +1,360 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Running Metabase on Docker' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/running-metabase-on-docker.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/running-metabase-on-docker +--- + +# Running Metabase on Docker + +> To get fast, reliable, and secure deployment with none of the work or hidden costs that come with self-hosting, check out [Metabase Cloud](/cloud/). + +Metabase provides an official Docker image via Dockerhub that can be used for deployments on any system that is running Docker. + +If you're trying to upgrade your Metabase version on Docker, check out these [upgrading instructions](upgrading-metabase). + +## Open Source quick start + +Use this quick start to run the Open Source version of Metabase locally. See below for instructions on [running Metabase in production](#production-installation). + +Assuming you have [Docker](https://www.docker.com/) installed and running, get the latest Docker image: + +``` +docker pull metabase/metabase:latest +``` + +Then start the Metabase container: + +``` +docker run -d -p 3000:3000 --name metabase metabase/metabase +``` + +This will launch an Metabase server on port 3000 by default. + +Optional: to view the logs as your Open Source Metabase initializes, run: + +``` +docker logs -f metabase +``` + +Once startup completes, you can access your Open Source Metabase at `http://localhost:3000`. + +To run your Open Source Metabase on a different port, say port 12345: + +``` +docker run -d -p 12345:3000 --name metabase metabase/metabase +``` + +## Pro or Enterprise quick start + +Use this quick start if you have a [license token](../installation-and-operation/activating-the-enterprise-edition) for a [Pro or Enterprise version](/pricing/) of Metabase, and you want to run Metabase locally. See below for instructions on [running Metabase in production](#production-installation). + +Assuming you have [Docker](https://www.docker.com/) installed and running, get the latest Docker image: + +``` +docker pull metabase/metabase-enterprise:latest +``` + +Then start the Metabase container: + +``` +docker run -d -p 3000:3000 --name metabase metabase/metabase-enterprise +``` + +This will launch a Metabase server on port 3000 by default. + +Optional: to view the logs as Metabase initializes, run: + +``` +docker logs -f metabase +``` + +Once startup completes, you can access your Pro or Enterprise Metabase at `http://localhost:3000`. + +To run your Pro or Enterprise Metabase on a different port, say port 12345: + +``` +docker run -d -p 12345:3000 --name metabase metabase/metabase-enterprise +``` + +## Production installation + +Metabase ships with an embedded H2 database that uses the file system to store its own application data. Meaning, if you remove the container, you'll lose your Metabase application data (your questions, dashboards, collections, and so on). + +If you want to run Metabase in production, you'll need store your application data in a [production-ready database](./migrating-from-h2#supported-databases-for-storing-your-metabase-application-data). + +Once you've provisioned a database, like Postgres, for Metabase to use to store its application data, all you need to do is provide Metabase with the connection information and credentials so Metabase can connect to it. + +### Running Docker in production + +Let's say you set up a Postgres database by running: + +``` +createdb metabaseappdb +``` + +No need to add any tables; Metabase will create those on startup. And let's assume that database is accessible via `my-database-host:5432` with username `name` and password `password`. + +Here's an example Docker command that tells Metabase to use that database: + +``` +docker run -d -p 3000:3000 \ + -e "MB_DB_TYPE=postgres" \ + -e "MB_DB_DBNAME=metabaseappdb" \ + -e "MB_DB_PORT=5432" \ + -e "MB_DB_USER=name" \ + -e "MB_DB_PASS=password" \ + -e "MB_DB_HOST=my-database-host" \ + --name metabase metabase/metabase +``` + +Keep in mind that Metabase will be connecting from _within_ your Docker container, so make sure that either: a) you're using a fully qualified hostname, or b) that you've set a proper entry in your container's `/etc/hosts file`. + +## Migrating to a production installation + +If you've already been running Metabase with the default application database (H2), and want to use a production-ready application database without losing your app data (your questions, dashboards, etc), see [Migrating from H2 to a production database](migrating-from-h2). + +## Example Docker compose YAML file + +Here's an example `docker-compose.yml` file for running Metabase with a PostgreSQL database `metabaseappdb`: + +> This is an example file and and is not meant to be used when running Metabase in a production environment. Please refer to our guide about [How to run Metabase in production](/learn/metabase-basics/administration/administration-and-operation/metabase-in-production) + +```yml +services: + metabase: + image: metabase/metabase:latest + container_name: metabase + hostname: metabase + volumes: + - /dev/urandom:/dev/random:ro + ports: + - 3000:3000 + environment: + MB_DB_TYPE: postgres + MB_DB_DBNAME: metabaseappdb + MB_DB_PORT: 5432 + MB_DB_USER: metabase + MB_DB_PASS: mysecretpassword + MB_DB_HOST: postgres + networks: + - metanet1 + healthcheck: + test: curl --fail -I http://localhost:3000/api/health || exit 1 + interval: 15s + timeout: 5s + retries: 5 + postgres: + image: postgres:latest + container_name: postgres + hostname: postgres + environment: + POSTGRES_USER: metabase + POSTGRES_DB: metabaseappdb + POSTGRES_PASSWORD: mysecretpassword + networks: + - metanet1 +networks: + metanet1: + driver: bridge +``` + +## Additional Docker maintenance and configuration + +- [Customizing the Metabase Jetty server](#customizing-the-metabase-jetty-server) +- [Docker-specific environment variables](#docker-specific-environment-variables) +- [Setting the Java Timezone](#setting-the-java-timezone) +- [Copying the application database](#copying-the-application-database) +- [Mounting a mapped file storage volume](#mounting-a-mapped-file-storage-volume) +- [Getting your config back if you stopped your container](#getting-your-config-back-if-you-stopped-your-container) +- [Adding external dependencies or plugins](#adding-external-dependencies-or-plugins) +- [Use Docker Secrets to hide sensitive parameters](#use-docker-secrets-to-hide-sensitive-parameters) +- [Troubleshooting](#troubleshooting) +- [Continue to setup](#continue-to-setup) + +### Customizing the Metabase Jetty server + +You can use any of the custom settings from [Customizing the Metabase Jetty Webserver](../configuring-metabase/customizing-jetty-webserver) by setting environment variables in your Docker run command. + +### Docker-specific environment variables + +In addition to the standard custom settings there are two docker specific environment variables `MUID` and `MGID` which are used to set the user and group IDs used by metabase when running in a docker container. These settings make it possible to match file permissions when files, such as the application database, are shared between the host and the container. + +Here's how to use a database file, owned by your account and stored in your home directory: + +``` +docker run -d -v ~/my-metabase-db:/metabase.db --name metabase -e MB_DB_FILE=/metabase.db -e MUID=$UID -e MGID=$GID -p 3000:3000 metabase/metabase +``` + +### Setting the Java Timezone + +It's best to set your Java timezone to match the timezone you'd like all your reports to come in. You can do this by simply specifying the `JAVA_TIMEZONE` environment variable which is picked up by the Metabase launch script. For example: + +``` +docker run -d -p 3000:3000 \ + -e "JAVA_TIMEZONE=US/Pacific" \ + --name metabase metabase/metabase +``` + +### Copying the application database + +The default location for the application database in the container is `/metabase.db/metabase.db.mv.db`. You can copy this directory out of the container using the following command (replacing `CONTAINER_ID` with the actual container ID or name, `metabase` if you named the container): + +``` +docker cp CONTAINER_ID:/metabase.db ./ +``` + +The DB contents will be left in a directory named metabase.db. + +### Mounting a mapped file storage volume + +To persist your data outside of the container and make it available for use between container launches, we can mount a local file path inside our container. + +``` +docker run -d -p 3000:3000 \ + -v ~/metabase-data:/metabase-data \ + -e "MB_DB_FILE=/metabase-data/metabase.db" \ + --name metabase metabase/metabase +``` + +When you launch your container, Metabase will use the database file (`MB_DB_FILE`) at `~/metabase-data/metabase.db` instead of its default location. and we are mounting that folder from our local filesystem into the container. + +### Getting your config back if you stopped your container + +If you've previously run and configured your Metabase using the local Database and then stopped the container, your data will still be there unless you deleted the container with the `docker rm` command. To recover your previous configuration: + +#### 1. Find the stopped container using the `docker ps -a` command. It will look something like this: + +``` +docker ps -a | grep metabase + ca072cd44a49 metabase/metabase "/app/run_metabase.sh" About an hour ago Up About an hour 0.0.0.0:3000->3000/tcp metabase + 02e4dff057d2 262aa3d0f714 "/app/run_metabase.sh" 23 hours ago Exited (0) 23 hours ago pedantic_hypatia + 0d2170d4aa4a 262aa3d0f714 "/app/run_metabase.sh" 23 hours ago Exited (0) 23 hours ago stoic_lumiere +``` + +Once you have identified the stopped container with your configuration in it, save the container ID from the left most column for the next step. + +#### 2. Use `docker commit` to create a new custom docker image from the stopped container containing your configuration. + +``` +docker commit ca072cd44a49 mycompany/metabase-custom +sha256:9ff56186de4dd0b9bb2a37c977c3a4c9358647cde60a16f11f4c05bded1fe77a +``` + +#### 3. Run your new image using `docker run` to get up and running again. + +``` +docker run -d -p 3000:3000 --name metabase mycompany/metabase-custom +430bb02a37bb2471176e54ca323d0940c4e0ee210c3ab04262cb6576fe4ded6d +``` + +You should have your previously configured Metabase Installation back. If it's not the one you expected, try a different stopped container and repeat these steps. + +### Adding external dependencies or plugins + +To add external dependency JAR files, such as the Oracle or Vertica JDBC drivers or 3rd-party Metabase drivers), you'll need to: + +- create a `plugins` directory in your host system, and +- bind that directory so it's available to Metabase as the path `/plugins` (using either `--mount` or `-v`/`--volume`). + +For example, if you have a directory named `/path/to/plugins` on your host system, you can make its contents available to Metabase using the `--mount` option as follows: + +``` +docker run -d -p 3000:3000 \ + --mount type=bind,source=/path/to/plugins,destination=/plugins \ + --name metabase metabase/metabase +``` + +Note that Metabase will use this directory to extract plugins bundled with the default Metabase distribution (such as drivers for various databases such as SQLite), thus it must be readable and writable by Docker. + +### Use Docker Secrets to hide sensitive parameters + +In order to keep your connection parameters hidden from plain sight, you can use Docker Secrets to put all parameters in files so Docker can read and load them in memory before it starts the container. + +Here is an example `docker-compose.yml` file to start a Metabase Docker container with secrets to connect to a PostgreSQL database. + +In addition to this example yml file, you'll need to create two files: + +- `db_user.txt` +- `db_password.txt` + +These files should be in the same directory as the `docker-compose.yml`. Put the `db_user` in the `db_user.txt` file, and db_password in the `db_password.txt` file. + +Notice the "\_FILE" on the environment variables that have a secret: + +```yml +services: + metabase: + image: metabase/metabase:latest + container_name: metabase + hostname: metabase + volumes: + - /dev/urandom:/dev/random:ro + ports: + - 3000:3000 + environment: + MB_DB_TYPE: postgres + MB_DB_DBNAME: metabase + MB_DB_PORT: 5432 + MB_DB_USER_FILE: /run/secrets/db_user + MB_DB_PASS_FILE: /run/secrets/db_password + MB_DB_HOST: postgres + networks: + - metanet1 + secrets: + - db_password + - db_user + healthcheck: + test: curl --fail -I http://localhost:3000/api/health || exit 1 + interval: 15s + timeout: 5s + retries: 5 + postgres: + image: postgres:latest + container_name: postgres + hostname: postgres + environment: + POSTGRES_USER_FILE: /run/secrets/db_user + POSTGRES_DB: metabase + POSTGRES_PASSWORD_FILE: /run/secrets/db_password + networks: + - metanet1 + secrets: + - db_password + - db_user +networks: + metanet1: + driver: bridge +secrets: + db_password: + file: db_password.txt + db_user: + file: db_user.txt +``` + +We currently support the following [environment variables](../configuring-metabase/environment-variables) to be used as secrets: + +- `MB_DB_USER` +- `MB_DB_PASS` +- `MB_DB_CONNECTION_URI` +- `MB_EMAIL_SMTP_PASSWORD` +- `MB_EMAIL_SMTP_USERNAME` +- `MB_LDAP_PASSWORD` +- `MB_LDAP_BIND_DN` + +In order for the Metabase container to read the files and use the contents as a secret, the environment variable name needs to be appended with a "\_FILE" as explained above. + +> This is an example file and and is not meant to be used when running Metabase in a production environment. Please refer to our guide about [How to run Metabase in production](/learn/metabase-basics/administration/administration-and-operation/metabase-in-production). + +## Troubleshooting + +See Running Metabase in the [Troubleshooting guide](../troubleshooting-guide/running). + +## Continue to setup + +Now that you've installed Metabase, it's time to [set it up and connect it to your database](../configuring-metabase/setting-up-metabase). diff --git a/_docs/doc-update-detection/installation-and-operation/running-metabase-on-elastic-beanstalk.md b/_docs/doc-update-detection/installation-and-operation/running-metabase-on-elastic-beanstalk.md new file mode 100644 index 000000000..d218c882b --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/running-metabase-on-elastic-beanstalk.md @@ -0,0 +1,87 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Running Metabase on AWS Elastic Beanstalk' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/running-metabase-on-elastic-beanstalk.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/running-metabase-on-elastic-beanstalk + - /docs/doc-update-detection/installation-and-operation/advanced-topics-for-running-Metabase-in-AWS-ElasticBeanstalk + - /docs/doc-update-detection/operations-guide/advanced-topics-for-running-Metabase-in-AWS-ElasticBeanstalk +--- + +# Running Metabase on AWS Elastic Beanstalk + +> Due to problems with the platform, we no longer recommend using Elastic Beanstalk to run Metabase in production. + +If you're running Metabase on Elastic Beanstalk, we recommend you switch to a different setup. + +## Alternatives to Elastic Beanstalk + +### Metabase Cloud + +We recommend [Metabase Cloud](/pricing/) (obviously). + +### Self-hosted setups + +You can set up Metabase with either PostgreSQL or MySQL as its application database, and run Metabase on a server you can monitor, either on your hardware or with a cloud provider. + +At a minimum, make sure you back up your application database regularly (and always before upgrading). Follow your organization's requirements for security, monitoring, and availability. + +### Professional services + +If you'd like help with setting up Metabase (or building out your data stack in general), check out the [professional services we offer](/product/professional-services). + +## Decouple your RDS database from the Elastic Beanstalk deployment + +If you're using AWS's Relational Database Service to store your Metabase application data, you can continue to do so (though you should still move your Metabase installation away from Elastic Beanstalk). You can use [environment variables](../configuring-metabase/environment-variables) to connect to your RDS host from wherever you move your Metabase installation to. + +### Notify people that your Metabase will be down for a bit + +This procedure will generate downtime, so make sure to communicate to your users that Metabase will be down while you recreate the environment with the new database. + +### Get a snapshot of your application database + +> You'll need the master username and password for the database you used when you created the Elastic Beanstalk instance. + +Identify the RDS endpoint that your Elastic Beanstalk is using by going to the configuration of the Environment and finding the endpoint value on the Database section. + +![RDS endpooint](images/EBDatabaseEndpoint.png) + +- If Retention is "Create snapshot", you're good to go. You can delete the whole Elastic Beanstalk environment, because AWS will take a snapshot (backup) of the database before deleting the environment. +- If Retention has a different value, visit your RDS instance and take a snapshot of the database used by the Elastic Beanstalk application. + + ![RDS snapshot](images/RDSTakeSnapshot.png) + +### Terminate your Elastic Beanstalk environment with snapshot + +Go to the Elastic Beanstalk Metabase application, select the running environment, and terminate it. Confirm that the database will be terminated **with snapshot**. + +![Terminate environment](images/EBTerminateEnvironment.png) + +Terminating the environment can take around 20 minutes. If the deletion fails, you'll have to identify through CloudFormation which resources failed to be deleted and delete them yourself. + +### Restore your snapshot + +Return to RDS and select the **Snapshots** option on the left of the page. You should see a Manual Snapshot listed. + +![RDS Snapshots](images/RDSSnapshotsMenu.png) + +Select that snapshot and click on **Actions** > **Restore Snapshot**. + +From this step on, you can follow the same steps as the [Configuring RDS for Metabase](./creating-RDS-database-on-AWS). + +## Upgrade your Elastic Beanstalk deployment + +If you want to stay in Elastic Beanstalk, you can keep upgrading it by following these steps: + +1. Download the [last published Beanstalk artifact file](https://downloads.metabase.com/v0.47.2/metabase-aws-eb.zip). +2. Unzip the file. +3. Edit the Dockerrun.aws.json file and change the image tag to the latest available version. Always Avoid using `:latest`, instead, use the latest version number. +4. Compress the file. +5. Upload the file to AWS as a new Beanstalk version. +6. Upgrade your environment. + +Remember that if you're using a Pro or Enterprise version of Metabase, you need to use the metabase/metabase-enterprise repository instead of the metabase/metabase one. diff --git a/_docs/doc-update-detection/installation-and-operation/running-metabase-on-podman.md b/_docs/doc-update-detection/installation-and-operation/running-metabase-on-podman.md new file mode 100644 index 000000000..990773704 --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/running-metabase-on-podman.md @@ -0,0 +1,166 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Running Metabase on Podman' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/running-metabase-on-podman.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/running-metabase-on-podman +--- + +# Running Metabase on Podman + +Our official Metabase Docker image is compatible on any system that is running [Podman](https://podman.io). + +## Open Source quick start + +Assuming you have [Podman](https://podman.io) installed and running, get the latest container image: + +``` +podman pull docker.io/metabase/metabase:latest +``` + +Then start the Metabase container: + +``` +podman run -d -p 3000:3000 --name=metabase docker.io/metabase/metabase:latest +``` + +This will launch an Metabase server on port 3000 by default. + +Optional: to view the logs as your Open Source Metabase initializes, run: + +``` +podman logs -f metabase +``` + +Once startup completes, you can access your Open Source Metabase at `http://localhost:3000`. + +To run your Open Source Metabase on a different port, say port 12345: + +``` +podman run -d -p 12345:3000 --name=metabase docker.io/metabase/metabase:latest +``` + +## Pro or Enterprise quick start + +Use this quick start if you have a [license token](../installation-and-operation/activating-the-enterprise-edition) for a [Pro or Enterprise version](/pricing/) of Metabase, and you want to run Metabase locally. + +Assuming you have [Podman](https://podman.io) installed and running, get the latest container image: + +``` +podman pull docker.io/metabase/metabase-enterprise:latest +``` + +Then start the Metabase container: + +``` +podman run -d -p 3000:3000 --name=metabase docker.io/metabase/metabase-enterprise:latest +``` + +This will launch a Metabase server on port 3000 by default. + +Optional: to view the logs as Metabase initializes, run: + +``` +podman logs -f metabase +``` + +Once startup completes, you can access your Pro or Enterprise Metabase at `http://localhost:3000`. + +To run your Pro or Enterprise Metabase on a different port, say port 12345: + +``` +podman run -d -p 12345:3000 --name=metabase docker.io/metabase/metabase-enterprise:latest +``` + +## Production installation + +Metabase ships with an embedded H2 database that uses the file system to store its own application data. Meaning, if you remove the container, you'll lose your Metabase application data (your questions, dashboards, collections, and so on). + +If you want to run Metabase in production, you'll need store your application data in a [production-ready database](./migrating-from-h2#supported-databases-for-storing-your-metabase-application-data). + +Once you've provisioned a database, like Postgres, for Metabase to use to store its application data, all you need to do is provide Metabase with the connection information and credentials so Metabase can connect to it. + +### Running Podman in production + +Let's say you set up a Postgres database by running: + +``` +createdb metabaseappdb +``` + +No need to add any tables; Metabase will create those on startup. And let's assume that database is accessible via `my-database-host:5432` with username `name` and password `password`. + +Here's an example Podman command that tells Metabase to use that database: + +``` +podman run -d -p 3000:3000 \ + -e "MB_DB_TYPE=postgres" \ + -e "MB_DB_DBNAME=metabaseappdb" \ + -e "MB_DB_PORT=5432" \ + -e "MB_DB_USER=name" \ + -e "MB_DB_PASS=password" \ + -e "MB_DB_HOST=my-database-host" \ + --name metabase metabase/metabase +``` + +Keep in mind that Metabase will be connecting from _within_ your Podman container, so make sure that either: a) you're using a fully qualified hostname, or b) that you've set a proper entry in your container's `/etc/hosts file`. + +## Migrating to a production installation + +If you've already been running Metabase with the default application database (H2), and want to use a production-ready application database without losing your app data (your questions, dashboards, etc), see [Migrating from H2 to a production database](migrating-from-h2). + +## Additional Podman maintenance and configuration + +- [Running Metabase as a service](#running-metabase-as-a-service) +- [Customizing the Metabase Jetty server](#customizing-the-metabase-jetty-server) +- [Setting the Java Timezone](#setting-the-java-timezone) +- [Troubleshooting](#troubleshooting) +- [Continue to setup](#continue-to-setup) + +### Running Metabase as a service + +We can use the [systemd](https://systemd.io/) initialization service to register a Metabase service that can be started and stopped automatically. Prior to executing this process, ensure that the Metabase container is operational. Then, utilize Podman's built-in feature to generate the service file as follows: + +``` +sudo podman generate systemd --new --name metabase > metabase.service +``` + +Before executing the service, inspect the contents of the `metabase.service` file to verify that all the accurate configurations are present. Once confirmed, locate the service file to the appropriate location by running the command: + +``` +sudo mv metabase.service /etc/systemd/system +``` + +To enable the automatic initiation of the Metabase service during system boot, execute: + +``` +sudo systemctl enable metabase +``` + +To verify that the system functions correctly, reboot the system. Upon completion of the system initialization process, the Metabase container should be operational as intended. + +### Customizing the Metabase Jetty server + +You can use any of the custom settings from [Customizing the Metabase Jetty Webserver](../configuring-metabase/customizing-jetty-webserver) by setting environment variables in your Podman run command. + +### Setting the Java Timezone + +It's best to set your Java timezone to match the timezone you'd like all your reports to come in. You can do this by simply specifying the `JAVA_TIMEZONE` environment variable which is picked up by the Metabase launch script. For example: + +``` +podman run -d -p 3000:3000 \ + -e "JAVA_TIMEZONE=US/Pacific" \ + --name metabase metabase/metabase +``` + +## Troubleshooting + +See Running Metabase in the [Troubleshooting guide](../troubleshooting-guide/running). + +## Continue to setup + +Now that you’ve installed Metabase, it’s time to [set it up and connect it to your database](../configuring-metabase/setting-up-metabase). diff --git a/_docs/doc-update-detection/installation-and-operation/running-the-metabase-jar-file.md b/_docs/doc-update-detection/installation-and-operation/running-the-metabase-jar-file.md new file mode 100644 index 000000000..f0357d8ea --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/running-the-metabase-jar-file.md @@ -0,0 +1,174 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Running the Metabase JAR file' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/running-the-metabase-jar-file.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/running-the-metabase-jar-file + - /docs/installation-and-operation/java-versions +--- + +# Running the Metabase OSS JAR file + +> We recommend running Metabase on [Metabase Cloud](/cloud/). If you need to self-host, you _can_ run Metabase as a standalone JAR, but [we recommend running Metabase in a Docker container](./running-metabase-on-docker). + +To run the free, Open Source version of Metabase via a JAR file, you will need to have a Java Runtime Environment (JRE) installed on your system. + +If you have a token for the [Pro or Enterprise editions](/pricing/) of Metabase, see [Activating your Metabase commercial license](../installation-and-operation/activating-the-enterprise-edition). + +## Quick start + +> The quick start is intended for running Metabase locally. See below for instructions on [running Metabase in production](#production-installation). + +If you have Java installed: + +1. [Download the JAR file for Metabase OSS](/start/oss/jar). If you're on a [Pro](/product/pro) or [Enterprise](/product/enterprise) plan, download the [JAR for the Enterprise Edition](https://downloads.metabase.com/enterprise/latest/metabase.jar). +2. Create a new directory and move the Metabase JAR into it. +3. Change into your new Metabase directory and run the JAR. + +``` +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +Metabase will log its progress in the terminal as it starts up. Wait until you see "Metabase Initialization Complete" and visit `http://localhost:3000/setup`. + +If you are using a Pro or Enterprise version, be sure to [activate your license](../installation-and-operation/activating-the-enterprise-edition). + +## Local installation + +If you just want to try Metabase out, play around with Metabase, or just use Metabase on your local machine, Metabase ships with a default application database that you can use. **This setup is not meant for production**. If you intend to run Metabase for real at your organization, see [Production installation](#production-installation). + +The below instructions are the same as the quick start above, just with a little more context around each step. + +### 1. Install Java JRE + +You may already have Java installed. To check the version, open a terminal and run: + +``` +java -version +``` + +If Java isn't installed, you'll need to install Java before you can run Metabase. We recommend version 21 of JRE from [Eclipse Temurin](https://adoptium.net/) with HotSpot JVM. You can run Metabase wherever Java 21 runs. Earlier Java versions aren't supported. The particular processor architecture shouldn't matter (although we only test Metabase for x86 and ARM). + +### 2. Download Metabase + +Download the JAR file: + +- [Metabase OSS](/start/oss/jar) +- [Metabase Enterprise/Pro edition](https://downloads.metabase.com/enterprise/latest/metabase.jar) + +If you want to install the [Pro or Enterprise editions](/pricing/) of Metabase, see [Activating your Metabase commercial license](../installation-and-operation/activating-the-enterprise-edition). + +### 3. Create a new directory and move the Metabase JAR into it + +When you run Metabase, Metabase will create some new files, so it's important to put the Metabase Jar file in a new directory before running it (so move it out of your downloads folder and put it a new directory). + +On posix systems, the commands would look something like this: + +Assuming you downloaded to `/Users/person/Downloads`: + +``` +mkdir ~/metabase +``` + +then + +``` +mv /Users/person/Downloads/metabase.jar ~/metabase +``` + +### 4. Change into your new Metabase directory and run the jar + +Change into the directory you created in step 2: + +``` +cd ~/metabase +``` + +Now that you have Java working you can run the JAR from a terminal with: + +``` +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +Metabase will start using the default settings. You should see some log entries starting to run in your terminal window showing you the application progress as it starts up. Once Metabase is fully started you'll see a confirmation such as: + +``` +... +06-19 10:29:34 INFO metabase.task :: Initializing task CheckForNewVersions +06-19 10:29:34 INFO metabase.task :: Initializing task SendAnonymousUsageStats +06-19 10:29:34 INFO metabase.task :: Initializing task SendAbandomentEmails +06-19 10:29:34 INFO metabase.task :: Initializing task SendPulses +06-19 10:29:34 INFO metabase.task :: Initializing task SendFollowUpEmails +06-19 10:29:34 INFO metabase.task :: Initializing task TaskHistoryCleanup +06-19 10:29:34 INFO metabase.core :: Metabase Initialization COMPLETE +``` + +At this point you're ready to go! You can access your new Metabase server on port 3000, most likely at `http://localhost:3000`. + +You can use another port than 3000 by setting the `MB_JETTY_PORT` [environment variable](../configuring-metabase/environment-variables) before running the jar. + +If you are using a Pro or Enterprise version of Metabase, be sure to [activate your license](../installation-and-operation/activating-the-enterprise-edition). + +## Production installation + +The steps are similar to those steps above with two important differences: if you want to run Metabase in production, you'll want to: + +- Use a [production application database](#production-application-database) to store your Metabase application data. +- Run [Metabase as a service](#running-the-metabase-jar-as-a-service). + +If you'd prefer to use Docker, check out [running Metabase on Docker](running-metabase-on-docker). + +### Production application database + +Here are some [databases we support](migrating-from-h2#supported-databases-for-storing-your-metabase-application-data). + +For example, say you want to use [PostgreSQL](https://www.postgresql.org/). You would get a PostgreSQL service up and running and create an empty database: + +``` +createdb metabaseappdb +``` + +You can call your app db whatever you want. And there's no need to create any tables in that database; Metabase will do that for you. You'll just need to set environment variables for Metabase to use on startup so Metabase knows how to connect to this database. + +You'll create a directory for your Metabase like in the steps listed above for the [Local installation](#local-installation), but when it's time to run the `java --add-opens java.base/java.nio=ALL-UNNAMED -jar` command to start up the JAR, you'll prefix the command with some environment variables to tell Metabase how to connect to the `metabaseappdb` you created: + +``` +export MB_DB_TYPE=postgres +export MB_DB_DBNAME=metabaseappdb +export MB_DB_PORT=5432 +export MB_DB_USER=username +export MB_DB_PASS=password +export MB_DB_HOST=localhost +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +The above command would connect Metabase to your Postgres database, `metabaseappdb` via `localhost:5432` with the user account `username` and password `password`. If you're running Metabase as a service, you'll put these environment variables in a separate configuration file. + +### Running the Metabase JAR as a service + +If you need to run the JAR in production, you should run Metabase as a service. Running Metabase as a service will: + +- Make sure Metabase runs automatically (and stay running). +- Allow you to run Metabase with an unprivileged user (which is good for security). + +The exact instructions for how to run Metabase as a service will differ depending on your operating system. For an example of how to set up Metabase as a service, check out [Running Metabase on Debian](./running-metabase-on-debian). + +### Migrating to a production installation + +If you've been running Metabase with the default H2 application database and your team has already created questions, dashboards, collections and so on, you'll want to migrate that data to a production application database. And the sooner you do, the better. See [Migrating from the H2 database](migrating-from-h2). + +## Troubleshooting + +If you run into any problems during installation, check out our [troubleshooting page](../troubleshooting-guide/running). + +## Upgrading Metabase + +See [Upgrading Metabase](upgrading-metabase). + +## Setting up Metabase + +Now that you’ve installed Metabase, it’s time to [set it up and connect it to your database](../configuring-metabase/setting-up-metabase). diff --git a/_docs/doc-update-detection/installation-and-operation/serialization.md b/_docs/doc-update-detection/installation-and-operation/serialization.md new file mode 100644 index 000000000..600ec66fe --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/serialization.md @@ -0,0 +1,786 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: Serialization +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/serialization.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/serialization +--- + +# Serialization + +{% include plans-blockquote.html feature="Serialization" %} + +Once you really get rolling with Metabase, it's often the case that you'll have more than one Metabase instance spun up. You might have a couple of testing or development instances and a few production ones, or maybe you have a separate Metabase per office or region. + +To help you out in situations like this, Metabase has a serialization feature which lets you create an _export_ of the contents of a Metabase that can then be _imported_ into one or more Metabases. + +**Export** will serialize the contents of your source Metabase as YAML files. + +**Import** will read those exported YAML files and create or update items in the target Metabase based on the contents serialized in those YAML files. + +There are two ways to run these `export` and `import` commands: + +- [Using CLI commands](#serialization-with-cli-commands) +- [Through the API](#serialization-via-the-api). + +> We're interested in how we can improve serialization to suit your workflow. [Upvote an existing issue](https://github.com/metabase/metabase/issues?q=is%3Aissue+is%3Aopen+serialization+label%3AOperation%2FSerialization) to let us know it's important to you. If a relevant issue doesn't yet exist, please create one and tell us what you need. + +## Serialization use cases + +- **Staging environments**. Enable a staging-to-production workflow for important dashboards by exporting from a staging instance of Metabase and then importing them into your production instance(s). +- **Version control**. Check the exported files into version control and audit changes to them, as the YAML files contained within the export are pretty readable. +- **Duplicating assets to other Metabase instances**. Export the "template" data from a source Metabase and import them to one or more target instances. + +Check out our guides for: + +- [Running multiple environments](/learn/metabase-basics/administration/administration-and-operation//multi-env) +- [Setting up git-based workflow](/learn/metabase-basics/administration/administration-and-operation//git-based-workflow) + +> Serialization isn't intended for use cases like duplicating assets or swapping data sources _within_ the same Metabase instance. If you're using serialization for duplicating assets within the same instance, check out [How export works](#how-export-works), [How import works](#how-import-works), and the directions for your use case in [Other uses of serialization](#other-uses-of-serialization) + +## How export works + +- [What gets exported](#what-gets-exported) +- [General Metabase settings that get exported](#general-metabase-settings-that-are-exported) +- [Customize what gets exported](#customize-what-gets-exported) +- [Example of a serialized question](#example-of-a-serialized-question) +- [Metabase uses Entity IDs to identify and reference items](#metabase-uses-entity-ids-to-identify-and-reference-metabase-items) + +### What gets exported + +Metabase will only export the following entities: + +- Collections (but personal collections don't get exported unless explicitly specified them through [export options](#customize-what-gets-exported)) +- Dashboards +- Saved questions +- Actions +- Models +- Metrics +- Snippets +- Data model and table metadata +- Segments +- Public sharing settings for questions and dashboards +- [General Metabase settings](#general-metabase-settings-that-are-exported) +- Events and timelines +- Database connection strings (only if specified through [export options](#customize-what-gets-exported)). + +All other entities—including users, groups, permissions, alerts, subscriptions—won't get exported. + +Metabase will export its artifacts to a directory of YAML files. The export includes: + +- Directories that contain YAML files for various Metabase entities. + An example export could include the following directories, depending on what you exported and the contents of your Metabase: + + - actions + - collections + - cards + - dashboards + - timelines + - databases + + When serializing through the API, the export directory [will be a compressed into a .tar.gz file](#you-must-compress-your-files-when-serializing-via-api-calls). + +- A `settings.yaml` file that includes some [Metabase-wide settings](#general-metabase-settings-that-are-exported) + +Database connection details are not included by default, so you but you can [configure your export](#customize-what-gets-exported) to include them. + +### General Metabase settings that are exported + +Here's the list of the general settings Metabase exports in the `settings.yaml` file. For more on Metabase settings, see [Configuring Metabase](../configuring-metabase/start). + +``` +humanization-strategy +native-query-autocomplete-match-style +site-locale +report-timezone-short +report-timezone-long +application-name +enable-xrays +show-homepage-pin-message +source-address-header +enable-nested-queries +custom-geojson-enabled +start-of-week +custom-geojson +available-timezones +unaggregated-query-row-limit +aggregated-query-row-limit +hide-embed-branding? +search-typeahead-enabled +enable-sandboxes? +application-font +available-locales +landing-page +enable-embedding +application-colors +application-logo-url +application-favicon-url +show-homepage-xrays +show-metabot +enable-whitelabeling? +show-homepage-data +site-name +application-font-files +loading-message +report-timezone +persisted-models-enabled +enable-content-management? +subscription-allowed-domains +breakout-bins-num +available-fonts +custom-formatting +``` + +### Customize what gets exported + +You can customize what gets exported. You can tell Metabase: + +- Export specific collections +- Do not export collections +- Do not export Metabase settings +- Do not export table metadata +- Include sample field values (excluded by default) +- Include database connection details (excluded by default) + +See [export parameters in CLI commands](#export-options) or [export parameters in API calls](#api-export-parameters). + +### Example of a serialized question + +Questions can be found in the `cards` directory of a collection directory. Here's an example card YAML file for a question written with SQL that uses a field filter and has an area chart visualization. + +> To preserve a native query's multi-line format, remove trailing whitespace from native queries. If your native query has trailing whitespace, YAML will convert your query to a single string literal (which only affects presentation, not functionality). + +```yml +name: Products by week +description: Area chart of products created by week +entity_id: r6vC_vLmo9zG6_r9sAuYG +created_at: "2024-05-08T19:10:24.348808Z" +creator_id: admin@metabase.local +display: area +archived: false +collection_id: onou5H28Wvy3kWnjxxdKQ +collection_preview: true +collection_position: null +query_type: native +dataset: false +cache_ttl: null +database_id: Sample Database +table_id: null +enable_embedding: false +embedding_params: null +made_public_by_id: null +public_uuid: null +parameters: + - default: + - Gizmo + id: c37d2f38-05fa-48c4-a208-19d9dba803c6 + name: Pick a category + slug: category_filter + target: + - dimension + - - template-tag + - category_filter + type: string/= +parameter_mappings: [] +dataset_query: + database: Sample Database + native: + query: |- + SELECT + category, + date_trunc ('week', created_at) AS "Week", + count(*) AS "Count" + FROM + products + WHERE + {{category_filter}} + GROUP BY + category, + "Week" + template-tags: + category_filter: + default: + - Gizmo + dimension: + - field + - - Sample Database + - PUBLIC + - PRODUCTS + - CATEGORY + - base-type: type/Text + display-name: Pick a category + id: c37d2f38-05fa-48c4-a208-19d9dba803c6 + name: category_filter + type: dimension + widget-type: string/= + type: native +result_metadata: + - base_type: type/Text + display_name: CATEGORY + effective_type: type/Text + field_ref: + - field + - CATEGORY + - base-type: type/Text + name: CATEGORY + semantic_type: null + - base_type: type/DateTime + display_name: Week + effective_type: type/DateTime + field_ref: + - field + - Week + - base-type: type/DateTime + name: Week + semantic_type: null + - base_type: type/BigInteger + display_name: Count + effective_type: type/BigInteger + field_ref: + - field + - Count + - base-type: type/BigInteger + name: Count + semantic_type: type/Quantity +visualization_settings: + column_settings: null + graph.dimensions: + - Week + - CATEGORY + graph.metrics: + - Count +serdes/meta: + - id: r6vC_vLmo9zG6_r9sAuYG + label: products_created_by_week + model: Card +initially_published_at: null +metabase_version: v1.49.7 (f0ff786) +type: question +``` + +### Metabase uses Entity IDs to identify and reference Metabase items + +Metabase assigns a unique Entity ID to every Metabase item (a dashboard, question, model, collection, etc.). These Entity IDs are in addition to the sequential IDs Metabase generates. Entity IDs use the [NanoID format](https://github.com/ai/nanoid), and are stable across Metabases. By "stable" we mean that you can, for example, export a dashboard with an entity ID from one Metabase, and import that dashboard into another Metabase and have that dashboard use the same Entity ID, even though it's in a different Metabase. + +To get an item's Entity ID in Metabase: + +1. Visit the item in Metabase. +2. Click on the info button. +3. In the overview tab, copy the Entity ID. + +You can also see the Entity IDs of items in the exported YAML files in the `entity_id` field. For example, in the [Example of a serialized question](#example-of-a-serialized-question), you'll see the Entity ID of that question: + +```yaml +entity_id: r6vC_vLmo9zG6_r9sAuYG +``` + +This ID also appears in the `serdes/meta → id` field (these IDs must match): + +```yaml +serdes/meta: + - id: r6vC_vLmo9zG6_r9sAuYG +``` + +To disambiguate entities that share the same name, Metabase includes Entity IDs in the file and directory names for exported entities. + +``` +r6vC_vLmo9zG6_r9sAuYG_products_by_week.yaml +IA96oUzmUbYfNFl0GzhRj_accounts_model.yaml +KUEGiWvoBFEc5oGQCEnPg_converted_customers.yaml +``` + +For example, in the [Example of a serialized question](#example-of-a-serialized-question) above, you can see the field `collection_id`: + +```yaml +collection_id: onou5H28Wvy3kWnjxxdKQ +``` + +This ID refers to the collection where the question was saved. In a real export, you'd be able to find a YAML file for this collection whose name starts with its ID: `onou5H28Wvy3kWnjxxdKQ`. + +### Entity IDs work with embedding + +Metabase supports working with [Entity IDs](#metabase-uses-entity-ids-to-identify-and-reference-metabase-items) for questions, dashboards, and collections in [Static Embedding](../embedding/static-embedding), [Interactive embedding](../embedding/interactive-embedding), and the [Embedded Analytics SDK](../embedding/sdk/introduction). + +A high-level workflow for using Entity IDs when embedding Metabase in your app would look something like: + +1. Create a dashboard in a Metabase running locally on your machine. +2. Embed the dashboard in your app locally using the Entity ID in your application code. +3. Export your Metabase changes to YAML files via serialization. +4. Import your Metabase changes (the exported YAML files) to your production Metabase. +5. Since the Entity ID remains the same in the production Metabase, you can just push the code in your app to production, and the code will refer to the right dashboard. + +### Databases, schemas, tables, and fields are identified by name + +By default, Metabase exports some database and data model settings. Exports exclude database connection strings by default. You can [explicitly include database connection strings](#customize-what-gets-exported). You can also choose to exclude the data model entirely. + +Metabase serializes databases and tables in the `databases` directory. It will include YAML files for every database, table, field, segment, and metric. + +Databases, tables, and fields are referred to by their names (unlike Metabase-specific items, which are [referred to by Entity IDs](#metabase-uses-entity-ids-to-identify-and-reference-metabase-items)). + +For example, in the [Example of a serialized question](#example-of-a-serialized-question), there are several YAML keys that reference Sample Database: + +```yaml +database_id: Sample Database +--- +dataset_query: + database: Sample Database +``` + +In the description of the field filter (`category_filter:`) in that example, you can see the reference to the field that's used to populate the filter options: + +```yaml +dimension: + - field + - - Sample Database + - PUBLIC + - PRODUCTS + - CATEGORY +``` + +It refers to the `CATEGORY` field in the `PRODUCTS` table in the `PUBLIC` schema in `Sample Database`. The serialized `Sample Database` in the `databases` directory will also include YAML files for this field and table. + +## How import works + +During import, Metabase will read the provided YAML files and create items according to the YAML specs. [Example of a serialized question](#example-of-a-serialized-question) how Metabase records information it needs to reconstruct an item. + +Metabase will not delete items from target instance during import, but it will overwrite items that already exist. + +Metabase relies on [Entity IDs](#metabase-uses-entity-ids-to-identify-and-reference-metabase-items) to figure out which items to create or overwrite, and what are the relationships between items. When importing into an instance that already has some content in it, keep in mind: + +- If you import an item with an `entity_id` that doesn't exist in your target Metabase, Metabase will create a new item. + +- If you import an item with an `entity_id` that already exists in your target Metabase, the existing item will be overwritten. + + In particular, this means that if you export a question, then make a change in an exported YAML file — like rename a question by directly editing the `name` field — and then import the edited file back, Metabase will try to apply the changes you made to the YAML. + +- If you import an item with a blank `entity_id`, Metabase will create a new item. Any `serdes/meta → id` will be ignored in this case. + +- All items and data sources referenced in YAML must either exist in the target Metabase already, or be included in the import. + + For example, if an exported YAML has the field `collection_id: onou5H28Wvy3kWnjxxdKQ`, then the collection `onou5H28Wvy3kWnjxxdKQ` must already exist in target instance, or there must be a YAML file with the export of a collection that has this ID. + +## Serialization best practices + +### Use the same Metabase version for source and target instance + +Currently, serialization only works if source and target Metabase have the same major version. +If you are using the CLI serialization commands, the version of the .jar file that you are using to run the serialization commands should match both the source and target Metabase versions as well. + +### If you're using H2 as your application database, you'll need to stop Metabase before importing or exporting + +If you're using Postgres or MySQL as your application database, you can import and export while your Metabase is still running. + +### Avoid using serialization for backups + +Just a note: serialization is _not_ meant to back up your Metabase. + +See [Backing up Metabase](./backing-up-metabase-application-data). + +If you're instead looking to do a one-time migration from the default H2 database included with Metabase to a MySQL/Postgres, then use the [migration guide instead](./migrating-from-h2). + +### You'll need to manually add license tokens + +Metabase excludes your license token from exports, so if you're running multiple environments of Metabase Enterprise Edition, you'll need to manually add your license token to the target Metabase(s), either via the [Metabase user interface](/docs/latest/paid-features/activating-the-enterprise-edition), or via an [environment variable](../configuring-metabase/environment-variables#mb_premium_embedding_token). + +### Metabase adds logs to exports and imports + +Exports: Metabase adds logs to the compressed directory as `export.log`. + +Imports: You can add the `-o -` flag to export logs directly into the terminal, or `-o import.log` to save to a file. + +## Serialization with CLI commands + +> To serialize data on Metabase Cloud, use the [import and export API endpoints](#serialization-via-the-api) + +Metabase provides [`export`](#exporting-with-cli) and [`import`](#importing-with-cli) CLI commands. + +See [How export works](#how-export-works), [How import works](#how-import-works), and [Serialization best practices](#serialization-best-practices) for general information about serialization. + +### Exporting with CLI + +To export the contents of a Metabase instance, change into the directory where you're running the Metabase JAR and run: + +``` +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar export dir_name +``` + +Where `dir_name` can be whatever you want to call the directory. + +### `export` options + +To view a list of `export` options, use the `help` command: + +``` +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar help export +``` + +Which will run and then print something like: + +``` +export path & options + Serialize Metabase instance into directory at `path`. + Options: + -c, --collection ID Export only specified ID; may occur multiple times. + -C, --no-collections Do not export any content in collections. + -S, --no-settings Do not export settings.yaml + -D, --no-data-model Do not export any data model entities; useful for subsequent exports. + -f, --include-field-values Include field values along with field metadata. + -s, --include-database-secrets Include database connection details (in plain text; use caution). +``` + +#### `--collection` + +By default, Metabase will include all collections (except for personal collections) in the export. To include personal collections, you must explicitly add them with the `--collection` flag. + +The `--collection` flag (alias `-c`) lets you specify by ID one or more collections to include in the export. You can find the collection ID in the collection's URL, e.g., for a collection at: `your-metabase.com/collection/42-terraforming-progress`, the ID would be `42`. + +If you want to specify multiple collections, separate the IDs with commas. E.g., + +``` +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar export export_name --collection 1,2,3 +``` + +#### `--no-collections` + +The `--no-collections` flag (alias `-C`) tells Metabase to exclude all collections from the export. + +#### `--no-settings` + +The `--no-settings` flag (alias `-S`) tells Metabase to exclude the `settings.yaml` file that includes [site-wide settings](#general-metabase-settings-that-are-exported), which is exported by default. + +#### `--no-data-model` + +The `--no-data-model` flag (alias `-D`) tells Metabase to exclude the Table Metadata settings from the export. Admins define the metadata settings in the [Table Metadata](../data-modeling/metadata-editing) tab of the Admin settings. + +#### `--include-field-values` + +The `--include-field-values` flag (alias `-f`) tells Metabase to include the sample values for field values, which Metabase uses to present dropdown menus. By default, Metabase excludes these sample field values. + +#### `--include-database-secrets` + +The `--include-database-secrets` flag (alias `-s`) tells Metabase to include connection details, including the database user name and password. By default, Metabase excludes these database connection secrets. If you don't use this flag, you'll need to manually input the credentials in the target Metabase. + +### Importing with CLI + +To import exported artifacts into a Metabase instance, go to the directory where you're running your target Metabase (the Metabase you want to import into) and use the following command, where `path_to_export` is the path to the export that you want to import: + +``` +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar import path_to_export +``` + +Currently, you can only import exported artifacts into a Metabase instance that was created from the same version of Metabase. + +### `import` options + +Most options are defined when exporting data from a Metabase. To view a list of import flags, run: + +``` +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar help import +``` + +Which prints out: + +``` +import path & options + Load serialized Metabase instance as created by the [[export]] command from directory `path`. +``` + +## Serialization via the API + +> Just like the CLI serialization commands, these endpoints are only available for [Pro](/product/pro) and [Enterprise](/product/enterprise) plans. + +You can import and export serialized Metabase data via Metabase's API, which makes serialization possible for [Metabase Cloud](/cloud/) deployments. + +There are two endpoints: + +- `POST /api/ee/serialization/export` +- `POST /api/ee/serialization/import` + +> We use `POST`, not `GET`, for the `/export` endpoint. The export operation does not modify your Metabase, but it's long and intensive, so we use `POST` to prevent accidental exports. + +For now, these endpoints are synchronous. If the serialization process takes too long, the request can time out. In this case, we suggest using the CLI commands. + +See [How export works](#how-export-works), [How import works](#how-import-works), and [Serialization best practices](#serialization-best-practices) for general information about serialization. + +### API export parameters + +You can append optional parameters to tell Metabase what to include or exclude from the export. You can also combine parameters (excluding, of course, `all_collections` and selective collections). + +So, assuming you're testing on `localhost`, and you want to exclude all collections from the export, you'd format the URL like so: + +``` +http://localhost:3000/api/ee/serialization/export?all_collections=false +``` + +You can include multiple parameters, separated by `&`. For example, to exclude both the settings and the data model from the export: + +``` +http://localhost:3000/api/ee/serialization/export?data_model=false&settings=false +``` + +### `collection` + +Type: Array of integers. + +Default value: Metabase will export all collections, unless `all_collections` is set to `false`. + +To select which collections to export, include the collection IDs. For example, to include collections `1` and `2`: + +```html +collection=1&collection=2 +``` + +### `all_collections` + +Type: Boolean + +Default: `true` (unless you specify a subset of collections with `collection`). + +To exclude all collections: + +```html +all_collections=false +``` + +### `settings` + +Type: Boolean. + +Default: `true`. + +To exclude the `settings.yaml` file that contains site-wide settings: + +```html +settings=false +``` + +### `data_model` + +Type: Boolean. + +Default: `true`. + +To exclude the [Table Metadata](../data-modeling/metadata-editing): + +``` +data_model=false +``` + +### `field_values` + +Type: Boolean. + +Default: `false`. + +To include the sample values for field values, which Metabase uses to present dropdown menus: + +``` +field_values=true +``` + +### `database_secrets` + +Type: Boolean. + +Default: `false`. + +To include database connection details, like the database username and password: + +```html +database_secrets=true +``` + +### `dirname` + +Type: String. + +Default: `-` + +To specify a different directory: + +``` +dirname=name_of_your_directory +``` + +### You must compress your files when serializing via API calls + +To keep file sizes over the network under control, both the `export` and `import` endpoints expect GZIP-compressed Tar files (`.tgz`). + +#### Compress a directory + +To compress a directory (e.g., a directory named `metabase_data`). + +```sh +tar -czf metabase_data.tgz metabase_data +``` + +#### Extract a directory + +To extract/unzip a directory: + +```sh +tar -xvf metabase_data.tgz +``` + +## Serialization API example + +### Step 1: Set up an API key + +1. Create an [API key](../people-and-groups/api-keys). +2. Assign the key to the Admin group + +### Step 2: Export + +1. Send a `curl` request to export data: + +```sh +curl \ + -H 'x-api-key: YOUR_API_KEY' \ + -X POST 'http://your-metabase-url/api/ee/serialization/export' \ + -o metabase_data.tgz +``` + +substituting `YOUR_API_KEY` with your API key and `your-metabase-url` with the URL of your Metabase instance. + +> We use `POST`, not `GET`, for the `/export` endpoint. + +This command will download the files as a GZIP-compressed Tar file named `metabase_data.tgz`. + +2. Unzip the compressed file: + +```sh +tar -xvf metabase_data.tgz +``` + +The extracted directory will be called something like `metabase-yyyy-MM-dd_HH-mm`, with the date and time of the export. + +### Step 3: Import + +1. Compress the directory containing serialized Metabase application data + +Let's say you have your YAML files with Metabase application data in a directory called `metabase_data`. Before importing those files to your target Metabase, you'll need to compress those files. + +```sh +tar -czf metabase_data.tgz metabase_data +``` + +3. POST to `/api/ee/serialization/import`. + +From the directory where you've stored your GZIP-compressed file, run: + +```sh +curl -X POST \ + -H 'x-api-key: YOUR_API_KEY' \ + -F file=@metabase_data.tgz \ + 'http://your-metabase-url/api/ee/serialization/import' \ + -o - +``` + +substituting `YOUR_API_KEY` with your API key and `your-metabase-url` with your Metabase instance URL. +The `-o -` option will output logs in the terminal. + +> If you import Metabase data into the same Metabase as you exported it from, you will overwrite your existing questions, dashboards, etc. See [How import works](#how-import-works). + +## Other uses of serialization + +Serialization is intended for version control, staging-to-production workflows, and duplicating assets to other Metabase instances. While it's possible to use serialization for other use cases (like duplicating assets _within_ a single instance), we don't officially support these use cases. + +We're providing some directions on how to approach these unsupported use cases, but you should use them at your own risk. We strongly recommend that you test any process involving serialization on a non-production instance first, and reach out to [help@metabase.com](mailto:help@metabase.com) if you have any questions. + +### Using serialization for duplicating content within the same Metabase + +Using serialization to duplicate content is not trivial, because you'll need to wrangle [Entity IDs](#metabase-uses-entity-ids-to-identify-and-reference-metabase-items) for all the items you want to duplicate — and the IDs for all the items that are related to those items — to avoid overwriting existing data. + +Before starting this perilous journey, review [how export works](#how-export-works) and [how import works](#how-import-works), and contact [help@metabase.com](mailto:help@metabase.com) if you have any questions. + +You'll need to keep in mind: + +- Importing an item with an Entity ID that already exists will overwrite the existing item. To use an existing YAML file to create a new item, you'll need to either a) create a new Entity ID or b) clear the Entity ID. +- Two items cannot have the same Entity IDs. +- `entity_id` and `serdes/meta → id` fields in the YAML file should match. +- If the `entity_id` and `serdes/meta → id` fields in a YAML file for an item are blank, Metabase will create a new item with a new Entity ID. +- All items and data sources referenced by an item should either already exist in target Metabase or be included in the import. + + For example, a collection can contain a dashboard that contains a question that is built on a model that references a data source. All of those dependencies must be either included in the import or already exist in the target instance. + + This means that you might need a multi-stage export/import: create some of the items you need (like collections) in Metabase first, export them to get their Entity IDs, then export the stuff that you want to duplicate and use those IDs in items that reference them. + +For example, to duplicate a collection that contains _only_ questions that are built directly on raw data (not on models or other saved questions), without changing the data source for the questions, you can use a process like this: + +1. In Metabase, create a "template" collection and add the items you'd like to duplicate. +2. In Metabase, create a new collection which will serve as the target for duplicated items. +3. Export the template collection and the target collection (you can use [export parameters](#customize-what-gets-exported) to export only a few collections). + The YAML files for template questions in the export will have their own Entity IDs and reference the Entity ID of the template collection. +4. Get the Entity ID of the target collection from its export. +5. In the YAML files for questions in the template collection export: + + - Clear the values for the fields `entity_id` and `serdes/meta → id` for questions. This will ensure that the template questions don't get overwritten, and instead Metabase will create new questions. + - Replace `collection_id` references to the template collection with the ID of the new collection + +6. Import the edited files. + +This process assumes that your duplicated questions will all use the same data source. You can combine this with [switching the data source](#using-serialization-to-swap-the-data-source-for-questions-within-one-instance) to use a different data source for every duplicated collection. + +If you want to create multiple copies of a collection at once, then instead of repeating this process for every copy, you could create your own target Entity IDs (they can be any string that uses the [NanoID format](https://github.com/ai/nanoid)), duplicate all the template YAML files, and replace template Entity IDs and any references to them with your created Entity IDs. + +If your collections contains dashboards, models, and other items that can add dependencies, this process can become even more complicated -- you need to handle every dependency. We strongly recommend that you first test your serialization on a non-production Metabase, and reach out to [help@metabase.com](mailto:help@metabase.com) if you need any help. + +### Using serialization to swap the data source for questions within one instance + +If you want to change the data source for some of the questions in your Metabase — for example, just for questions in a single collection - you can serialize the questions manually, then edit the exported YAML files. + +> If you want to switch _every_ question built on database A to use database B instead, and database B has exactly the same schema as database A, you don't need to use serialization: you can just swap the connection string in **Admin > Databases** + +Your databases must have the same engine, and ideally they should have the same schema. + +You'll need to keep in mind: + +- Databases, tables and fields are [referred to in Metabase by name](#databases-schemas-tables-and-fields-are-identified-by-name) +- Database connection details are not exported by default. To export database connection details, you'll need to [specify this in export parameters](#customize-what-gets-exported). +- Databases, tables and fields referenced by an item should either already exist in the target Metabase, or be included in the import. + +For example, if you want to switch all questions in the `Movie reviews` collection to use the `Romance` database instead of the `Horror` database, and _both databases have the same schema_, you could follow a process like this: + +1. In Metabase, add a new database connection in **Admin > Databases** and name it `Romance`. +2. Export the collection `Movie reviews`. + + You can tell Metabase to export a single collection, or you can export all the collections and just work with files in the folder for the `Movie reviews` collection + +3. In the YAML files for items from this collection, replace all references to `Horror` database with references to `Romance` +4. Import the edited files. + +Importing will overwrite the original questions. If you're looking to create new questions that use a different data source, you can combine this process with [Using serialization for duplicating assets](#using-serialization-for-duplicating-content-within-the-same-metabase). + +This process assumes that your new data source has exactly the same schema. If the schema is different, then you will also need to replace all references to all tables and fields. This process can be complicated and error-prone, so we strongly recommend that you test your serialization on a non-production instance first, and reach out to [help@metabase.com](mailto:help@metabase.com) if you need any help. + +## Migrating from the old serialization commands + +If you're upgrading from Metabase version 46.X or older, here's what you need to know: + +- The `export` command replaces the `dump` command. +- The `import` command replace the `load` command. + +A few other changes to call out: + +- The exported YAML files have a slightly different structure: + - Metabase will prefix each file with a 24-character Entity ID (like `IA96oUzmUbYfNFl0GzhRj_accounts_model.yaml`). + You can run a Metabase command to [drop Entity IDs](./commands#drop-entity-ids) before exporting. + - The file tree is slightly different. +- To serialize personal collections, you just need to include the personal collection IDs in the list of comma-separated IDs following the `-c` option (short for `--collection`). + +If you've written scripts to automate serialization, you'll need to: + +- Reserialize your Metabase using the upgraded Metabase (which uses the new `export` and `import` commands). Note that serialization will only work if you export and import your Metabase using the same Metabase version. +- Update those scripts with the new commands. See the new [export options](#export-options). +- If your scripts do any post-processing of the exported YAML files, you may need to update your scripts to accommodate the slightly different directory and YAML file structures. + +## Further reading + +- [Serialization tutorial](/learn/metabase-basics/administration/administration-and-operation//serialization). +- [Multiple environments](/learn/metabase-basics/administration/administration-and-operation//multi-env) +- [Setting up a git-based workflow](/learn/metabase-basics/administration/administration-and-operation//git-based-workflow). +- Need help? Contact [support@metabase.com](mailto:support@metabase.com). diff --git a/_docs/doc-update-detection/installation-and-operation/start.md b/_docs/doc-update-detection/installation-and-operation/start.md new file mode 100644 index 000000000..447e576df --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/start.md @@ -0,0 +1,65 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: 'Installation and Operation' +title: 'Installation and operation overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/start.md' +--- + +# Installation and operation overview + +The birth, care, and feeding of your Metabase. + +## [Installing Metabase](./installing-metabase) + +Options for installing Metabase. + +## [Migrating to a production database](./migrating-from-h2) + +If you started using Metabase with the default, H2 application database, here's how to migrate your data to a production-ready database. + +## [Configuring the Metabase application database](./configuring-application-database) + +Use environment variables to set up your application database. + +## [Backing up Metabase application data](./backing-up-metabase-application-data) + +How to back up your Metabase data: questions, dashboards, and other application data. + +## [Upgrading Metabase](upgrading-metabase) + +How to safely upgrade your Metabase. + +## [Serialization](./serialization) + +Export your questions, dashboards, and more as YAML files that you can check into version control. + +## [Monitoring your Metabase](./monitoring-metabase) + +Monitor your Metabase with JMX. + +## [Observability with Prometheus](./observability-with-prometheus) + +Export Metabase metrics for viewing with Prometheus. + +## [Supported browsers](./supported-browsers) + +Rest in peace, Internet Explorer. + +## [About the anonymous usage data we collect](./information-collection). + +We collect anonymous Metabase usage data to improve the product. We don't collect your data. + +## [Accessibility](./accessibility) + +Notes on Metabase's accessibility. + +## [Command line commands](./commands) + +Metabase's CLI. + +--- + +If you’d like more technical resources to set up your data stack with Metabase, connect with a [Metabase Expert](/partners/). diff --git a/_docs/doc-update-detection/installation-and-operation/supported-browsers.md b/_docs/doc-update-detection/installation-and-operation/supported-browsers.md new file mode 100644 index 000000000..936304b8a --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/supported-browsers.md @@ -0,0 +1,24 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Supported browsers' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/supported-browsers.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/supported-browsers +--- + +# Supported browsers + +We try our best to make sure Metabase works in as many browsers as possible, but as this is the Internet, there may be little quirks from time to time in different settings. We believe Metabase works on these versions of these browsers and will attempt to fix specific bugs if any are found: + +- Chrome (v70+) +- Firefox (v68+) +- Microsoft Edge (v17+) +- Safari (v11+) + +Metabase may run perfectly well on older versions of these browsers or on specific browsers not listed above, but your mileage may vary. In particular, we ended support for IE11 in Metabase 0.40: it mostly still works, but you may see some unexpected behavior. + +We recommend you use the most up-to-date browser you can. diff --git a/_docs/doc-update-detection/installation-and-operation/upgrading-metabase.md b/_docs/doc-update-detection/installation-and-operation/upgrading-metabase.md new file mode 100644 index 000000000..7af6b5790 --- /dev/null +++ b/_docs/doc-update-detection/installation-and-operation/upgrading-metabase.md @@ -0,0 +1,186 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Installation and Operation' +title: 'Upgrading Metabase' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/installation-and-operation/upgrading-metabase.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/upgrading-metabase +--- + +# Upgrading Metabase + +Instructions for upgrading to a new [Metabase release](https://github.com/metabase/metabase/releases). + +## Backing up your application database + +The application database keeps track of all of your people, dashboards, questions, collections, permissions: all the application data in Metabase (that is, everything but the data you've connected to Metabase). While it's unlikely you'll need to roll back to your current version, a backup will do wonders for your peace of mind. + +See [Backing up Metabase application data](backing-up-metabase-application-data). + +## Swapping in the new Metabase version + +Steps differ depending on whether you're running the JAR or a Docker image. + +### Upgrading a JAR running locally + +If you're running the JVM Jar file directly: + +1. [Back up your application database](backing-up-metabase-application-data). + +2. Download the latest version of the JAR file: + + - [Metabase Open Source JAR](/start/oss/jar) + - [Metabase Pro or Enterprise JAR](https://downloads.metabase.com/enterprise/latest/metabase.jar) + +3. Use a terminal to access your existing Metabase process and kill it (usually CTRL-C). + +4. Replace the existing JAR file (`metabase.jar`) in your Metabase directory with the newer version. + +5. Restart the server: + + ``` + java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar + ``` + +On startup, Metabase will perform any tasks it needs to complete the upgrade. Once Metabase has completed those tasks, you'll be running the new version. + +### Upgrading a JAR running in production as a service + +To upgrade, you'll need to stop the service, replace the JAR with the newer version, and restart the service. + +E.g., if you're running Metabase on Debian as a service using Nginx. + +1. [Back up your application database](backing-up-metabase-application-data). + +2. Download the latest version of the JAR file: + + - [Metabase Open Source JAR](/start/oss/jar) + - [Metabase Pro or Enterprise JAR](https://downloads.metabase.com/enterprise/latest/metabase.jar) + +3. Stop the Metabase service. Aassuming you called your service `metabase.service`), you'll run: + + ``` + sudo systemctl stop metabase.service + ``` + +4. In your Metabase directory on your server, replace the current (older) Metabase JAR file with the newer JAR you downloaded. + +5. Restart the service: + + ``` + sudo systemctl restart metabase.service + ``` + +### Upgrading the Docker image + +If you're running Metabase in a Docker container: + +1. [Back up your application database](backing-up-metabase-application-data). + + > WARNING: If you're not using a [production-ready database](migrating-from-h2), your application data (questions, dashboards, and so on) will have been stored in an H2 database _inside_ your container. Upgrading requires swapping out your existing container for a new image with the upgraded Metabase JAR, which will wipe out your application data. We recommend switching to a production-ready database before you upgrade. + +2. Stop the current Docker container. + +3. Pull the latest Metabase Docker image. + + Metabase Open Source: + + ``` + docker pull metabase/metabase:latest + ``` + + Metabase Pro or Enterprise: + + ``` + docker pull metabase/metabase-enterprise:latest + ``` + +4. Start the new Docker container. Depending on the ports and what you want to name the container, the command will look something like: + + Metabase Open Source: + + ``` + docker run -d -p 3000:3000 -e MB_DB_CONNECTION_URI="jdbc:postgresql://:5432/metabase?user=&password=" --name metabase metabase/metabase:latest + ``` + + Metabase Pro or Enterprise: + + ``` + docker run -d -p 3000:3000 -e MB_DB_CONNECTION_URI="jdbc:postgresql://:5432/metabase?user=&password=" --name metabase metabase/metabase-enterprise:latest + ``` + +On startup, Metabase will perform the upgrade automatically. Once Metabase has completed the upgrade, you'll be running the new version. + +## Upgrading from older versions of Metabase + +If you're on a Metabase version older than Metabase 40, you'll need to upgrade release by release until you're on the latest version of Metabase 40. From the latest version of Metabase 40, you can then jump to the current version of Metabase. + +For example, if you're running Metabase 1.38, your upgrade path would look like: + +- 1.38.X +- 1.39.X +- 1.40.X +- Latest + +With X being the latest version available for each release. + +Check out a list of [Metabase releases](https://github.com/metabase/metabase/releases). + +## Upgrading Metabase Cloud + +If you're on a [Metabase Cloud](/pricing/) plan, we'll upgrade your Metabase automatically with each new release; no action needed on your end. How soon we upgrade you depends on the type of release: + +- Minor releases (e.g., x.47.4 to x.47.5): Usually about a week. +- Major releases (e.g., x.47.4 to x.48.0): Longer, usually weeks (just to make sure everything goes smoothly). + +Cloud customers can request an early upgrade by emailing support at help@metabase.com. Include the URL of the Metabase you want us to upgrade. + +## Upgrading Metabase on other platforms + +- [Upgrading Azure Web Apps deployments](running-metabase-on-azure#additional-configurations) + +## Rolling back an upgrade + +In general, regular backups (especially backups before upgrading), are the best policy, so we recommend reverting to a backup of your application database to roll back an upgrade. + +But if you've made changes to your application database since upgrading that you want to keep, you may be able to use the `migrate down` command to roll back your Metabase application database to support the previous Metabase version you were running. When Metabase upgrades to a new version, it runs migrations that may change the application database schema. The `migrate down` command undoes those schema changes. In general, we recommend restoring from a backup (the backup that you definitely remembered to generate before upgrading), and only using the `migrate down` command if you really need to keep changes made after your upgrade. + +### Using the migrate down command + +Stop your Metabase and use the current, upgraded Metabase JAR (not the Metabase JAR you want to roll back to) to complete the rollback with the `migrate down` command. Make sure that the connection details for your application database are set in the environment variables, for example: + +``` +export MB_DB_TYPE=postgres +export MB_DB_DBNAME=metabaseappdb +export MB_DB_PORT=5432 +export MB_DB_USER=username +export MB_DB_PASS=password +export MB_DB_HOST=localhost +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar migrate down +``` + +If you're running Docker, use the command `"migrate down"` (with the quotes around `"migrate down"`), and include the connection details for your application database, for example: + +``` +docker run + -e "MB_DB_TYPE=postgres" \ + -e "MB_DB_DBNAME=metabaseappdb" \ + -e "MB_DB_PORT=5432" \ + -e "MB_DB_USER=name" \ + -e "MB_DB_PASS=password" \ + -e "MB_DB_HOST=my-database-host" \ +--rm metabase/metabase "migrate down" +``` + +If you're running Docker Compose with the right environments variables, the command would be: + +``` +docker compose run metabase "migrate down" +``` + +Note the quotes around `"migrate down"` for the Docker and Docker compose command. + +Once the migration process completes, start up Metabase using the JAR or Docker image for the version you want to run. diff --git a/_docs/doc-update-detection/people-and-groups/account-settings.md b/_docs/doc-update-detection/people-and-groups/account-settings.md new file mode 100644 index 000000000..2a58ec3b4 --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/account-settings.md @@ -0,0 +1,42 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'Account settings' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/account-settings.md' +redirect_from: + - /docs/doc-update-detection/users-guide/account-settings +--- + +# Account settings + +You can view your account settings by going to the top right of the screen and clicking on the **gear** icon > **Account settings**. + +## Account profile + +You can set your first and last names, change your email address, and set your language. See our list of [supported languages](../configuring-metabase/localization). + +## Account password + +You can change your password here. Note that if your Metabase uses Single Sign-On (SSO), your administrator will have disabled this password section, as your identity provider will manage logins. + +If you're having trouble logging in, see our [People can't log into Metabase](../troubleshooting-guide/cant-log-in). + +## Account login history + +The login history lists each login, along with some location information (if available), and some client information (like Browser (Firefox/Windows)). +If you see any suspicious login attempts, change your password and notify your administrator. + +### A note about new login emails + +Whenever you log in from a new device, Metabase will send you an email just to let you know someone (presumably you) has logged in from an unrecognized device. If you see this email, but don't remember logging in, or don't recognize the device, change your password and let your administrator know. + +## Disable animations in Metabase + +This isn't an in-Metabase setting, but just so you know: you can disable UI animations in Metabase (like sidebars sliding around, or rotating spinners) by changing the settings for your operating system so it respects the `prefers-reduced-motion` CSS media feature. This change will also affect other applications, not just Metabase. Check out the instructions for how to set the user preferences for your operating system in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion#user_preferences). + +## Notifications + +If you subscribe or are added to dashboard subscriptions or alerts, you’ll be able to manage those notifications here (as well as on the relevant question or dashboard themselves). diff --git a/_docs/doc-update-detection/people-and-groups/api-keys.md b/_docs/doc-update-detection/people-and-groups/api-keys.md new file mode 100644 index 000000000..bc22f11c2 --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/api-keys.md @@ -0,0 +1,125 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'API keys' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/api-keys.md' +--- + +# API keys + +Metabase can create API keys to authenticate programmatic requests to the API. To set the permissions for an API key, you can assign the key to a [group](./managing#groups). + +## Fair warning about Metabase's API + +We don't version the [Metabase API](../api). We rarely change API endpoints, and almost never remove them, but if you write code that relies on the API, there's a chance you might have to update your code in the future. + +That said, there are times when it's nice to work with the API, like when managing permissions with a large number of people and groups, or bulk archiving, or content creation. So we added the ability to create API keys to authenticate your programmatic requests. + +## Create an API key + +To create an API key: + +1. Click on the **gear** icon in the upper right. +2. Select **Admin settings**. +3. Go to the **Settings** tab. +4. Click on the **Authentication** tab on the left menu. +5. Scroll to **API Keys** and click **Manage**. +6. Click the **Create API Key** button. +7. Enter a **Key name**. You can have multiple API keys, so give it a name that will help you remember what you're using the key for. +8. Select a **[Group](./managing#groups)**. The key will have the same permissions granted to that group. +9. Click **Create**. +10. Copy the generated API key and save it somewhere safe. Metabase won't be able to show you the key again. If you lose the key, you'll need to regenerate a new key. + +### Creating API keys from the config file + +If you're on a [Pro or Enterprise self-hosted plan](/pricing/), you can [create API keys via the configuration file](../configuring-metabase/config-file#api-keys). + +## Managing API Keys + +To view and manage existing API keys: + +1. Click on the **gear** icon in the upper right. +2. Select **Admin settings**. +3. Go to the **Settings** tab. +4. Click on the **Authentication** tab on the left menu. +5. Scroll to **API Keys** and click **Manage**. + +### Editing API keys + +To edit an API key, scroll to the key you want to edit and click on the **pencil** icon. Metabase will pop up an **Edit API Key** modal where you can edit: + +- The key's name +- Which group the key belongs to. +- Change (regenerate) the key. Metabase will replace the existing API key with a new key. You won't be able to recover the old key. + +### Deleting API keys + +You won't be able to recover a deleted API key. You'll have to create a new key. + +To delete an API Key: + +1. Click on the **gear** icon in the upper right. +2. Select **Admin settings**. +3. Go to the **Settings** tab. +4. Click on the **Authentication** tab on the left menu. +5. Scroll to **API Keys** and click **Manage**. +6. Select the key you want to delete and click the **trash** icon. +7. Metabase will pop up a **Delete API Key** modal. Click the **Delete API Key** button. + +### Metabase will transfer API keys associated with a group that gets deleted to the All users group + +If you have API keys assigned to a group, but then someone deletes that group, the API keys will still work, but Metabase will reassign those keys to the All users group. If you want to change their group, you'll need to edit the keys manually. + +## Example `GET` requests + +Here are some example `GET` requests that return the groups in your Metabase. These examples assume you're running Metabase locally on the default port: 3000. + +### `curl` example + +Replace `YOUR_API_KEY` with the API key you generated above. + +```sh +curl \ +-H 'x-api-key: YOUR_API_KEY' \ +-X GET 'http://localhost:3000/api/permissions/group' +``` + +### JavaScript example + +Assuming you've set your key as an environment variable like so: + +```sh +export METABASE_API_KEY="YOUR_API_KEY" +``` + +Here's a basic `GET` request using `fetch` to get the list of groups. You can copy the code, save it as file (e.g., as `api-test.js`), and run the code with `node api-test.js`. + +```js +// Assuming you've set the key in process with +// `export METABASE_API_KEY="YOUR_KEY_HERE"` +const API_KEY = process.env.METABASE_API_KEY; + +const init = { + headers: { + "Content-Type": "application/json", + "X-API-KEY": API_KEY, + }, +}; + +const host = "http://127.0.0.1:3000"; + +async function getGroups() { + const response = await fetch(`${host}/api/permissions/group`, init); + return response.json(); +} + +getGroups().then(groups => console.log("Groups in your Metabase:", groups)); +``` + +## Further reading + +- [Metabase API reference](../api). +- [Working with the Metabase API](/learn/metabase-basics/administration/administration-and-operation/metabase-api). diff --git a/_docs/doc-update-detection/people-and-groups/authenticating-with-jwt.md b/_docs/doc-update-detection/people-and-groups/authenticating-with-jwt.md new file mode 100644 index 000000000..157465bbb --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/authenticating-with-jwt.md @@ -0,0 +1,107 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'JWT-based authentication' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/authenticating-with-jwt.md' +description: 'How to set up JWT-based authentication in Metabase to connect with your identity provider and manage user access.' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/authenticating-with-jwt +--- + +# JWT-based authentication + +{% include plans-blockquote.html feature="JWT-based authentication" %} + +You can connect Metabase to your identity provider using JSON Web Tokens (JWT) to authenticate people. + +## Typical flow for a JWT-based SSO interaction with Metabase + +Assuming your site is localhost serving on port 3000: + +1. Person attempts to view a question, e.g., `http://localhost:3000/question/1-superb-question`. +2. If the person isn't logged in, Metabase redirects them to `http://localhost:3000/auth/sso`. +3. Retaining the original `/question/1-superb-question` URI, Metabase redirects the person to the SSO provider (the authentication app). +4. Person logs in using the basic form. +5. In the event of a successful sign-in, your authentication app should issue a GET request to your Metabase endpoint with the token and the "return to" URI: `http://localhost:3000/auth/sso?jwt=TOKEN_GOES_HERE&return_to=/question/1-superb-question`. +6. Metabase verifies the JSON Web Token, logs the person in, then redirects the person to their original destination, `/question/1-superb-question`. + +## Enabling JWT authentication + +Navigate to the **Admin**>**Settings** section of the Admin area, then click on the **Authentication** tab. Click the **Configure** button in the JWT section of this page, and you'll see this form: + +![JWT form](images/JWT-auth-form.png) + +Here's a breakdown of each of the settings: + +**JWT Identity Provider URI:** This is where Metabase will redirect login requests. That is, it's where your users go to log in through your identity provider. + +**String Used by the JWT Signing Key:** The string used to seed the private key used to validate JWT messages. Both Metabase and the authentication app should have the same JWT signing key. + +## User attribute configuration (optional) + +These are additional settings you can fill in to pass user attributes to Metabase. + +- **Email attribute:** the key to retrieve each JWT user's email address. +- **First Name attribute:** the key to retrieve each JWT user's first name. +- **Last Name attribute:** if you guessed that this is the key to retrieve each JWT user's last name, well then you have been paying attention. + +You can send additional user attributes to Metabase by adding the attributes as key/value pairs to your JWT. These attributes will be synced on every login. + +## Configure group mappings + +You can use your JWT to assign Metabase users to custom groups. + +1. Add groups to your JWT: `groups: ["group_name"]`. +1. In Metabase, go to the Admin panel and switch to **Setting > Authentication** tab. +1. Click the **Configure** button under JWT. +1. Under **Group Schema**, turn on the toggle **Synchronize Group Memberships** +1. Click **New mapping** and add the name of a JWT group. +1. In the row that appears, click the dropdown to pick the Metabase group(s) that this should map to. + ![Metabase JWT group mappings](./images/jwt-groups.png) +1. Repeat this for each of the groups you want to map. + +Alternatively, you can define the mappings between JWT and Metabase groups using the [environment variable `MB_JWT_GROUP_MAPPINGS`](../configuring-metabase/environment-variables#mb_jwt_group_mappings). It accepts a JSON object where the keys are JWT groups and the values are lists of Metabase groups IDs. For example: + +``` +MB_JWT_GROUP_MAPPINGS='{"extHR":[7], "extSales":[3,4]}' +``` + +where `extHR`, `extSales` are names of JWT groups and 3,4,7 are IDs of Metabase groups. + +You can find Metabase Group ID in the URL for the group page, like `http://your-metabase-url/admin/people/groups/`. "All Users" group has ID 1 and "Administrators" group has ID 2. + +You can also use the [environment variable `MB_JWT_GROUP_SYNC`](../configuring-metabase/environment-variables#mb_jwt_group_sync) to turn group sync on or off. + +``` +MB_JWT_GROUP_SYNC=true +``` + +## Creating Metabase accounts with SSO + +> Paid plans [charge for each additional account](/docs/latest/cloud/how-billing-works#what-counts-as-a-user-account). + +A new SSO login will automatically create a new Metabase account. + +Metabase accounts created with an external identity provider login don't have passwords. People who sign up for Metabase using an IdP must continue to use the IdP to log into Metabase. + +## Disabling password logins + +> **Avoid locking yourself out of your Metabase!** This setting will apply to all Metabase accounts, _including your Metabase admin account_. We recommend that you keep password authentication **enabled**. This will safeguard you from getting locked out of Metabase in case of any problems with SSO. + +To require people to log in with SSO, disable password authentication from **Admin settings** > **Authentication**. + +![Password disable](images/password-disable.png) + +## Note about Azure + +If you're using Azure, you may need to use Azure AD B2C. Check out their [tokens overview](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview). + +## Example code using JWT-based authentication + +You can find example code that uses JWT authentication in the [SSO examples repository](https://github.com/metabase/sso-examples). + +- [JWT example in a Clojure app](https://github.com/metabase/sso-examples/tree/master/clj-jwt-example) +- [JWT example in JavaScript (Node) app](https://github.com/metabase/sso-examples/tree/master/nodejs-jwt-example) diff --git a/_docs/doc-update-detection/people-and-groups/authenticating-with-saml.md b/_docs/doc-update-detection/people-and-groups/authenticating-with-saml.md new file mode 100644 index 000000000..a06d55622 --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/authenticating-with-saml.md @@ -0,0 +1,215 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'SAML-based authentication' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/authenticating-with-saml.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/authenticating-with-saml +--- + +# SAML-based authentication + +{% include plans-blockquote.html feature="SAML authentication" %} + +Integrating your SSO with Metabase allows you to: + +- Provision a Metabase account when someone logs in to Metabase. +- Automatically pass user attributes from your SSO to Metabase in order to power [data sandboxes](../permissions/data-sandboxes). +- Let people access Metabase without re-authenticating. + +## Confirm the password for your Metabase admin account + +Before setting up SAML, make sure you know the password for your Metabase admin account. If you encounter any issues during the setup process, you can login via the "Admin backup login" option on the sign-in screen. + +## Setting up SAML with your IdP in Metabase + +Once you've [confirmed the password to your Metabase admin account](#confirm-the-password-for-your-metabase-admin-account), head over to the **Settings** section of the Admin Panel, then click on the **Authentication** tab. Click the **Set up** button in the SAML section of the Authentication page, and you'll see this form: + +![SAML form](images/saml-form.png) + +The form includes three sections: + +1. [Metabase info that you'll have to input into your identity provider (IdP)](#generic-saml-configuration). +2. [IdP info that you'll need to tell Metabase about](#enabling-saml-authentication-in-metabase). +3. [Signing SSO requests (optional)](#settings-for-signing-sso-requests-optional). + +## SAML guides + +First you'll need to make sure things are configured correctly with your IdP. Each IdP handles SAML setup differently. + +We've written up some guides for the most common providers: + +- [Auth0](saml-auth0) +- [Microsoft Entra ID](saml-azure) +- [Google](saml-google) +- [Keycloak](saml-keycloak) +- [Okta](saml-okta) + +If you don't see your IdP listed here: + +- Refer to your IdP's reference docs on configuring SAML. You'll be looking for something like this [OneLogin SAML guide](https://onelogin.service-now.com/support?id=kb_article&sys_id=83f71bc3db1e9f0024c780c74b961970). +- Using the information found on the Metabase SAML form, fill out your IdP's SAML form. +- For more information, see the next section on [Generic SAML configuration](#generic-saml-configuration). + +## User provisioning + +By default, Metabase will create accounts for people who don't yet have a Metabase account but who are able to log in via SAML SSO. + +If you've set up [User provisioning with SCIM](./user-provisioning), you'll want to turn this setting off so that Metabase doesn't automatically create a new account for anyone who authenticates successfully, as you may want to use SCIM to determine who can and can't create an account in Metabase. + +## Generic SAML configuration + +The top portion of the SAML form in Metabase has the information you'll need to fill out your IdP's SAML form, with buttons to make copying the information easy. + +The names of the fields in the Metabase SAML form won't always match the names used by your IdP. We've provided a description of each field below to help you map information from one place to another. + +### URL the IdP should redirect back to + +The redirect URL is the web address that people will be sent to after signing in with your IdP. To redirect people to your Metabase, your redirect URL should be your Metabase [Site URL](../configuring-metabase/settings#site-url), with `/auth/sso` at the end. + +For example, if your Metabase Site URL is `https://metabase.yourcompany.com`, you'll use + +``` +https://metabase.yourcompany.com/auth/sso +``` + +as the redirect URL in your IdP's SAML form. + +Different IdPs use different names for the redirect URL. Here are some common examples: + +| Provider | Name | +| ---------------------- | ------------------------ | +| [Auth0](saml-auth0) | Application Callback URL | +| [Okta](saml-okta) | Single Sign On URL | +| OneLogin | ACS (Consumer) URL | + +### User attributes + +Metabase will automatically log in people who've been authenticated by your SAML identity provider. In order to do so, the first assertion returned in the identity provider's SAML response _must_ contain attributes for each person's first name, last name, and email. + +Most IdPs already include these assertions by default, but some (such as [Okta](./saml-okta)) must be configured to include them. + +Generally you'll need to paste these user attributes (first name, last name, and email) into fields labelled "Name", "Attributes" or "Parameters". + +> If you allow people to edit their email addresses: make sure to update the corresponding account emails in Metabase. Keeping email addresses in sync will protect people from losing access to their accounts. + +### Settings for signing SSO requests (optional) + +These are additional settings you can fill in to sign SSO requests to ensure they don’t get tampered with. + +## Enabling SAML authentication in Metabase + +Metabase will now need to know some things about your IdP. Here's a breakdown of each of the settings: + +### SAML identity provider URL + +Metabase will redirect login requests to the Identity Provider URL, where people will go to log in with SSO. + +Different IdPs use different names for the Identity Provider URL. Here are some common examples: + +| Provider | Name | +| ---------------------- | ------------------------------------ | +| [Auth0](saml-auth0) | Identity Provider Login URL | +| [Okta](saml-okta) | Identity Provider Single-Sign On URL | +| OneLogin | SAML 2.0 Endpoint (HTTP) | + +### SAML identity provider issuer + +The SAML identity provider issuer is a unique identifier for the IdP. You might also see "Issuer" referred to as "Entity ID". Assertions from the IdP will contain this information, and Metabase will verify that the issuer matches the value you set. + +We recommend that you set this value to make your SAML configuration more secure. + +| Provider | Name | +| ---------------------- | --------------------------- | +| [Auth0](saml-auth0) | Identity Provider Login URL | +| [Okta](saml-okta) | Identity Provider Issuer | +| OneLogin | Issuer URL | + +### SAML identity provider certificate + +The SAML identity provider certificate is an encoded certificate that Metabase will use when connecting to the IdP URI. The certificate will look like a big blob of text that you'll want to copy and paste carefully — the spacing is important! + +Your IdP might have you download this certificate as a file (usually `.cer` or `.pem`), which you'll then need to open up in a text editor in order to copy the contents to then paste into the box in Metabase. + +Note that your certificate text may include header and footer comments that look like `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`. These comments should be included when pasting your certificate text into Metabase. + +| Provider | Name | +| ---------------------- | ------------------- | +| [Auth0](saml-auth0) | Signing Certificate | +| [Okta](saml-okta) | X.509 Certificate | +| OneLogin | X.509 Certificate | + +### Settings for signing SSO requests (optional) + +To sign request so that they can't be tampered with, you'll need to provide additional settings. + +If your IdP encrypts SAML responses, you'll need to ensure this section is filled out. + +> If you change any of these settings, either during initial setup or after editing an existing value, you will need to restart Metabase due to the way the keystore file is read. + +- **SAML keystore path:** the absolute path to the keystore file to use for signing SAML requests. +- **SAML keystore password:** the magic spell that will open the keystore. +- **SAML keystore alias:** the alias for the key that Metabase should use for signing SAML requests. + +## SAML Single logout (SLO) + +Metabase supports single logout (SLO) for SAML. + +The endpoint for SLO: `/auth/sso/handle_slo` + +So if your Metabase is served at `metabase.example.com` the logout service POST binding URL would be: + +``` +https://metabase.example.com/auth/sso/handle_slo +``` + +## Synchronizing group membership with your IdP + +This setting allows you to assign users to Metabase groups based on an attribute of your users in your IdP. This setting may not correlate to group functionality provided by your IdP; you may need to create a separate user attribute to set people's Metabase groups, like `metabaseGroups`. + +First, you will need to create a SAML user attribute that you will use to indicate which Metabase groups the person should be a part of. This created user attribute can be a XML string or a list of XML strings. Different IdPs have different ways of handling this, but you will likely need to edit your user profiles or find a way to map a user's groups to a list of Metabase group names. + +## Configuring the group schema in Metabase + +Once you've gotten everything set up in your SAML provider, you'll need to configure the group schema in Metabase. + +1. Turn on the **Synchronize group memberships** setting. +2. Click **Edit mappings**. +3. Click **Create a mapping**. +4. Enter in the name of one of the groups you entered as your `metabaseGroups` attribute values, then click the **Add** button. +5. Click the dropdown that appears under the `Groups` heading to select the Metabase group(s) that users with this particular `metabaseGroups` value should be added to. +6. Click **Save**. +7. After that, type in the name of the user attribute you added in your SAML provider. In this case, we told Okta that the `metabaseGroups` attribute should be named `MetabaseGroupName`, so that's what we'll enter in the Group Attribute Name field in Metabase. + +![Group schema](images/saml-okta-groups.png) + +## Creating Metabase accounts with SSO + +> Paid plans [charge for each additional account](/docs/latest/cloud/how-billing-works#what-counts-as-a-user-account). + +A new SSO login will automatically create a new Metabase account. + +Metabase accounts created with an external identity provider login don't have passwords. People who sign up for Metabase using an IdP must continue to use the IdP to log into Metabase. + +## Disabling password logins + +> **Avoid locking yourself out of your Metabase!** Turning off password logins applies to all Metabase accounts, _including your Metabase admin account_. Before turning off password logins, make sure you can log in to your admin account using SSO. + +To _require_ people to log in with SSO, disable password authentication from **Admin settings** > **Authentication**. Turn off the **Enable Password Authentication** toggle. + +![Password disable](images/password-disable.png) + +## New account notification emails + +When people log in to Metabase for the first time via SSO, Metabase will automatically create an account for them, which will trigger an email notification to Metabase administrators. If you don't want these notifications to be sent, you can toggle them off at the bottom of the Authentication page. + +## Example code using SAML + +You can find example code that uses SAML authentication in the [SSO examples repository](https://github.com/metabase/sso-examples). + +## Troubleshooting SAML issues + +- [Troubleshooting SAML](../troubleshooting-guide/saml). diff --git a/_docs/doc-update-detection/people-and-groups/changing-password-complexity.md b/_docs/doc-update-detection/people-and-groups/changing-password-complexity.md new file mode 100644 index 000000000..689f618c1 --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/changing-password-complexity.md @@ -0,0 +1,37 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: Passwords +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/changing-password-complexity.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/changing-password-complexity +--- + +# Passwords + +Metabase can allow authentication via email and password. + +## Password complexity + +Metabase offers a couple controls for administrators who prefer to increase the password requirements on their user accounts. + + export MB_PASSWORD_COMPLEXITY=strong + export MB_PASSWORD_LENGTH=10 + +The settings above can be used independently, so it's fine to use only one or the other. By default Metabase use complexity = `normal` and a password length of 6. The following options are available for complexity choice: + +- `weak` = no character constraints +- `normal` = at least 1 digit +- `strong` = minimum 8 characters w/ 2 lowercase, 2 uppercase, 1 digit, and 1 special character + +By default, Metabase also prevents users from setting passwords that are in a list of common passwords (like `qwerty123` and +`passw0rd`). Changing the complexity requirement to `weak` disables this behavior. + +## Disabling password logins + +{% include plans-blockquote.html feature="Disabling password logins" %} + +On Pro and Enterprise plans, you can require people to log in with SSO by disabling password authentication from **Admin settings** > **Authentication**. diff --git a/_docs/doc-update-detection/people-and-groups/changing-session-expiration.md b/_docs/doc-update-detection/people-and-groups/changing-session-expiration.md new file mode 100644 index 000000000..e31d21bba --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/changing-session-expiration.md @@ -0,0 +1,58 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'Session expiration' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/changing-session-expiration.md' +redirect_from: + - /docs/doc-update-detection/operations-guide/changing-session-expiration +--- + +# Session expiration + +By default, Metabase sessions are valid for two weeks after a user last authenticated (e.g. by entering their email address/password or via an SSO provider). For example, even if you visit your Metabase instance every day, you'll still have to log in again every two weeks. + +## Session age + +The session age is the maximum time that a person stays logged into Metabase (even if the person closes the browser). + +You can set the environment variable [`MAX_SESSION_AGE`](../configuring-metabase/environment-variables#max_session_age): + +``` +# Change session expiration to 24 hours +MAX_SESSION_AGE=1440 java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +or set the Java system property: + +``` +java -DMAX_SESSION_AGE=1440 -jar metabase.jar +``` + +`MAX_SESSION_AGE` is in minutes. + +## Session timeout + +{% include plans-blockquote.html feature="Session timeout" %} + +The session timeout is the maximum time that a person can be inactive (for example, if someone leaves Metabase open in a long-forgotten browser tab). + +You can toggle this setting from **Admin** > **Authentication**, or set the environment variable [`MB_SESSION_TIMEOUT`](../configuring-metabase/environment-variables#mb_session_timeout). + +Session timeout is null by default. You can use a session timeout to log people out earlier than the max [session age](#session-age). + +## Session cookies + +Metabase also supports using [session cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Session_cookies), which mean users will only stay authenticated until they close their browser. This can be enabled on a per-user basis by unchecking the "Remember me" box when logging in. Once the user closes their browser, the next time they visit Metabase they'll have to log in again. Session expiration still applies, so even if you leave your browser open forever, you'll still be required to re-authenticate after two weeks or whatever session expiration you've configured. + +You can tell Metabase to always use session cookies with the environment variable or Java system property `MB_SESSION_COOKIES`: + +``` +MB_SESSION_COOKIES=true java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar +``` + +Setting this environment variable will override the behavior of the "Remember me" checkbox and enforce the use of session cookies for all users. + +Note that browsers may use "session restoring", which means they automatically restore their previous session when reopened. In this case, the browser effectively acts as if it was never closed; session cookies will act the same as permanent cookies. For browsers that support this feature, this behavior is usually configurable. diff --git a/_docs/doc-update-detection/people-and-groups/google-sign-in.md b/_docs/doc-update-detection/people-and-groups/google-sign-in.md new file mode 100644 index 000000000..6e50269d9 --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/google-sign-in.md @@ -0,0 +1,72 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'Google Sign-In' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/google-sign-in.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/10-single-sign-on + - /docs/doc-update-detection/people-and-groups/google-and-ldap +--- + +# Google Sign-In + +Enabling [Google Sign-In](https://developers.google.com/identity/sign-in/web/sign-in) for single sign-on (SSO) lets your team log in with a click instead of using email and password. SSO can also be used to let people create Metabase accounts without asking an admin to add each person manually. You can find SSO options under **Settings** > **Admin settings** > **Authentication**. + +If you'd like to have people authenticate with [SAML][saml-docs] or [JWT][jwt-docs], Metabase's [Pro and Enterprise](/pricing/) let you do just that. + +## Enabling Google Sign-In + +Google Sign-In is a good option for SSO if: + +- Your team is already using Google Workspace, or +- You'd like to use Google's 2-step or multi-factor authentication (2FA or MFA) to secure your Metabase. + +## Get your Client ID from the Google developer console + +To let your team start signing in with Google, you’ll first need to create an application through Google’s [developer console](https://console.developers.google.com/projectselector2/apis/library). + +Next, you'll have to create authorization credentials and [get a Google API Client ID](https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid): + +- In the `Authorized JavaScript origins` section, specify the URI of your Metabase instance. +- Leave the `Authorized Redirect URIs` section blank. +- Copy your Client ID, which you'll paste into Metabase when setting up Google Sign-in. + +## Setting up Google Sign-in in Metabase + +Once you have your Google API `Client ID` (ending in `.apps.googleusercontent.com`), visit your Metabase and: + +1. Click on the settings **Gear** icon in the upper right. +2. Select **Admin settings**. +3. In the **Settings** tab, click on **Authentication**. +4. On the **Sign in with Google** card, click **Set up**. +5. In the **Client ID** field, paste your Google API Client ID. + +## Creating Metabase accounts with Google Sign-in + +> On [paid plans](/pricing/), you're [charged for each active account](/docs/latest/cloud/how-billing-works#what-counts-as-a-user-account). + +If people's Google account email addresses are from a specific domain, and you want to allow them to sign up on their own, you can enter that domain in the **Domain** field. + +Once set up, existing Metabase users signed in to a Google account that matches the email they used to set up their Metabase account will be able to sign in with just a click. + +Note that Metabase accounts _created_ with Google Sign-In will not have passwords; they must use Google to sign in to Metabase. + +## Multiple domains for Google Sign-in + +{% include plans-blockquote.html feature="Multiple domains for Google Sign-in" %} + +If you're on a [pro](/product/pro) or [Enterprise](/product/enterprise) plan, you can specify multiple domains from the same Google Workspace in the **Domain** field, separated by a comma. For example, `mycompany.com,example.com.br,otherdomain.co.uk`. + +## Syncing user attributes with Google + +User attributes can't be synced with regular Google Sign-In. To synchronize user attributes, you'll need to set up [Google SAML][google-saml-docs] or [JWT][jwt-docs] instead. + +[data-sandboxing-docs]: ../permissions/data-sandboxes +[google-saml-docs]: ./saml-google +[jwt-docs]: ./authenticating-with-jwt +[saml-docs]: ./authenticating-with-saml +[user-attributes-docs]: ../permissions/data-sandboxes#choosing-user-attributes-for-data-sandboxes +[user-attributes-def]: /glossary/attribute#user-attributes-in-metabase diff --git a/_docs/doc-update-detection/people-and-groups/images/AdminBar.png b/_docs/doc-update-detection/people-and-groups/images/AdminBar.png new file mode 100644 index 000000000..a532a8b90 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/AdminBar.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/JWT-auth-form.png b/_docs/doc-update-detection/people-and-groups/images/JWT-auth-form.png new file mode 100644 index 000000000..8819e2a7c Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/JWT-auth-form.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/RemoveUser.png b/_docs/doc-update-detection/people-and-groups/images/RemoveUser.png new file mode 100644 index 000000000..079a08ab7 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/RemoveUser.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/auth0callbackurl.png b/_docs/doc-update-detection/people-and-groups/images/auth0callbackurl.png new file mode 100644 index 000000000..1f6de8d06 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/auth0callbackurl.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/auth0createapp.png b/_docs/doc-update-detection/people-and-groups/images/auth0createapp.png new file mode 100644 index 000000000..3afd0845b Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/auth0createapp.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/auth0regularapp.png b/_docs/doc-update-detection/people-and-groups/images/auth0regularapp.png new file mode 100644 index 000000000..4ee101d70 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/auth0regularapp.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/auth0saml2addon.png b/_docs/doc-update-detection/people-and-groups/images/auth0saml2addon.png new file mode 100644 index 000000000..4540d2506 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/auth0saml2addon.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/auth0samlmappings.png b/_docs/doc-update-detection/people-and-groups/images/auth0samlmappings.png new file mode 100644 index 000000000..2d5833245 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/auth0samlmappings.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/auth0samlusage.png b/_docs/doc-update-detection/people-and-groups/images/auth0samlusage.png new file mode 100644 index 000000000..251277dea Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/auth0samlusage.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/groups.png b/_docs/doc-update-detection/people-and-groups/images/groups.png new file mode 100644 index 000000000..e3411797a Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/groups.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/jwt-groups.png b/_docs/doc-update-detection/people-and-groups/images/jwt-groups.png new file mode 100644 index 000000000..db0f5aeb1 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/jwt-groups.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/ldap-attributes.png b/_docs/doc-update-detection/people-and-groups/images/ldap-attributes.png new file mode 100644 index 000000000..c6e366c18 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/ldap-attributes.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/ldap-group-mapping.png b/_docs/doc-update-detection/people-and-groups/images/ldap-group-mapping.png new file mode 100644 index 000000000..5ff3a7e14 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/ldap-group-mapping.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/okta-adding-groups.png b/_docs/doc-update-detection/people-and-groups/images/okta-adding-groups.png new file mode 100644 index 000000000..114f5d09b Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/okta-adding-groups.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/okta-group-attribute.png b/_docs/doc-update-detection/people-and-groups/images/okta-group-attribute.png new file mode 100644 index 000000000..0b0cc32cb Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/okta-group-attribute.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/okta-new-attribute-custom.png b/_docs/doc-update-detection/people-and-groups/images/okta-new-attribute-custom.png new file mode 100644 index 000000000..1918b5416 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/okta-new-attribute-custom.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/okta-new-attribute.png b/_docs/doc-update-detection/people-and-groups/images/okta-new-attribute.png new file mode 100644 index 000000000..559fa50f3 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/okta-new-attribute.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/password-disable.png b/_docs/doc-update-detection/people-and-groups/images/password-disable.png new file mode 100644 index 000000000..b9c3a522b Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/password-disable.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/saml-azure-ad-create.png b/_docs/doc-update-detection/people-and-groups/images/saml-azure-ad-create.png new file mode 100644 index 000000000..425e371a9 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/saml-azure-ad-create.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/saml-azure-ad-enterprise-app.png b/_docs/doc-update-detection/people-and-groups/images/saml-azure-ad-enterprise-app.png new file mode 100644 index 000000000..07f8e0c47 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/saml-azure-ad-enterprise-app.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/saml-azure-app-saml.png b/_docs/doc-update-detection/people-and-groups/images/saml-azure-app-saml.png new file mode 100644 index 000000000..64f49beb0 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/saml-azure-app-saml.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/saml-azure-step-1.png b/_docs/doc-update-detection/people-and-groups/images/saml-azure-step-1.png new file mode 100644 index 000000000..038d09f91 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/saml-azure-step-1.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/saml-form.png b/_docs/doc-update-detection/people-and-groups/images/saml-form.png new file mode 100644 index 000000000..1a4f835d3 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/saml-form.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/saml-okta-groups.png b/_docs/doc-update-detection/people-and-groups/images/saml-okta-groups.png new file mode 100644 index 000000000..d54118b47 Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/saml-okta-groups.png differ diff --git a/_docs/doc-update-detection/people-and-groups/images/user-provisioning.png b/_docs/doc-update-detection/people-and-groups/images/user-provisioning.png new file mode 100644 index 000000000..23e5497cb Binary files /dev/null and b/_docs/doc-update-detection/people-and-groups/images/user-provisioning.png differ diff --git a/_docs/doc-update-detection/people-and-groups/ldap.md b/_docs/doc-update-detection/people-and-groups/ldap.md new file mode 100644 index 000000000..bac4b422f --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/ldap.md @@ -0,0 +1,114 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: LDAP +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/ldap.md' +--- + +# LDAP + +Metabase supports authentication with Lightweight Directory Access Protocol (LDAP). + +You can find SSO options under **Admin settings** > **Settings** > **Authentication**. + +## Required LDAP attributes + +You need to set up your LDAP directory with these attributes: + +- email (defaulting to the `mail` attribute) +- first name (defaulting to the `givenName` attribute) +- last name (defaulting to the `sn` attribute). + +If your LDAP setup uses other attributes for these, you can edit this under the "Attributes" portion of the form. + +![Attributes](./images/ldap-attributes.png) + +Your LDAP directory must have the email field populated for each entry that will become a Metabase user, otherwise Metabase won't be able to create the account, nor will that person be able to log in. If either name field is missing, Metabase will use a default of "Unknown," and the person can change their name in their [account settings](./account-settings). + +## Enabling LDAP authentication + +In the **Admin settings** > **Settings** > **Authentication** tab, go to the LDAP section and click **Set up**. Click the toggle at the top of the form to enable LDAP, then fill out the form with the relevant details. + +## User provisioning + +When a person logs in via LDAP, Metabase can create a Metabase account for them automatically (if they don't already have a Metabase account). + +## Server settings + +- LDAP Host. Your server name. E.g., ldap.yourdomain.org +- LDAP Port. The Server port, usually 389 or 636 if SSL is used. +- LDAP Security settings. Options are None, SSL, or StarTLS. +- LDAP admin username. The distinguished name to bind as (if any). This user will be used to look up information about other users. +- LDAP admin password. + +Then save your changes. Metabase will automatically pull the [required attributes](#required-ldap-attributes) from your LDAP directory. + +## User schema + +The **User Schema** section on this same page is where you can adjust settings related to where and how Metabase connects to your LDAP server to authenticate users. + +### User search base + +The **User search base** field should be completed with the _distinguished name_ (DN) of the entry in your LDAP server that is the starting point when searching for users. + +For example, let's say you're configuring LDAP for your company, WidgetCo, where your base DN is `dc=widgetco,dc=com`. If entries for employees are all stored within an organizational unit in your LDAP server named `People`, you'll want to supply the user search base field with the DN `ou=People,dc=widgetco,dc=com`. This tells Metabase to begin searching for matching entries at that location within the LDAP server. + +### User filter + +You'll see the following grayed-out default value in the **User filter** field: + +``` +(&(objectClass=inetOrgPerson)(|(uid={login})(mail={login}))) +``` + +When a person logs into Metabase, this command confirms that the login they supplied matches either a UID _or_ email field in your LDAP server, _and_ that the matching entry has an objectClass of `inetOrgPerson`. + +This default command will work for most LDAP servers, since `inetOrgPerson` is a widely-adopted objectClass. But if your company for example uses a different objectClass to categorize employees, this field is where you can set a different command for how Metabase finds and authenticates an LDAP entry upon a person logging in. + +## LDAP group mapping + +Manually assigning people to [groups](./managing#groups) in Metabase after they've logged in via SSO can get tedious. Instead, you can take advantage of the groups that already exist in your LDAP directory by enabling [group mappings](/learn/metabase-basics/administration/permissions/ldap-auth-access-control#group-management). + +Scroll to **Group Schema** on the same LDAP settings page, and click the toggle to enable group mapping. Selecting **Edit Mapping** will bring up a modal where you can create and edit mappings, specifying which LDAP group corresponds to which Metabase group. + +As you can see below, if you have an **Accounting** group in both your LDAP server and Metabase instance, you'll just need to supply the Distinguished Name from your LDAP server (in the example, it's `cn=Accounting,ou=Groups,dc=widgetco,dc=com`) and select its match from the dropdown of your existing Metabase groups. + +![Group Mapping](images/ldap-group-mapping.png) + +Some things to keep in mind regarding group mapping: + +- The Administrator group works like any other group. +- Updates to a person's group membership based on LDAP mappings are not instantaneous; the changes will take effect only _after_ people log back in. +- People are only ever added to or removed from mapped groups; the sync has no effect on groups in your Metabase that don't have an LDAP mapping. + +## LDAP group membership filter + +{% include plans-blockquote.html feature="LDAP advanced features" %} + +Group membership lookup filter. The placeholders {dn} and {uid} will be replaced by the user's Distinguished Name and UID, respectively. + +## Syncing user attributes with LDAP + +{% include plans-blockquote.html feature="LDAP advanced features" %} + +You can manage [user attributes][user-attributes-def] such as names, emails, and roles from your LDAP directory. When you set up [data sandboxing][data-sandboxing-docs], your LDAP directory will be able to [pass these attributes][user-attributes-docs] to Metabase. + +## Troubleshooting login issues + +- [Can't log in](../troubleshooting-guide/cant-log-in). +- [Troubleshooting LDAP](../troubleshooting-guide/ldap) + +## Further reading + +- [Using LDAP for authentication and access control](/learn/metabase-basics/administration/permissions/ldap-auth-access-control). +- [Permissions overview](../permissions/start). + +[data-sandboxing-docs]: ../permissions/data-sandboxes +[google-saml-docs]: ./saml-google +[jwt-docs]: ./authenticating-with-jwt +[saml-docs]: ./authenticating-with-saml +[user-attributes-docs]: ../permissions/data-sandboxes#choosing-user-attributes-for-data-sandboxes +[user-attributes-def]: /glossary/attribute#user-attributes-in-metabase diff --git a/_docs/doc-update-detection/people-and-groups/managing.md b/_docs/doc-update-detection/people-and-groups/managing.md new file mode 100644 index 000000000..99548663b --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/managing.md @@ -0,0 +1,232 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'People and groups' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/managing.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/04-managing-users +--- + +# People and groups + +People can have [accounts](#creating-an-account) in Metabase, and those accounts can be members of [groups](#groups). These groups are used to define [permissions](../permissions/introduction). People can be in multiple groups. + +> This page covers accounts people use to log in to _your_ Metabase(s). These accounts are distinct from [Metabase _store_ accounts](https://store.metabase.com), which are used to manage paid Metabase plans. + +## Managing people and groups + +To start managing people and groups: + +Hit Cmd/Ctrl + K to bring up the command palette and search for "People". Click on the **People** settings result. + +Or + +Click on the **gear** icon > **Admin settings** > **People**. You'll see a list of all the people in your organization. + +![Admin menu](images/AdminBar.png) + +## Creating an account + +Admins can add people to their Metabase. To add a new person manually, click on the gear icon and select **Admin settings**. Under the **People** tab, click **Invite someone** in the upper right corner. You’ll be prompted to enter their email, and optionally their first and last names–only the email is required. + +Click **Create** to activate an account. An account becomes active once you click **Create**, even if the person never signs into the account. The account remains active until you [deactivate the account](#deactivating-an-account). If you're on a Pro or Enterprise Metabase plan, all active accounts will count toward your user account total. If one person has more than one account, each account will count toward the total (see [how billing works](/docs/latest/cloud/how-billing-works)). + +If you’ve already [configured Metabase to use email](../configuring-metabase/email), Metabase will send the person an email inviting them to log into Metabase. If you haven't yet setup email for your Metabase, Metabase will give you a temporary password that you’ll have to manually send to the person. + +To create accounts with SSO, check out [authentication options](./start#authentication). + +## Editing an account + +You can edit someone's name and email address by clicking the three dots icon and choosing **Edit user**. + +> Be careful: changing an account's email address _will change the address the person will use to log in to Metabase_. + +## Adding a user attribute + +{% include plans-blockquote.html feature="User attributes" %} + +To add a user attribute manually: + +1. Go to **Admin settings** > **People**. +2. Find the person's account and click the **three dot** (...) menu. +3. Click **Edit user**. +4. Click **+ Add an attribute**. +5. Add the name of the user attribute under "Key". For example, "Department". +6. Add the value that applies to the specific person. For example, "Engineering". +7. Optional: if a group for sandboxed people doesn't exist, [create a group](#creating-a-group) to organize people who will get sandboxed table permissions, such as "Sandboxed people". +8. Add the person to the group. + +You can also sync user attributes from your identity provider [via SSO](./start#authentication). + +User attributes are required for [data sandbox](../permissions/data-sandboxes) permissions. + +You can also employ user attributes to specify what database role Metabase should use when that person queries a database. Check out [impersonation access](../permissions/data#impersonated-view-data-permission). + +## Deactivating an account + +To deactivate someone's account, click on the three dots icon on the right of a person’s row and select **Deactivate** from the dropdown. Deactivating an account will mark it as inactive and prevent the user from logging in - but it _won’t_ delete that person's saved questions or dashboards. + +If you're using SSO, you should deactivate the account in Metabase as well as your IdP (that is, deactivation doesn't get applied from Metabase to your IdP, and vice versa). + +![Remove a user](images/RemoveUser.png) + +To reactivate a deactivated account, click the **Deactivated** radio button at the top of the people list to see the list of deactivated accounts. Click on the icon on the far right to reactivate that account, allowing them to log in to Metabase again. + +## Deleting an account + +Metabase doesn't explicitly support account deletion. Instead, Metabase deactivates accounts so people can't log in to them, while it preserves any questions, models, dashboards, and other items created by those accounts. + +If you want to delete an account because the account information was set up incorrectly, you can deactivate the old account and create a new one instead. + +1. Change the name and email associated with the old account. +2. [Deactivate](#deactivating-an-account) the old account. +3. [Create a new account](#creating-an-account) with the person's correct information. + +## Checking someone's auth method + +Search for a person and look for an icon beside their name. + +- If they log in using Google credentials, Metabase displays a Google icon. +- If they log in using an email address and password stored in Metabase, no icon is shown. + +Note that the type of user is set when the account is first created: if you create a user in Metabase, but that person then logs in via Google or some other form of SSO, the latter's icon will _not_ show up next to their name. + +## Resetting someone’s password + +If you've already [configured your email settings](../configuring-metabase/email), people can reset their passwords using the "forgot password" link on the login screen. If you haven't yet configured your email settings, they will see a message telling them to ask an admin to reset their password for them. + +To reset a password for someone, just click the three dots icon next to their account and choose **Reset Password**. If you haven’t [configured your email settings](../configuring-metabase/email) yet, you’ll be given a temporary password that you’ll have to share with that person. Otherwise, they’ll receive a password reset email. + +## Resetting the admin password + +If you're using Metabase Cloud, [contact support](/help-premium) to reset your admin password. + +If you're a Metabase admin and have access to the server console, you can get Metabase to send you a password reset token: + +1. Stop the running Metabase application. +2. Restart Metabase with `reset-password email@example.com`, where "email@example.com" is the email associated with the admin account: + ``` + java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar reset-password email@example.com + ``` +3. Metabase will print out a random token like this: + + ``` + ... + Resetting password for email@example.com... + + OK [[[1_7db2b600-d538-4aeb-b4f7-0cf5b1970d89]]] + ``` + +4. Start Metabase normally again (_without_ the `reset-password` option). +5. Navigate to it in your browser using the path `/auth/reset_password/:token`, where ":token" is the token that was generated from the step above. The full URL should look something like this: + ``` + https://metabase.example.com/auth/reset_password/1_7db2b600-d538-4aeb-b4f7-0cf5b1970d89 + ``` +6. You should now see a page where you can input a new password for the admin account. + +## Unsubscribe from all subscriptions and alerts + +This action will delete any dashboard subscriptions or alerts the person has created, and remove them as a recipient from any other subscriptions or alerts. + +This action doesn't affect email distribution lists that are managed outside of Metabase. + +## Default user accounts + +Metabase includes default user accounts to handle various tasks. We're documenting these accounts here so you know they're legitimate accounts and not someone trying to spy on your Metabase. Some things to know about them: + +- Customers are not charged for these accounts. +- No one can log in to these user accounts. +- Metabase excludes these user accounts from the **Admin settings** > **People** tab. + +### Anonymous user account + +- ID: 0 +- First name: External +- Last name: User +- Email: null + +Metabase uses this anonymous user account to identify anonymous views, for example views of a [public question or dashboard](../embedding/public-links). This account is a virtual user: the account doesn't exist in the application database. You'll see this account show up in [usage analytics](../usage-and-performance-tools/usage-analytics). + +### Metabase internal account + +- ID: 13371338 +- First name: Internal +- Last name: Metabase +- Email: internal@metabase.com + +Metabase uses this account to load content into Metabase (like the [Usage analytics](../usage-and-performance-tools/usage-analytics) collection). You may see this `internal@metabase.com` account in the logs. + +## Groups + +To determine [who has access to what](../permissions/start), you’ll need to + +- Create one or more groups. +- Choose which level of access that group has to different databases, collections, and so on. +- Then add people to those groups. +- (Optional) promote people to [group managers](#group-managers). + +To view and manage your groups, go to the **Admin Panel** > **People** tab, and then click on **Groups** from the side menu. + +![Groups](images/groups.png) + +### Special default groups + +Every Metabase has two default groups: Administrators and All Users. These are special groups that can’t be removed. + +#### Administrators + +To make someone an admin of Metabase, you just need to add them to the Administrators group. Metabase admins can log into the Admin Panel and make changes there, and they always have unrestricted access to all data that you have in your Metabase instance. So be careful who you add to the Administrator group! + +#### All users + +The **All Users** group is another special one. Every Metabase user is always a member of this group, though they can also be a member of as many other groups as you want. We recommend using the All Users group as a way to set default access levels for new Metabase users. If you have [Google single sign-on](./google-sign-in) enabled, new users who join that way will be automatically added to the All Users group. + +It's important that your All Users group should never have _greater_ access for an item than a group for which you're trying to restrict access — otherwise the more permissive setting will win out. See [Setting permissions](../permissions/start). + +## Creating a group + +Go to **Admin settings** > **People** > **Groups**, and click the **Add a group** button. + +We recommend creating groups that correspond to the teams your company or organization has, such as Human Resources, Engineering, Finance, and so on. By default, newly created groups don’t have access to anything. + +To remove a group, click the X icon to the right of a group in the list to remove it (remember, you can’t remove the special default groups). + +## Adding people to groups + +To add people to that group, click into a group and then click **Add members**. + +To remove someone from that group, click on the **X** to the right of the group member. + +You can also add or remove people from groups from the **People** list using the dropdown in the **Groups** column. + +## Group managers + +{% include plans-blockquote.html feature="Group managers" %} + +**Group managers** can manage other people within their group. + +Group managers can: + +- Add or remove people from their group (that is, people who already have accounts in your Metabase). +- View all people in the **Admin settings** > **People** tab. +- Promote other people to group manager, or demote them from group manager to member. +- Rename their group. + +Group managers are not admins, so their powers are limited. They cannot create new groups or invite new people to your Metabase. + +## Promoting/demoting group managers + +To promote someone to become a group manager: + +1. At the top right of the screen, click the **gear** icon > **Admin settings** > **People** > **Groups**. +2. Select the group you want the person to manage. If the person isn't already in the group, you'll need to add that person to the group. +3. Find the person you want to promote, hover over their member type, and click the up arrow to promote them to group manager. If you want to demote them, click on the down arrow. + +## Further reading + +- [Configure Single Sign-On (SSO)](./start#authentication). +- [Permissions strategies](/learn/metabase-basics/administration/permissions/strategy). +- [Multi-tenant permissions](/learn/metabase-basics/administration/permissions/multi-tenant-permissions). diff --git a/_docs/doc-update-detection/people-and-groups/saml-auth0.md b/_docs/doc-update-detection/people-and-groups/saml-auth0.md new file mode 100644 index 000000000..c7d973da9 --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/saml-auth0.md @@ -0,0 +1,88 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'SAML with Auth0' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/saml-auth0.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/saml-auth0 +--- + +# SAML with Auth0 + +{% include plans-blockquote.html feature="SAML authentication" %} + +1. [Configure SAML in Auth0](#working-in-the-auth0-console) (the identity provider). +2. [Configure SAML in Metabase](./authenticating-with-saml#enabling-saml-authentication-in-metabase) (the service provider). + +For more information, check out our guide for [authenticating with SAML](./authenticating-with-saml). + +## Working in the Auth0 console + +### Create an application + +After you log in to your Auth0 account, navigate to **Applications** and select **Create Application**. + +![Auth0 Applications Page](images/auth0createapp.png) + +Enter “Metabase” as the application name with type “Regular Web Applications”. + +![Auth0 Application Selection](images/auth0regularapp.png) + +Now go to Settings tab inside Auth0's Metabase App and fill in the following values: + +- Application Login URI: the URL of your Metabase instance. +- Allowed Callback URLs: the URL that's below **Configure your identity provider (IdP)** in SAML settings inside Metabase (it ends with `/auth/sso`). + +![Auth0 SAML Settings Page](images/auth0callbackurl.png) + +Scroll to the bottom of the page and click **Save Changes**. + +### Enable SAML in Auth0 + +Next, we need to activate the SAML2 Web App Addon. Scroll back to the top of the settings page and select **Addons** from the navigation menu. + +In the **Addons** section, select the **SAML 2 Web App** to load the settings popup. + +![Auth0 Application Addons](images/auth0saml2addon.png) + +### Mapping fields from users in Auth0 to Metabase + +On the top of the **Settings** section on this page, you need to re-enter the value you included in **Allowed Callback URLs** in the field named **Application Callback URL**. Copy and paste the following JSON file in the settings box so that Auth0 can send the correct mappings to Metabase when a user logs in: + +``` +{ + "mappings": { + "email":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", + "given_name":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname", + "family_name":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname", + "groups":"http://schemas.xmlsoap.org/claims/Group" + } +} +``` + +If you need to set additional user properties, you can always return to this step to add additional fields to the mappings object. + +![Auth0 SAML Mappings](images/auth0samlmappings.png) + +## Configuring Metabase + +Next, in the Auth0 Addon: SAML2 Web App popup, click on the **Usage** tab and then configure in Metabase (column on the left) the values that this tab provides (column on the right). + +![Auth0 SAML usage](images/auth0samlusage.png) + +| Metabase | Auth0 | +| ---------------------------------- | ------------------------------------------------------------------------------------------ | +| SAML Identity Provider URL | Identity Provider Login URL | +| SAML Identity Provider Issuer | Issuer | +| SAML Identity Provider Certificate | Open the Identity Provider Metadata link and copy the string under the X509Certificate tag | + +The "SAML Application Name" value can be left as the default (Metabase). + +Save your settings, then [enable SAML](authenticating-with-saml) in Metabase, and you should be good to go! + +## Troubleshooting SAML issues + +- [SAML troubleshooting page](../troubleshooting-guide/saml). diff --git a/_docs/doc-update-detection/people-and-groups/saml-azure.md b/_docs/doc-update-detection/people-and-groups/saml-azure.md new file mode 100644 index 000000000..d73f481d4 --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/saml-azure.md @@ -0,0 +1,78 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'SAML with Microsoft Entra ID' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/saml-azure.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/authenticating-with-saml-azure-ad +--- + +# SAML with Microsoft Entra ID + +{% include plans-blockquote.html feature="SAML authentication" %} + +## Enable SAML in Metabase + +First, follow our guide to [enable SAML authentication](authenticating-with-saml). + +## Add an Enterprise Application in Microsoft Entra ID + +Go to Microsoft Entra admin center and click on **Enterprise Applications** under Applications from the side bar. Once there, click on **+ New Application** in the bar on the top of the page. + +![AZEnterpriseApp](images/saml-azure-ad-enterprise-app.png) + +In the new page click on **+ Create your own application** and a bar will open in the right side of the page. Enter "Metabase" as the name of the application, select `Integrate any other application you don't find in the gallery (Non-gallery)` as the option and click the **Create** button on the bottom of the bar. + +![AZMetabaseApp](images/saml-azure-ad-create.png) + +On the application page, under **Manage**, select **Single Sign-on**, then click on the "SAML" button. + +![AZAppSAML](images/saml-azure-app-saml.png) + +When the "Set up Single Sign-On with SAML" page appears, you'll see an option for "Basic SAML configuration". Click on the **Edit** button to enter the required info. + +![AZAzureStep1](images/saml-azure-step-1.png) + +Fill out the following fields as follows and click "Save": + +- **Identifier (Entity ID)**: `Metabase` +- **Reply URL (Assertion Consumer Service URL)**: go to your Metabase instance in Settings -> Admin-> Authentication -> SAML and insert the value that your Metabase instance reports in the "Configure your identity provider (IdP)" box. + +Click on "Save" and then note the following 2 items on step 4: + +- "Login URL": this is the value you need to enter in "SAML identity provider URL" in Metabase on the next step +- "Microsoft Entra Identifier": this is the value you need to enter in "SAML identity provider issuer" in Metabase on the next step + +Download the "Federation Metadata XML" file, which will have the certificate you'll need in the next step. + +To finish the Microsoft Entra side of the configuration, click on the **Users and groups** button on the Manage tab and add the users or groups that should have access to Metabase. + +## Configure the Enterprise Application with Metabase SSO information + +Log in to Metabase as an administrator and go to **Admin** -> **Settings** -> **Authentication** -> **SAML**. + +Under "Tell Metabase about your identity provider", enter the following: + +- **SAML Identity Provider URL**: the "Login URL" you got on Step 4 on the Microsoft Entra ID SAML SSO configuration +- **SAML Identity Provider Certificate**: open the "Federation Metadata XML" with a text editor, copy and paste the super long string under the `` tag in the "App Federation Metadata Url". Make sure you copy and paste the whole string; if you miss any character, the integration won't work +- **SAML Application Name**: "Metabase" +- **SAML Identity Provider Issuer**: the "Microsoft Entra Identifier" URL you got from the Microsoft Entra ID SAML SSO configuration. + +Click on **Save and Enable** below, and you should now be able to log in via Microsoft Entra ID. + +## Send group membership to Metabase for group mapping + +If you want to send the user group membership to Metabase, then you need to add a group claim on step 2, "Set up Single Sign-On with SAML" on Azure: + +1. To the right of "Attributes & Claims", click on "Edit." +2. Click "Add a group claim." + 3 On the menu that appears for "Which groups associated with the user should be returned in the claim?", select "All groups." +3. Click on Save. +4. Then add the group mapping on the Metabase SAML configuration. + +## Further reading + +- [User provisioning](./user-provisioning) diff --git a/_docs/doc-update-detection/people-and-groups/saml-google.md b/_docs/doc-update-detection/people-and-groups/saml-google.md new file mode 100644 index 000000000..1d9133da9 --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/saml-google.md @@ -0,0 +1,70 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'SAML with Google' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/saml-google.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/saml-google +--- + +# SAML with Google + +{% include plans-blockquote.html feature="Google SAML authentication" %} + +1. Set up a [custom SAML app](https://support.google.com/a/answer/6087519) in your [Google admin console](https://admin.google.com). +2. As you follow Google's instructions, you'll need to: + +- [Save information about Google for Metabase](#saving-google-idp-info-for-metabase). +- [Provide Google info to Metabase](#filling-out-the-metabase-saml-form). +- [Provide Metabase info to Google ](#filling-out-service-provider-details). +- [Set up attribute mappings in Google](#setting-up-attribute-mappings). + +See [authenticating with SAML](./authenticating-with-saml) for general SAML info. + +## Saving Google IdP info for Metabase + +On the **Google Identity Provider details** page: + +1. Download the **IdP metadata**. +2. Copy the **SSO URL**. +3. Download the **certificate**. + +## Filling out the Metabase SAML form + +1. From your Google **IdP metadata**, locate the **issuer**. + - The **issuer** looks like this: `https://accounts.google.com/o/saml2/`. +2. Go to your Metabase SAML form (**Admin settings** > **Authentication** > **SAML**). +3. Put the **issuer** in the Metabase **SAML Identity Provider Issuer** field. +4. Put the **SSO URL** in the Metabase **SAML Identity Provider URL** field. +5. Paste the **certificate** in the Metabase **SAML Identity Provider Certificate** field. + +- Make sure to include any header and footer comments (like `---BEGIN CERTIFICATE---`). + +## Filling out service provider details + +On the **Service provider details** page: + +1. Put the Metabase **URL the IdP should redirect to** in the Google **ACS URL** field. +2. Put the Metabase **SAML Application Name** in the Google **Entity ID** field. + - The **SAML Application Name** can be anything you like (e.g., "yourcompany-metabase"). +3. **Start URL** and **Signed response** are optional fields. + +## Setting up attribute mappings + +On the **Attribute mappings** page, you'll need to add "First name", "Last name", and "Email" as attributes, so that Google can pass them to Metabase during authentication. + +For example, to add the attribute "First name": + +1. Click **Add another mapping**. +2. Under **Google Directory attributes**, choose **Basic information** > **First name** as the attribute field name. +3. Go to your Metabase SAML form, and look for **SAML attributes** > **User's first name attribute**. + - The attribute looks like this: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname`. +4. Paste the **User's first name attribute** under your Google **App attributes**. +5. Repeat steps 1-3 for the attributes "Last name" and "Email". + +## Troubleshooting SAML issues + +- [Troubleshooting SAML](../troubleshooting-guide/saml). diff --git a/_docs/doc-update-detection/people-and-groups/saml-keycloak.md b/_docs/doc-update-detection/people-and-groups/saml-keycloak.md new file mode 100644 index 000000000..38a592a86 --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/saml-keycloak.md @@ -0,0 +1,105 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'SAML with Keycloak' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/saml-keycloak.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/saml-keycloak +--- + +# SAML with Keycloak + +Keycloak is an open source platform that can be used as a user directory to save user data while acting as the IdP for single sign-on. + +1. [Set up SAML in Keycloak](#working-in-the-keycloak-console) (the identity provider). +2. [Set up SAML in Metabase](./authenticating-with-saml#enabling-saml-authentication-in-metabase) (the service provider). + +For more information, check out our guide for [authenticating with SAML](./authenticating-with-saml). + +## Working in the Keycloak console + +1. Go to the Keycloak admin console and sign in as an administrator. +2. Create a user from **Manage** > **Users**. You'll need to populate the fields with an email, first name, and last name. +3. Once you've created at least one user, navigation tabs will appear at the top of the **Users** page. Go to **Credentials** to set password for your user. + - Turn off the **Temporary** toggle. + - Click **Set Password** to save your changes. +4. Create a new SSO client from **Manage** > **Clients** > **Create** + + - **Client ID**: Enter `metabase` in lowercase. + - **Client type**: Select `SAML` from the dropdown. + - Click **Next**. + - **Valid Redirect URIs**: The URL where you are hosting your Metabase instance followed by a slash (/) and an asterisk (*). For example, if you are hosting Metabase locally at `http://localhost:3000`, the URL would be `http://localhost:3000/*`. + - **Home URL**: In your Metabase, go to **Admin settings** > **Authentication** > **SAML**. You'll find your Home URL in the field **URL the IdP should redirect back to**. + - Click **Save**. + +5. (Optional, but recommended on test environments) Disable key signing for SSO client. See [settings for signing SSO requests](/docs/latest/people-and-groups/authenticating-with-saml#settings-for-signing-sso-requests-optional). + + - Click **Keys** tab. + - **Client signature required:** Off. + +6. Map user attributes from Metabase to SSO client. + - Click **Client scopes** tab. + - Click `metabase-dedicated`. + - Click **Add predefined mappers**. + - [Map attributes from users in Keycloak to Metabase](#mapping-attributes-from-users-in-keycloak-to-metabase). +7. Configure the service provider (Metabase) from **Configure** > **Realm Settings**. + - From **Endpoints**, select “SAML 2.0 Identity Provider Metadata”. + - An XML file will open in a new tab. + - Keep this for reference, we will use it in the next section to configure Metabase. + +## Mapping fields from Keycloak to Metabase + +1. Go to your Metabase **Admin settings** > **Authentication** > **SAML**. +2. From the XML file from Step 7 above: + - **SAML Identity Provider URL**: Insert the URL that appears right after the following string: `Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location=` + - **SAML Identity Provider Issuer**: Insert the URL that appears right after `entityID=`. + - **SAML Identity Provider Certificate**: Input the long string that appears after the `` tag. Take care when inserting this string: if any letters or special characters are added or off, the setup won't work. + - **SAML Application Name**: `metabase` +3. Click **Save Changes**. +4. Check that **SAML Authentication** is toggled **ON** at the top of the page. + +## Mapping attributes from users in Keycloak to Metabase + +Keycloak can import four user attributes by default: name, surname, email and role. + +Let's say we want email, name, and surname to be passed between the client (Metabase) and the authentication server (Keycloak). + +1. Select “X500 email”, “X500 givenName” and “X500 surname” from the checkboxes that are on the right side of the console. +2. Click **Add Selected**. +3. Click **Edit** beside each attribute and make the following changes: + - **SAML Attribute Name**: the name that Metabase expects to receive. + - **SAML Attribute NameFormat**: select “Basic” from the dropdown menu. + +You can edit the attribute values from your Metabase **Admin settings** > **Authentication** > **SAML** > **Attributes**. + +## Configure group mappings between Keycloak and Metabase + +You can configure Metabase to automatically assign people to Metabase groups based on their Keycloak groups. + +### Set up group mapping in Keycloak + +In your Keycloak client: + +1. Click on **Client Scopes** tab +2. Click on the **metabase-dedicated** client scope that has been created already. +3. Click on **Add Mapper > "By Configuration**. +4. Select **Group list**. +5. Change the name of the attribute to `member_of`. +6. Deselect the option to use the "Full group path" (so it's easier to configure in Metabase later). +7. Click on **Save**. + +### Set up group mapping in Metabase + +1. In Admin settings, go to **Authentication > SAML**. +2. In SAML settings, toggle on **Synchronize Group Memberships** +3. For each of the Keycloak groups, set up a new mapping to a Metabase group. + + Currently, Keycloak groups will show up in Metabase with the slash character ("/") prepended to the group name. So, for example, a group named `sales` in Keycloak show up in Metabase as `/sales`. + +4. In **Group attribute name**, enter `member_of` (the name for the attribute with the group list in your Keycloack configuration). +## Troubleshooting SAML issues + +For common issues, go to [Troubleshooting SAML](../troubleshooting-guide/saml). diff --git a/_docs/doc-update-detection/people-and-groups/saml-okta.md b/_docs/doc-update-detection/people-and-groups/saml-okta.md new file mode 100644 index 000000000..35b9d4469 --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/saml-okta.md @@ -0,0 +1,211 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'SAML with Okta' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/saml-okta.md' +--- + +# SAML with Okta + +{% include plans-blockquote.html feature="Okta SAML authentication" %} + +1. [Turn on SAML-based SSO in Metabase](#turn-on-saml-based-sso-in-metabase) +2. [Set up SAML in Okta](#set-up-saml-in-okta). +3. [Set up SAML up in Metabase](#set-up-saml-in-metabase). + +You can also optionally [configure group mappings](#configure-group-mappings) to automatically assign Okta users to Metabase groups. + +See [authenticating with SAML](./authenticating-with-saml) for general SAML info. + +## Turn on SAML-based SSO in Metabase + +In the **Admin**>**Settings** section of the Admin area, go to the **Authentication** tab and click on **Set up** under **SAML**. + +You'll see a SAML configuration form like this: + +![SAML form](images/saml-form.png) + +You'll need to use the information in this form to set up SAML in Okta. + +## Set up SAML in Okta + +Before configuring SAML authentication in Metabase, you'll need to create a new SAML app integration in Okta. + +### Create an app integration in Okta + +From the Okta **Admin** console, [create a new SAML app integration][okta-saml-docs] to use with Metabase. + +### Configure Okta SAML settings + +To configure Okta app integration with Metabase, you'll need to use the information found in Metabase in the **Admin panel** > **Authentication** > **SAML** section. + +#### General settings + +| Okta SAML | Metabase SAML | +| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| **Single sign-on URL** | **URL the IdP should redirect to**. This is your Metabase [Site URL][site-url] -- it should start with `https://` and end with `/auth/sso`. | +| **Audience URI (SP Entity ID)** | **SAML Application Name** ("Metabase" by default) | + +#### Attribute statements + +In the **Attribute statements (optional)** section of the Okta application SAML setting, create the following attribute statements: + +- email address +- first name (given name) +- last name (surname) + +Even though Okta says these are optional, Metabase requires them. Okta will pass these attributes to Metabase during authentication to automatically log people in to Metabase. + +| Name | Value | +| -------------------------------------------------------------------- | -------------- | +| `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` | user.email | +| `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname` | user.firstName | +| `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname` | user.lastName | + +The names of attribute statement in Okta should match the attribute names in Metabase (names are case sensitive). If you want to use non-default attribute names in you Okta app configuration, you will also need to change the names for the attribute fields in Metabase in **Admin panel** > **Authentication** > **SAML**. + +> **Make sure that people [cannot edit their email address attribute](https://help.okta.com/oie/en-us/content/topics/users-groups-profiles/usgp-user-edit-attributes.htm)**. To log people in to your Metabase (or to create a Metabase account on first login), your IdP will pass the email address attribute to Metabase. If a person can change the email address attribute, they'll potentially be able to access Metabase accounts other than their own. + +### Example of an Okta assertion + +You can click **Preview SAML assertion** to view the XML file generated by Okta. It should look something like this: + +``` + + http://www.okta.com/Issuer + + userName + + + + + + + my-metabase-app + + + + + urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport + + + + + + Cam + + + + + Saul + + + + + cam@metabase.com + + + + +``` + +## Set up SAML in Metabase + +Once you set up your SAML app in Okta, you'll need to configure SAML in Metabase. You'll need some information from Okta: + +1. In Okta, go to the page for your Metabase app integration. +2. Go to the **Sign On** tab. +3. Click on **View SAML setup instructions**. + +Use the information from Okta SAML instructions to fill the Metabase SAML form in **Admin panel** > **Authentication** > **SAML**: + +| Metabase SAML | Okta SAML | +| ---------------------------------- | ------------------------------------ | +| SAML Identity Provider URL | Identity Provider Single Sign-On URL | +| SAML Identity Provider Certificate | X.509 Certificate\* | +| SAML Identity Provider Issuer | Identity Provider Issuer | + +\*Make sure to include any header and footer comments, like `---BEGIN CERTIFICATE---` and `---END CERTIFICATE---`. + +## Configure group mappings + +You can configure Metabase to automatically assign people to Metabase groups when they log in. You'll need to create a SAML attribute statement that will pass the groups information to Metabase, and then configure Metabase to read this attribute and map its contents to Metabase groups. + +You can use either: + +- [A custom user profile attribute](#use-a-user-profile-attribute-to-assign-groups) that contains user's Metabase groups. +- [Okta User Groups](#map-okta-user-groups-to-metabase-groups). + +### Use a user profile attribute to assign groups + +You can create a custom user profile attribute and fill it with the Metabase groups for each user. + +1. In Okta **Profile Editor**, [create a new User Profile attribute](https://help.okta.com/en-us/content/topics/users-groups-profiles/usgp-add-custom-user-attributes.htm) called `metabaseGroups`, which can be a `string` or a `string array`. + ![New User Profile attribute](images/okta-new-attribute.png) +2. For each user in Okta, fill the `metabaseGroups` attribute with their Metabase group(s). + + ![Metabase groups attribute](images/okta-adding-groups.png) + + We recommend that you use the same names for the groups in Okta as you would use in Metabase. + + Metabase groups don't have to correspond to Okta User Groups. If you'd like to use Okta User Groups to set up Metabase Groups, see [Map Okta User Groups to Metabase groups](#map-okta-user-groups-to-metabase-groups). + + > Your Okta account has to have `SAML_SUPPORT_ARRAY_ATTRIBUTES` enabled, as Metabase expects Okta to pass attributes as an array. If your Okta account is old, you might need to reach out to Okta support to enable `SAML_SUPPORT_ARRAY_ATTRIBUTES`. + +3. In the **Okta SAML settings** for the Metabase app integration, add a new attribute statement `MetabaseGroupName` with the value `user.metabaseGroups` (the profile attribute you just created) + + ![New attribute statement referencing the attribute](images/okta-new-attribute-custom.png) + +4. In **Metabase SAML settings**: + +- Turn on **Synchronize Group Memberships**. +- For each of the groups you added to Okta users, set up a new mapping to a Metabase group. +- In **Group attribute name**, enter `MetabaseGroupName` (the name of the SAML attribute statement). + + ![Metabase group mapping](images/saml-okta-groups.png) + +### Map Okta User Groups to Metabase groups + +1. Create Okta User groups corresponding to Metabase groups and assign them to Okta users. +2. In Okta's **SAML Settings** for the Metabase app integration, add a new attribute statement `MetabaseGroupName`, set the type to "Basic", and the value to: + + ``` + Arrays.flatten(getFilteredGroups({"groupID1", "groupID2"}, "group.name", 100)) + ``` + + where the Group IDs in `{"groupId1", "groupId2"}` are the groups that you would like to map to Metabase groups. You can find the Okta Group ID in the URL of the group's page: `https://your-okta-url.okta.com/admin/group/GROUP_ID`. + + This expression will retrieve the names of Okta User Groups that a user is a part of and return them as an array. + + ![New attribute statement for groups](images/okta-group-attribute.png) + + > Your Okta account has to have `SAML_SUPPORT_ARRAY_ATTRIBUTES` enabled, as Metabase expects Okta to pass attributes as an array. If your Okta account is old, you might need to reach out to Okta support to enable `SAML_SUPPORT_ARRAY_ATTRIBUTES`. + + Next, you'll need to tell Metabase how to map Okta groups to Metabase groups. + +3. In **Metabase SAML settings**: + +- Turn on **Synchronize Group Memberships**. +- For each of the groups you added to Okta users, set up a new mapping to a Metabase group. +- In **Group attribute name**, enter `MetabaseGroupName` (the name of the SAML attribute statement). + + ![Metabase group mapping](images/saml-okta-groups.png) + +## Troubleshooting SAML issues + +For common issues, go to [Troubleshooting SAML][troubleshooting-saml]. + +[enabling-saml-in-metabase]: ./authenticating-with-saml#enabling-saml-authentication-in-metabase +[okta-saml-docs]: https://help.okta.com/oie/en-us/content/topics/apps/apps_app_integration_wizard_saml.htm +[okta-create-attribute-statement]: https://support.okta.com/help/s/article/How-to-define-and-configure-a-custom-SAML-attribute-statement +[saml-doc]: ./authenticating-with-saml +[site-url]: ../configuring-metabase/settings#site-url +[troubleshooting-saml]: ../troubleshooting-guide/saml + +## Further reading + +- [User provisioning](./user-provisioning) diff --git a/_docs/doc-update-detection/people-and-groups/start.md b/_docs/doc-update-detection/people-and-groups/start.md new file mode 100644 index 000000000..0b1e2f7e4 --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/start.md @@ -0,0 +1,78 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: 'People and Groups' +title: 'People overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/start.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/sso +--- + +# People overview + +User accounts, groups, and authentication. For permissions, see [Permissions overview](../permissions/start). + +## [Editing your account settings](./account-settings) + +Edit your profile and password, and view your login history. + +## [Managing people and groups](./managing) + +Admin controls for setting up user accounts and organizing them into groups. + +## [Changing password complexity](./changing-password-complexity) + +Make people use longer and more complex passwords. + +## [Changing session expiration](./changing-session-expiration) + +Tell Metabase how long it should wait before asking people to log in again. + +## Authentication + +Metabase offers several options for authentication. + +> If you need to set up 2-step or multi-factor authentication (2FA or MFA) for your Metabase, consider using one of the SSO options below. + +### SSO for Metabase Open Source and Starter plans + +- [Google Sign-in](./google-sign-in) +- [LDAP](./ldap) + +### SSO for Metabase Pro and Enterprise plans + +With [Pro and Enterprise plans](/pricing/), you have more options to help orchestrate lots of people and groups. + +- [JWT][jwt] +- LDAP advanced features + - [Group membership filter](./ldap#ldap-group-membership-filter) + - [Syncing user attributes](./ldap#syncing-user-attributes-with-ldap) +- [SAML][saml] + - [Auth0][saml-auth0] + - [Microsoft Entra ID][azure-ad] + - [Google][saml-google] + - [Keycloak][saml-keycloak] + - [Okta][saml-okta] + +## [API keys](./api-keys) + +Create keys to authenticate API calls. + +## [User provisioning](./user-provisioning) + +Metabase supports user provisioning via the SCIM protocol. + +[azure-ad]: ./saml-azure +[google-sign-in]: ./google-and-ldap#enabling-google-sign-in +[jwt]: ./authenticating-with-jwt +[ldap]: ./google-and-ldap#enabling-ldap-authentication +[ldap-group-membership-filter]: ./google-and-ldap#ldap-group-membership-filter +[ldap-user-attributes]: ./google-and-ldap#syncing-user-attributes-with-ldap +[saml-okta]: ./saml-okta +[saml]: ./authenticating-with-saml +[saml-auth0]: ./saml-auth0 +[saml-google]: ./saml-google +[saml-keycloak]: ./saml-keycloak +[sso-def]: /glossary/sso diff --git a/_docs/doc-update-detection/people-and-groups/user-provisioning.md b/_docs/doc-update-detection/people-and-groups/user-provisioning.md new file mode 100644 index 000000000..1e077f71a --- /dev/null +++ b/_docs/doc-update-detection/people-and-groups/user-provisioning.md @@ -0,0 +1,72 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'People and Groups' +title: 'User provisioning with SCIM' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/people-and-groups/user-provisioning.md' +--- + +# User provisioning with SCIM + +{% include plans-blockquote.html feature="User provisioning with SCIM" %} + +Metabase supports user provisioning via the System for Cross-domain Identity Management (SCIM) protocol. In addition to Single Sign-on (SSO), you can set up user provisioning in Metabase with SCIM to: + +- **Decouple authentication from provisioning**. Even though anyone could authenticate with SSO, you may only want some people to be able to create an account in Metabase. +- **Support deprovisioning user accounts**. If you deactivate someone from your SSO, SCIM can let Metabase know to deactivate their Metabase account as well. + +> For now, Metabase officially supports SCIM for [Okta](https://help.okta.com/en-us/content/topics/apps/apps_app_integration_wizard_scim.htm?cshid=ext_Apps_App_Integration_Wizard-scim) and [Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/configure-automatic-user-provisioning-portal). Other SCIM providers may work, but we haven't tested them. If you're having issues with another identity provider, please [reach out to us](/help/premium). + +## Setting up user provisioning + +![Setting up user provisioning with SCIM in Metabase](./images/user-provisioning.png) + +To set up user provisioning. Click on the settings **Gear** icon in the upper right and navigate to **Admin settings** > **Settings**> **Authentication**. + +Click on the **User provisioning** tab. + +## User provisioning via SCIM + +To set up user provisioning with SCIM, hit the toggle to enable it. Metabase will tell you the SCIM endpoint URL and SCIM token to share with your identity provider. + +> If you've previously set up user provisioning with SAML, Metabase will turn that setting off and use the SCIM setup instead. + +## SCIM endpoint URL + +The SCIM endpoint is `/api/ee/scim/v2`. So your URL will looks something like: + +``` +https://metabase.example.com/api/ee/scim/v2 +``` + +Replacing the hostname with your Metabase's hostname. + +Share this endpoint URL with your identity provider. + +## SCIM token + +Copy the token and save the token somewhere safe. For security, Metabase can't show you the token again. You can, however, regenerate the token, but you'll need to let your identity provider know about the new token. + +## SCIM with Okta + +Once you've enabled SCIM in Metabase and gotten your SCIM endpoint URL and SCIM token, follow the docs for [Setting up SCIM in Okta](https://help.okta.com/en-us/content/topics/apps/apps_app_integration_wizard_scim.htm?cshid=ext_Apps_App_Integration_Wizard-scim). + +With Okta, Metabase supports user and group provisioning; groups are created and populated in Metabase. + +## SCIM with Microsoft Entra ID + +Once you've enabled SCIM in Metabase and gotten your SCIM endpoint URL and SCIM token, follow the docs for [Setting up SCIM in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/app-provisioning/configure-automatic-user-provisioning-portal). + +With Microsoft Entra ID, Metabase only supports user provisioning (groups aren't created or populated). + +## Notify admins of new users provisioned from SSO + +If you're not using SCIM to provision user accounts, you can optionally have Metabase send an email to admins whenever someone signs in to Metabase via SSO for the first time (which creates a Metabase account). This setting doesn't require you to set up SCIM. + +## Further reading + +- [Authenticating with SAML](./authenticating-with-saml) +- [SAML with Okta](./saml-okta) +- [SAML with Microsoft Entra ID](./saml-azure) diff --git a/_docs/doc-update-detection/permissions/application.md b/_docs/doc-update-detection/permissions/application.md new file mode 100644 index 000000000..b047bb7d1 --- /dev/null +++ b/_docs/doc-update-detection/permissions/application.md @@ -0,0 +1,50 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Permissions +title: 'Application permissions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/permissions/application.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/application-permissions +--- + +# Application permissions + +{% include plans-blockquote.html feature="Application permissions" %} + +Application settings are useful for granting groups access to some, but not all, of Metabase's administrative features. + +To set application permissions, got to the top right of the screen and click on the **gear** icon > **Admin settings** > **Permissions** > **Application**. + +## Settings access + +Settings access defines which groups can view and edit the settings under the Admin > Settings tab. These settings include: + +- [Settings](../configuring-metabase/settings) +- [Email](../configuring-metabase/email) +- [Slack](../configuring-metabase/slack) +- [Authentication](../people-and-groups/start) +- [Maps](../configuring-metabase/custom-maps) +- [Localization](../configuring-metabase/localization) +- [Appearance](../configuring-metabase/appearance) +- [Public sharing](../embedding/public-links) +- [Embedding in other applications](../embedding/start) +- [Caching](../configuring-metabase/caching) + +## Monitoring access + +Monitoring access sets permissions for the following: + +- [Tools](../usage-and-performance-tools/tools) +- [Troubleshooting](../troubleshooting-guide/index) + +## Subscriptions and alerts + +This setting determines who can set up: + +- [Dashboard subscriptions](../dashboards/subscriptions) +- [Alerts](../questions/alerts) + +People will need to be in groups with either view or edit access to the collection that contains the dashboard or question in order to set up alerts. See [Collection permissions](../permissions/collections). diff --git a/_docs/doc-update-detection/permissions/collections.md b/_docs/doc-update-detection/permissions/collections.md new file mode 100644 index 000000000..83d3c74e6 --- /dev/null +++ b/_docs/doc-update-detection/permissions/collections.md @@ -0,0 +1,127 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Permissions +title: 'Collection permissions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/permissions/collections.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/06-collections +--- + +# Collection permissions + +![Collection detail](./images/collection-detail.png) + +You can use [collections](../exploration-and-organization/collections) to organize questions, dashboards, models, timelines, and other collections. You can set permissions on those collections to determine which groups of people can view and curate collections' items. + +Metabase starts out with a default top-level collection which is called **Our analytics**, which every other collection is saved inside of. + +## Collection permission levels + +There are three permission levels for collections: + +- [Curate access](#curate-access) +- [View access](#view-access) +- [No access](#no-access) + +| Action | Curate Access | View Access | No Access | +| ---------------------------------- | ------------- | ----------- | --------- | +| View items | ✅ | ✅ | ❌ | +| Edit items' title and descriptions | ✅ | ❌ | ❌ | +| Move items | ✅ | ❌ | ❌ | +| Delete items | ✅ | ❌ | ❌ | +| Pin items | ✅ | ❌ | ❌ | +| View events and timelines | ✅ | ✅ | ❌ | +| Edit events and timelines | ✅ | ❌ | ❌ | + +### Curate access + +The group can view, edit, move, delete, and pin items saved in this collection, and can save or move new items into it. The group can also create new sub-collections within this collection. The group can also create and edit [events and timelines](../exploration-and-organization/events-and-timelines). + +### View access + +The group can see all the questions, dashboards, and models in the collection, as well as [events and timelines](../exploration-and-organization/events-and-timelines). + +### No access + +The group won't see this collection listed, and they'll lack access to any of the items saved within it. + +## Collection vs data permissions + +Collection permissions only apply to viewing and curating existing questions, models, and dashboards. Changing the query on an existing question, or creating a new question, requires that the group have [data permissions](./data) for the underlying data. + +There is one, important exception: when a group has their data permission set to [Block](./data#blocked-view-data-permission) for a database or table, the group won't be able to view questions based on that data, even if they have curate access to the collection where those questions are saved. + +## Dashboards with questions from multiple collections + +If a dashboard includes questions saved to other collections, the group will need view or curate access to all of those collections in order to view those questions. If not, Metabase will apologize and tell you that you lack permissions to see the cards saved to the other collections. + +![Dashboard with questions from multiple collections, where the person is not in a group with access to one of the collections](./images/dashboard-no-permissions.png) + +In general, it's easier to manage permissions when keeping all of a dashboard's questions in the same collection. + +## Setting permissions for collections + +You can set permissions on collections by clicking on the lock icon in the top-right of the screen while viewing the collection and clicking on **Edit permissions**. Only Administrators can edit collection permissions. Each [user group](./introduction) can have either View, Curate, or No access to a collection: + +![Permissions](./images/collection-permissions.png) + +If you want to see the bigger picture of what permissions your user groups have for all your collections, just click the link that says **See all collection permissions**, which takes you to the Admin Panel. You'll see a list of your collections down along the left, and clicking on any of those will bring up a list of each group's permission settings for that collection. + +![Collection Permissions](./images/admin-panel-collections.png) + +Just like with data access permissions, collection permissions are _additive_, meaning that if a user belongs to more than one group, if one of their groups has a more restrictive setting for a collection than another one of their groups, they'll be given the _more permissive_ setting. This is especially important to remember when dealing with the All Users group: since all users are members of this group, if you give the All Users group Curate access to a collection, then _all_ users will be given Curate access for that collection, even if they also belong to a group with _less_ access than that. + +## Permissions and sub-collections + +A group can be given access to a collection located somewhere within one or more sub-collections _without_ having to have access to every collection "above" it. For example, if a group had access to the "Super Secret Collection" that's saved several layers deep within a "Marketing" collection that the group lacks access to, the "Super Secret Collection" would show up at the top-most level that the group _does_ have access to. + +## Deleting collections + +Users with curate permission for a collection can move collections to Trash, see [Delete and Restore](../exploration-and-organization/delete-and-restore). + +## Pinning items in collections + +![Pins](./images/pinned-items.png) + +People in groups with Curate access to a collection can pin items in the collection. Pinning an item in a collection turns the item into a handsome card at the top of the collection. + +To pin an item, select the **pin icon** next to the item's name. + +Note that collections themselves can't be pinned. If you're running on a [Pro or Enterprise plan](/pricing/), admins can designate [Official Collections][offical-collections]. + +## Special collections + +### Our analytics + +The "Our analytics" collection and individual personal collections are invincible; they cannot be archived, injured, or slain. They are eternal. + +### Usage analytics + +See [Usage analytics](../usage-and-performance-tools/usage-analytics). + +### Personal collections + +Each person has a personal collection where they're always allowed to save things, even if they don't have Curate permissions for any other collections. + +Administrators can see and edit the contents of every user's personal collection (even those belonging to other Administrators) by clicking on the **Other users' personal collections** link at the bottom of the sidebar when viewing "Our analytics". + +A personal collection works just like any other collection except that its permissions are fixed and cannot be changed. If a sub-collection within a personal collection is moved to a different collection, the sub-collection will inherit the permissions of its new parent collection. + +## Further reading + +- [Working with collection permissions][collection-permissions]. + +[collections]: ../exploration-and-organization/collections +[collection-permissions]: /learn/metabase-basics/administration/permissions/collection-permissions +[dashboard-subscriptions]: ../dashboards/subscriptions +[data-permissions]: ./data +[data-sandboxing]: ../permissions/data-sandboxes +[offical-collections]: ../exploration-and-organization/collections#official-collections +[permissions]: /learn/metabase-basics/administration/permissions +[sandbox-columns]: /learn/metabase-basics/administration/permissions/data-sandboxing-column-permissions +[sandbox-rows]: /learn/metabase-basics/administration/permissions/data-sandboxing-row-permissions +[slack-integration]: ../configuring-metabase/slack +[sql-snippet-folders]: ../questions/native-editor/snippets diff --git a/_docs/doc-update-detection/permissions/data-sandbox-examples.md b/_docs/doc-update-detection/permissions/data-sandbox-examples.md new file mode 100644 index 000000000..7c4121b29 --- /dev/null +++ b/_docs/doc-update-detection/permissions/data-sandbox-examples.md @@ -0,0 +1,153 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Permissions +title: 'Data sandbox examples' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/permissions/data-sandbox-examples.md' +--- + +# Data sandbox examples + +{% include plans-blockquote.html feature="Data sandboxes" %} + +[Data sandboxes](./data-sandboxes) let you: + +- Restrict **rows** using a [basic sandbox](./data-sandboxes#basic-data-sandboxes-filter-by-a-column-in-the-table). +- Restrict **columns** (and rows) using a [custom sandbox](./data-sandboxes#custom-data-sandboxes-use-a-saved-question-to-create-a-custom-view-of-a-table). + +## Setup for all examples below + +The examples below use the Sample database included with Metabase. Here's the basic setup: + +1. **Block permissions for the All users group**: Hit cmd/ctrl + k to bring up the command palette and search for "Permissions". In the **Permissions** > **Data** tab. Click on the **All users** group. For the Sample database, set the All User's [View data](./data#view-data-permissions) permission to "Blocked". + +2. **Create a group called Customers**. Hit cmd/ctrl + k and search for the People settings. [Create a group called "Customers". + +3. **Create a user account for Cloyd Beer**. We'll [create a user account](../people-and-groups/managing#creating-an-account) for a random person from the People table in our Sample Database. Let's go with `Cloyd Beer` from the Sample database's `People` table. + +4. **Add a user attribute to the account**: We'll add a user attribute to Cloyd's account. Since we want to be able to filter the data by user ID, we'll grab Cloyd's ID from the Sample database's `People` table and add the ID as a [user attribute](../people-and-groups/managing#adding-a-user-attribute): `user_id: 2499` (`2499` is Mr. Beer's ID in the Sample database). + +![User details](images/edit-user-details.png) + +5. **Add Mr. Beer to the Customers group**: See [adding people to groups](../people-and-groups/managing#adding-people-to-groups). + +6. **Create a collection that is only viewable by Admins.**. Call it "Admin collection". We'll use this collection to store SQL questions that we use to sandbox tables in examples 2 and 3. See [Collection permissions](./collections). + +## Basic sandbox setup - filtering rows based on user attributes + +In this example, we’ll sandbox our `Orders` table so that anyone in our Customers group will only be able to see rows in the Orders table where the `User ID` column matches the person's `user_id` attribute. + +1. **Go to the Admin settings > Permissions > data**. Click on the "Customers" group. + +2. **Set View data to Granular**. For the Sample Database, set the Customer group's [View data](./data#view-data-permissions) to "Granular". Setting to "Granular" will allow us to set up permissions on individual tables for the Customer group. + +3. **Sandbox the Orders and People tables**. Here, we'll set the View data permissions on the `Orders` and `People` tables to "Sandboxed". And since we want people to self-serve their data (by asking questions, creating dashboards, etc.), we'll also set their [Create queries](../permissions/data#create-queries-permissions) permission to "Query builder only." + +![Grant sandboxed access](images/grant-sandboxed-access.png) + +4. **Filter by a column for each table.** For each table, Metabase will ask us "How do you want to filter this table for users in this group?". In each case, we'll keep the default selection: "Filter by a column on this table." For the `Orders` table, we'll filter by the `User ID` column, which we'll set equal to the `user_id` attribute for people in the Customers group. + +![Sandbox settings](images/select-user-attribute.png) + +For the `People` table, we'll filter by the `ID` column, which we'll set equal to that same `user_id` attribute. + +5. **Save your changes**. Otherwise, all is for naught. + +### Testing out the basic sandbox + +To test out Mr. Beer's sandbox, we’ll open up a new incognito/private browser window and log in using Mr. Beer's account. + +1. Log in as Cloyd Beer. +2. Click **Browse** > **Databases**. +3. Click on the **Orders** table. +4. Confirm that Metabase displays only the orders that Mr. Beer placed, that is, orders associated with the User ID of `2499`. + +If Mr. Beer views any charts, dashboards, or even automated [X-ray explorations](../exploration-and-organization/x-rays) that include the sandboxed `Orders` data, Metabase will also filter those results to show only the data Mr. Beer is permitted to see. When Mr. Beer uses the query builder to ask new questions, his results will be limited to the sandboxed data. + +## Custom sandbox setups + +The second way you can create a sandbox is by using a saved question to define a customized view of a table to display. When someone with sandboxed access to a table queries that table, behind the scenes Metabase will instead use the saved question you created as the source data for their query. + +You can: + +- [Filter out columns](#custom-example-1-filtering-columns) +- [Filter out rows and columns](#custom-example-2-filtering-rows-and-columns) + +## Custom example 1: filtering columns + +In this example, we have a table called `People` that we want to trim down so that Mr. Beer and other Customers can view any row, but only some columns. + +![Original People table](images/advanced-example-1-people-table.png) + +1. **Create a query that limits the columns in the People table.** Using the native/SQL editor, we'll write a query that only returns the columns in that table that we _do_ want our Customers group to see, like this: + +```sql + ID, + Name, + 'Created At', + State +FROM + People +``` + +Here are the results: + +![Filtering question](images/advanced-example-1-filtering-question.png) + +We'll call this question "Filtered people table". Save it to the "Admins collection" you created in the setup (or any collection that only Admins have access to). + +2. **Use a saved question to create a custom view for this table**: We'll go to the Permissions section and grant this group sandboxed access to this table. This time we'll select the second option, "Use a saved question to create a custom view for this table", and select the saved question we just created ("Filtered people table"), like so: + +![Sandbox options](images/advanced-example-1-sandbox-modal.png) + +3. **Save changes**, lest our toil matter not. + +4. **Verify things are working correctly**. We can log in as Mr. Beer, and when we go to open up the `People` table, we should see that Mr. Beer can instead see the results of the filtering question. + +When Mr. Beer views a chart that uses data from this sandboxed table, Metabase will also apply the filtering. **If the chart uses any columns excluded by the sandboxed table, the chart will NOT load for Mr. Beer.** + +## Custom example 2: Filtering rows and columns + +If we want to specify which columns _and_ rows people can view, we can sandbox a table based on a SQL question with a variable, and associate that variable with a user attribute. To do that, we'll give our Customers group a custom view of the `Orders` table, but only let each person see rows based on their `user_id` user attribute. + +1. **Create a SQL question with a variable**. We'll create a query that selects only some of the columns from the `Orders` table, and then add a `WHERE` clause with a variable that we can associate with Cloyd Beer's `user_id` user attribute. + +![Filtering question](images/advanced-example-2-filtering-question.png) + +And here's the code: + +```sql +{% raw %} +SELECT + id, + created_at, + product_id, + quantity, + total, + user_id +FROM + orders +WHERE + user_id = {{user_id}} +{% endraw %} +``` + +Save it to the "Admins collection" you created in the setup (or any collection that only Admins have access to). + +2. **Set up the sandbox**: Return to the **Permissions** tab. Select Cloyd Beer's Customer group, and set the **View data** access for the `Orders` table to **Sandboxed**. Select **Use a saved question to create a custom view for this table**. Open up the sandboxed access modal and select the second option and select my filtering question, we'll see an additional section which allows me to map the variable we defined in our question with a user attribute: + +![Sandboxing options](images/advanced-example-2-sandboxing-options.png) + +3. **Save your changes**. Or abandon all hope. + +4. **Verify the sandbox**: Now, when we log in as Mr. Beer and look at the `Orders` table, Mr. Beer will only see the columns we included in the filtering question, and the rows are filtered as specified by the variable in the question's `WHERE` clause: + +![Results](images/advanced-example-2-results.png) + +## Further reading + +- [Basic sandboxes: setting row-level permissions](/learn/metabase-basics/administration/permissions/data-sandboxing-row-permissions) +- [Custom sandboxes: limiting access to columns](/learn/metabase-basics/administration/permissions/data-sandboxing-column-permissions) +- [Configuring permissions for different customer schemas](/learn/metabase-basics/administration/permissions/multi-tenant-permissions) diff --git a/_docs/doc-update-detection/permissions/data-sandboxes.md b/_docs/doc-update-detection/permissions/data-sandboxes.md new file mode 100644 index 000000000..27d7b5700 --- /dev/null +++ b/_docs/doc-update-detection/permissions/data-sandboxes.md @@ -0,0 +1,280 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Permissions +title: 'Data sandboxes' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/permissions/data-sandboxes.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/data-sandboxes +--- + +# Data sandboxes + +{% include plans-blockquote.html feature="Data sandboxes" %} + +Data sandboxes let you give granular permissions to rows and columns for different groups of people. You can sandbox what data a group [can view](./data#can-view-data-permission), as well as what data a group [can query](./data#create-queries-permissions) with the query builder. + +You can use sandboxes to set up [self-service analytics](/learn/metabase-basics/embedding/multi-tenant-self-service-analytics), so that each of your customers only views the rows that match their customer ID. For example, if you have an Accounts table with information about your customers, you can sandbox that table so that each customer only sees the data relevant to them. + +## Data sandbox examples + +You can skip the theory and go [straight to sandbox examples](data-sandbox-examples). + +## How sandboxes work + +You can think of a data sandbox as a bundle of permissions that includes: + +- The filtered version of a table that will replace your original table, everywhere that the original table is used in Metabase. +- The [group](../people-and-groups/managing#groups) of people who should see the filtered version of the table. + +You can define up to one data sandbox for each table/group combo in your Metabase. That means you can display different versions of a table for different groups, such as "Sandboxed Accounts for Sales" to your salespeople, and "Sandboxed Accounts for Managers" for sales managers. + +## Types of data sandboxes + +Data sandboxes show specific data to each person based on their [user attributes](../people-and-groups/managing#adding-a-user-attribute). You can: + +- Restrict **rows** for specific people with a [basic sandbox](#basic-data-sandboxes-filter-by-a-column-in-the-table). +- Restrict **columns** (as well as rows) for specific people with a [custom sandbox](#custom-data-sandboxes-use-a-saved-question-to-create-a-custom-view-of-a-table) (also known as an advanced sandbox). + +| | Basic sandbox (filter by a column in the table) | Custom sandbox (use a saved SQL question) | +| ---------------------------------------------- | ----------------------------------------------- | ----------------------------------------- | +| Restrict rows by filtering on a single column | ✅ | ✅ | +| Restrict rows by filtering on multiple columns | ❌ | ✅ | +| Restrict columns | ❌ | ✅ | +| Edit columns | ❌ | ✅ | + +### Basic data sandboxes: filter by a column in the table + +To **restrict rows**, use a basic sandbox. A basic sandbox displays a filtered version of a table instead of the original table to a group. The filter works by setting a column in the table to a specific [user attribute value](#choosing-user-attributes-for-data-sandboxes). + +For example, you can create a basic sandbox to filter the Accounts table for a group so that: + +- A person with the user attribute value "Basic" will see rows where `Plan = "Basic"` (rows where the Plan column matches the value "Basic"). +- A person with the user attribute value "Premium" will see the rows where `Plan = "Premium"` (rows where the Plan column matches the value "Premium"). + +### Custom data sandboxes: use a saved question to create a custom view of a table + +To **restrict columns** as well as rows, use a custom sandbox (also known as an advanced sandbox). A custom sandbox displays the results of a saved SQL question in place of your original table. + +For example, say your original Accounts table includes the columns: `ID`, `Email`, `Plan`, and `Created At`. If you want to hide the Email column, you can create a "Sandboxed Accounts" SQL question with the columns: `ID`, `Plan`, and `Created At`. + +A custom sandbox will display the "Sandboxed Accounts" question result instead of the original Accounts table, to a specific group, everywhere that Accounts is used in Metabase. + +You can also use a custom sandbox to: + +- [Display an edited column instead of hiding the column](#displaying-edited-columns-in-an-custom-sandbox). +- [Pass a user attribute to a SQL parameter](#restricting-rows-in-an-custom-sandbox-with-user-attributes). +- [Pass a user attribute to a Markdown parameter](/learn/metabase-basics/querying-and-dashboards/dashboards/markdown#custom-url-with-a-sandboxing-attribute). + +## Limitations + +Things that don't play well in a sandbox. + +### Groups with native query permissions (access to the SQL editor) cannot be sandboxed + +You can't set up [query builder and native](./data#create-queries-permissions) for sandboxed groups. + +To enforce row-level permissions with the native query editor, check out [impersonation](./impersonation). + +### SQL questions cannot be sandboxed + +Since Metabase can't parse SQL queries, the results of SQL questions will always use original tables, not sandboxed tables. + +[Use collection permissions](#saved-sql-questions-cannot-be-sandboxed) to prevent sandboxed groups from viewing saved SQL questions with restricted data. + +### Non-SQL databases cannot be sandboxed + +Data sandbox permissions are unavailable for non-SQL databases such as Apache Druid or MongoDB. + +## Prerequisites for basic sandboxes + +- A [group](../people-and-groups/managing#groups) of people to be added to the basic sandbox. +- [User attributes](../people-and-groups/managing#adding-a-user-attribute) for each person in the group. + +A basic sandbox displays a filtered table, in place of an original table, to a specific group. How Metabase filters that table depends on the value in each person's user attribute. + +For example, you can set up a basic sandbox so that: + +- Someone with the user attribute with key of "plan" and a value of "Basic" will see a version of the Accounts table with a filter for `Plan = "Basic"` (that is, only the rows where the Plan column matches the value "Basic"). +- Someone with a "plan" user attribute set to "Premium" will see a different version of the Accounts table with the filter `Plan = "Premium"` applied. + +## Choosing user attributes for data sandboxes + +**User attributes are required for basic sandboxes, and optional for custom sandboxes**. When [adding a new user attribute](../people-and-groups/managing#adding-a-user-attribute), you'll set up a key-value pair for each person. + +Metabase uses the user attribute key to look up the user attribute value for a specific person. User attribute keys can be mapped to parameters in Metabase. + +The **user attribute value** must be an exact, case-sensitive match for the filter value of a sandboxed table. For example, if you're creating a [basic sandbox](#basic-data-sandboxes-filter-by-a-column-in-the-table) on the Accounts table with the filter `Plan = "Basic"`, make sure that you enter "Basic" as the user attribute value. If you set the user attribute value to lowercase "basic" (a value which doesn't exist in the Plan column of the Accounts table), the sandboxed person will get an empty result instead of the sandboxed table. + +Examples of user attributes in play: + +- [Restricting rows in basic sandboxes](./data-sandbox-examples#basic-sandbox-setup---filtering-rows-based-on-user-attributes) +- [Restricting rows in custom sandboxes](./data-sandbox-examples#custom-example-2-filtering-rows-and-columns) +- [Displaying custom text in Markdown dashboard cards](/learn/metabase-basics/querying-and-dashboards/dashboards/markdown#custom-url-with-a-sandboxing-attribute) + +## Creating a basic sandbox + +1. Make sure to do the [prerequisites for basic sandboxes](#prerequisites-for-basic-sandboxes) first. +2. Go to **Admin settings** > **Permissions**. +3. Select the database and table that you want to sandbox. +4. Find the group that you want to put in the sandbox. +5. Click on the dropdown under **View data** for that group. +6. Select "Sandboxed". +7. Click the dropdown under **Column** and enter the column to filter the table on, such as "Plan". +8. Click the dropdown under **User attribute** and enter the user attribute **key**, such as "Plan". + +> If you have saved SQL questions that use sandboxed data, make sure to move all of those questions to admin-only collections. For more info, see [Permissions conflicts: saved SQL questions](#saved-sql-questions-cannot-be-sandboxed). + +You can find a sample basic sandbox setup in the [Data sandbox examples](./data-sandbox-examples). + +## Prerequisites for custom sandboxes + +- A [group](../people-and-groups/managing#groups) of people to be added to the advanced data sandbox. +- An admin-only [collection](../exploration-and-organization/collections), with [collection permissions](../permissions/collections) set to **No access** for all groups except Administrators. +- A [saved SQL question](../questions/native-editor/writing-sql) with the rows and columns to be displayed to the people in the custom sandbox, stored in the admin-only collection. +- Optional: if you want to restrict **rows** in a custom sandbox, set up [user attributes](#choosing-user-attributes-for-data-sandboxes) for each of the people in the group. + +### Creating a SQL question for Metabase to display in an custom sandbox + +In an advanced data sandbox, Metabase will display a saved question in place of an original table to a particular group. + +**Use a SQL question** to define the exact rows and columns to be included in the sandbox. If you use a query builder (GUI) question, you might accidentally expose extra data, since GUI questions can include data from other saved questions or models. + +> Make sure to save the SQL question in an admin-only collection ([collection permissions](../permissions/collections) set to **No access** for all groups except Administrators). For more info, see [Permissions conflicts: saved SQL questions](#saved-sql-questions-cannot-be-sandboxed). + +### Displaying edited columns in an custom sandbox + +Aside from excluding rows and columns from an custom sandbox, you can also **display edited columns** (without changing the columns in your database). + +For example, you can create a "Sandboxed Accounts" SQL question that truncates the Email column to display usernames instead of complete email addresses. + +If you edit a column, the schema of the saved SQL question (the question you want to display in the sandbox) must match the schema of the original table. That means the "Sandboxed Accounts" SQL question must return the same number of columns and corresponding data types as the original Accounts table. + +You cannot add a column to a custom sandbox. + +## Creating a custom sandbox + +1. Make sure to do the [prerequisites for custom sandboxes](#prerequisites-for-custom-sandboxes) first. +2. Go to **Admin settings** > **Permissions**. +3. Select the database and table that you want to sandbox. +4. Find the group that you want to put in the sandbox. +5. Click on the dropdown under **Data access** for that group. +6. Select "Sandboxed". +7. Select "Use a saved question to create a custom view for this table". +8. Select your saved question. The question should be written in SQL. If the question contains parameters, those parameters must be required (they cannot be optional). +9. Optional: [restrict rows based on people's user attributes](#restricting-rows-in-an-custom-sandbox-with-user-attributes). + +> If you have saved SQL questions that use sandboxed data, make sure to move all of those questions to admin-only collections. + +You can find sample custom sandbox setups in the [Data sandbox examples](./data-sandbox-examples). + +## Restricting rows in an custom sandbox with user attributes + +You can set up an custom sandbox to restrict different rows for each person depending on their [user attributes](../people-and-groups/managing#adding-a-user-attribute). For example, you can display the "Sandboxed Accounts" question with the filter `Plan = "Basic"` for one group, and the filter `Plan = "Premium"` for another group. + +1. Make sure you've done all the [prerequisites for custom sandboxes](#prerequisites-for-custom-sandboxes). +2. Go to the saved SQL question that will be displayed to the people in the custom sandbox. +3. Add a [parameterized](../questions/native-editor/sql-parameters) `WHERE` clause to your SQL query, such as `{%raw%}WHERE plan = {{ plan_variable }} {%endraw%}`. +4. Save the SQL question. +5. Go to **Admin settings** > **Permissions**. +6. Find the group and table for your custom sandbox. +7. Open the dropdown under **View data**. +8. Click **Edit sandboxed access**. +9. Scroll down and set **Parameter or variable** to the name of the parameter in your saved SQL question (such as "Plan Variable"). +10. Set the **User attribute** to a [user attribute key](#choosing-user-attributes-for-data-sandboxes) (such as the key "User's Plan", _not_ the value "Basic"). +11. Click **Save**. + +For a sample SQL variable and user attribute setup, see the [Data sandbox examples](./data-sandbox-examples). + +### How row restriction works in an custom sandbox + +How user attributes, SQL parameters, and custom sandboxes work together to display different rows to different people. + +A standard `WHERE` clause filters a table by setting a column to a fixed value: + +```sql +WHERE column_name = column_value +``` + +In step 2 of the [row restriction setup](#restricting-rows-in-an-custom-sandbox-with-user-attributes) above, you'll add a SQL variable so that the `WHERE` clause will accept a dynamic value. The [SQL variable type](../questions/native-editor/sql-parameters#sql-variable-types) must be text, number, or date: + +```sql +WHERE plan = {%raw%}{{ plan_variable }}{%endraw%} +``` + +In steps 9-10 of the [row restriction setup](#restricting-rows-in-an-custom-sandbox-with-user-attributes) above, you're telling Metabase to map the SQL variable `plan_variable` to a **user attribute key** (such as "User's Plan"). Metabase will use the key to look up the specific **user attribute value** (such as "Basic") associated with a person's Metabase account. When that person logs into Metabase and uses the sandboxed table, they'll see the query result that is filtered on: + +```sql +WHERE plan = "Basic" +``` + +Note that the parameters must be required for SQL questions used to create a custom sandbox. E.g., you cannot use an optional parameter; the following won't work: + +```sql +[[WHERE plan = {%raw%}{{ plan_variable }}{%endraw%}]] +``` + +Learn more about [SQL parameters](../questions/native-editor/sql-parameters) + +## Preventing data sandbox permissions conflicts + +Some Metabase permissions can conflict with data sandboxes to give more permissive or more restrictive data access than you intended. + +Say you have an [custom sandbox](#custom-data-sandboxes-use-a-saved-question-to-create-a-custom-view-of-a-table) that hides the Email column from the Accounts table (for a particular group). + +The Email column may get exposed to a sandboxed person if: + +- The sandboxed person belongs to [multiple data sandboxes](#multiple-data-sandbox-permissions). +- A non-sandboxed person shares the Email column from: + - A saved [SQL question](../questions/native-editor/writing-sql). + - A [public link](#public-sharing) + - An [alert, or dashboard subscription](../permissions/notifications) + +### Multiple data sandbox permissions + +Multiple data sandboxes on the same table can create a permissions conflict. You can add a person to a maximum of one data sandbox per table (via the person's group). + +For example, if you have: + +- One sandbox for the group "Basic Accounts" that filters the Accounts table on `Plan = "Basic"`. +- Another sandbox for the group "Converted Accounts" that filters the Accounts table on `Trial Converted = true`. + +If you put Vincent Accountman in both groups, he'll be in conflicting sandboxes for the Accounts table, and get an error message whenever he tries to use Accounts in Metabase. + +To resolve data sandbox permissions conflicts: + +- Remove the person from all but one of the groups. +- Set the all but one of the group's [View data](./data#view-data-permissions) access to the datatabase to "Blocked". + +### Saved SQL questions cannot be sandboxed + +Data sandbox permissions don't apply to the results of SQL questions. That is, saved SQL questions will always display results from the original table rather than the sandboxed table. + +Say that you have an custom sandbox which hides the Email column from the Accounts table. If a non-sandboxed person creates a SQL question that includes the Email column, **anyone with collection permissions to view that SQL question** will be able to: + +- See the Email column in the SQL question results. +- Use the SQL question to start a new question that includes the Email column. + +To prevent the Email column from being exposed via a SQL question: + +- Put any SQL questions that include the Email column in a separate collection. +- Set the [collection permissions](../permissions/collections) to **No access** for sandboxed groups that should not see the Email column. + +[Collection permissions](../permissions/collections) must be used to prevent sandboxed groups from viewing saved SQL questions that reference sandboxed tables. That's why, when you create an custom sandbox, you have to put the saved SQL question (the one you want to display in the sandbox) in an admin-only collection. + +### Public sharing + +Data sandbox permissions don't apply to public questions or public dashboards. If a non-sandboxed person creates a public link using an original table, the original table will be displayed to anyone who has the public link URL. + +To prevent this from happening, you'll have to [disable public sharing](../embedding/public-links) for your Metabase instance. + +Metabase can only create a data sandbox using the group membership or user attributes of people who are logged in. Since public links don’t require logins, Metabase won’t have enough info to create the sandbox. + +## Further reading + +- [Data sandbox examples](./data-sandbox-examples) +- [Permissions strategies](/learn/metabase-basics/administration/permissions/strategy) +- [Configuring permissions for different customer schemas](/learn/metabase-basics/administration/permissions/multi-tenant-permissions) +- [Securing embedded Metabase](/learn/metabase-basics/embedding/securing-embeds) diff --git a/_docs/doc-update-detection/permissions/data.md b/_docs/doc-update-detection/permissions/data.md new file mode 100644 index 000000000..5dd376fa3 --- /dev/null +++ b/_docs/doc-update-detection/permissions/data.md @@ -0,0 +1,198 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Permissions +title: 'Data permissions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/permissions/data.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/data-permissions +--- + +# Data permissions + +This page covers permissions for databases and tables. If you haven't already, check out our [Permissions overview][permissions-overview]. + +## Setting permissions on a database, schema, or table + +To set data permissions on a database, schema, or table for a group: + +1. Hit Cmd/Ctrl + K. Search for **Permissions** and click on the Permissions settings result. Metabase will default to the **Data** tab. + +Or + +1. Click on the **gear** icon in the upper right. + +2. Select **Admin settings**. + +3. Click on the **Permissions** tab, which defaults to the **Data** tab. + +You can view permissions either by group or by database. + +## Data permission types + +You can set the following types of permissions on a database, schema, or table: + +- [View data](#view-data-permissions) +- [Create queries](#create-queries-permissions) +- [Download results](#download-results-permissions) +- [Manage table metadata](#manage-table-metadata-permissions) +- [Manage database](#manage-database-permissions) + +> If you're upgrading from a version below Metabase 50, your permission levels may look different, but the data access hasn't changed. See [what's changed with data permissions and why](./no-self-service-deprecation). + +## View data permissions + +{% include plans-blockquote.html feature="View data permissions" %} + +The **View data** permission determines what data people can see when viewing questions, dashboards, models, and metrics. View data permissions also determine whether a group can view the models and metrics browsers in the sidebar. To [browse databases](../exploration-and-organization/exploration#browse-your-databases), a group will also need [Create queries](#create-queries-permissions) permissions for the relevant data. + +Permission levels include: + +- [Can view](#can-view-data-permission) +- [Granular](#granular-view-data-permission) +- [Sandboxed](#sandboxed-view-data-permission) +- [Impersonated](#impersonated-view-data-permission) +- [Blocked](#blocked-view-data-permission) + +View data permission settings apply to different levels in your database: + +| View data permission | Database | Schema | Table | +| -------------------- | -------- | ------ | ----- | +| Can view | ✅ | ✅ | ✅ | +| Granular\* | ✅ | ✅ | ❌ | +| Sandboxed | ❌ | ❌ | ✅ | +| Impersonated | ✅ | ❌ | ❌ | +| Blocked | ✅ | ✅ | ✅ | + +\* The "Granular" setting is not itself a type of permission; it just signals that permissions are set at a level below the current level. For example, you can select "Granular" at a schema level to set permissions per table for tables in that schema. + +In the free, open-source version of Metabase, the **View data** setting defaults to "Can view". Since the setting's options aren't available in the OSS version, Metabase will only display this **View data** setting in the Pro/Enterprise version. + +For _which_ questions, models, and dashboards a group can view, instead see [collection permissions](collections). + +### Can view data permission + +{% include plans-blockquote.html feature="Can view data permission" %} + +Setting to **Can view** means the group can view all the data for the data source, provided they have [collection permissions](./collections) to view questions, models, and dashboards. + +In order to view the data in the [Browse databases](../exploration-and-organization/exploration#browse-your-databases) section, the group would additionally need to be able to [Create queries](#create-queries-permissions). + +### Granular view data permission + +{% include plans-blockquote.html feature="Granular view data permission" %} + +This option lets you set View data permissions for individual schemas or tables. Available only for databases and schemas. If you select Granular for a database or schema, Metabase will open that data source and ask you to set permissions for each individual schema or table. + +For tables, you have the option to set either **Can view** or **Sandboxed**. + +### Sandboxed view data permission + +{% include plans-blockquote.html feature="Sandboxed view data permission" %} + +Allows you to set row-level permissions based on user attributes. Can only be configured at the table level. + +See [Data sandboxes](./data-sandboxes). + +### Impersonated view data permission + +{% include plans-blockquote.html feature="Impersonated view data permission" %} + +The **Impersonated** option lets you use a role in your database to specify what data people can view and query. Impersonation can only be set at the database level, as Metabase will defer to the permissions granted to the database role. + +See [impersonated view data permissions](./impersonation) + +### Blocked view data permission + +{% include plans-blockquote.html feature="Blocked view data permission" %} + +**Blocked** ensures people in a group can’t see the data from this database, schema, or table, regardless of their permissions at the collection level. + +The Blocked view data permission can be set at the database, schema, or table level. Essentially, what Blocked does is make collections permissions _insufficient_ to view a question. For example, even if a question is in a collection that the group has access to, but that question queries a data source that is Blocked for that group, people in that group won't be able to view that question _unless_ they're in another group with the data permissions to that data source. + +Setting blocked access for a group ALWAYS prevents the group from viewing questions built with the native query editor that query ANY tables from the same database. So even if you only block a single table in a database, the group won't be able to view the results of SQL questions that query ANY table in that database. The reason: Metabase doesn't (yet) parse SQL queries, so it can't know for sure whether the SQL queries the table you want to block. + +If a person in a Blocked group belongs to _another_ group that has its View data permission set to "Can view", that more permissive access will take precedence, and they'll be able to view that question. + +## Create queries permissions + +Specifies whether a group can create new questions based on the data source. Creating queries includes the ability to drill-through and filter questions, or anything that involves changing the results. This permission also determines whether a group will get access to the [database browser](../exploration-and-organization/exploration#browse-your-databases) to explore that data source. + +To enable Create queries permissions for a group, that group must be able to view the data source ("Can view" permission.) + +Create query levels include: + +### Query builder and native create queries permission + +People can use Metabase's query builder or its native/SQL editor. + +### Query builder only create queries permission + +People can create new questions and drill-through existing questions using Metabase's query builder. + +### Granular + +The granular option lets you define Create queries permissions for each schema and/or table in the database. + +## Download results permissions + +{% include plans-blockquote.html feature="Download permissions" %} + +You can set permissions on whether people in a group can download results (and how many rows) from a data source. Options are: + +- No (they can't download results) +- Granular (you want to set access for individual tables or schemas) +- 10 thousand rows +- 1 million rows + +## Manage table metadata permissions + +{% include plans-blockquote.html feature="Data model permissions" %} + +You can define whether a group can [edit table metadata](../data-modeling/metadata-editing). Options are: + +- Yes (meaning, they can edit metadata for that data source). +- No +- Granular (to set permissions specific to each table). + +## Manage database permissions + +{% include plans-blockquote.html feature="Database management permissions" %} + +The **Manage database** permission grants access to the settings page for a given database (i.e., the page at **Admin settings** > **Databases** > your database). + +On the database settings page, you can: + +- Edit any of the [connection options](../databases/connecting) for the data source. +- [Sync schemas](../databases/sync-scan#manually-syncing-tables-and-columns). +- [Scan field values](../databases/sync-scan#manually-scanning-column-values). + +Note that only admins can delete database connections in your Metabase, so people with **Manage database** permissions won't see the **Remove database** button. + +## Revoke access even though "All Users" has greater access + +If you see this modal pop-up, Metabase is telling you that the people in the All Users group (that is, everyone in your Metabase), have a higher level of access to the database, schema, or table that you're setting permissions on. To limit your current group to your preferred permission level, the All Users group must have a less permissive level of access to the data source in question. + +## Upload permissions + +See [Upload permissions](../databases/uploads#add-people-to-a-group-with-data-access-to-the-upload-schema). + +## Further reading + +- [Permissions introduction](./introduction) +- [Impersonation](./impersonation) +- [Learn permissions](/learn/metabase-basics/administration/permissions) +- [Troubleshooting permissions](../troubleshooting-guide/permissions) +- [Data sandboxing: setting row-level permissions][sandbox-rows] +- [Advanced data sandboxing: limiting access to columns][sandbox-columns] +- [Users, roles, and privileges](../databases/users-roles-privileges) + +[collections]: ./collections +[dashboard-subscriptions]: ../dashboards/subscriptions +[data-sandboxing]: ./data-sandboxes +[permissions-overview]: ./introduction +[sandbox-columns]: /learn/metabase-basics/administration/permissions/data-sandboxing-column-permissions +[sandbox-rows]: /learn/metabase-basics/administration/permissions/data-sandboxing-row-permissions +[sql-snippet-folders]: ../questions/native-editor/snippets diff --git a/_docs/doc-update-detection/permissions/images/admin-panel-collections.png b/_docs/doc-update-detection/permissions/images/admin-panel-collections.png new file mode 100644 index 000000000..87838610f Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/admin-panel-collections.png differ diff --git a/_docs/doc-update-detection/permissions/images/advanced-example-1-filtering-question.png b/_docs/doc-update-detection/permissions/images/advanced-example-1-filtering-question.png new file mode 100644 index 000000000..16789b02b Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/advanced-example-1-filtering-question.png differ diff --git a/_docs/doc-update-detection/permissions/images/advanced-example-1-people-table.png b/_docs/doc-update-detection/permissions/images/advanced-example-1-people-table.png new file mode 100644 index 000000000..60dfaf968 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/advanced-example-1-people-table.png differ diff --git a/_docs/doc-update-detection/permissions/images/advanced-example-1-sandbox-modal.png b/_docs/doc-update-detection/permissions/images/advanced-example-1-sandbox-modal.png new file mode 100644 index 000000000..efc22e7a7 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/advanced-example-1-sandbox-modal.png differ diff --git a/_docs/doc-update-detection/permissions/images/advanced-example-2-filtering-question.png b/_docs/doc-update-detection/permissions/images/advanced-example-2-filtering-question.png new file mode 100644 index 000000000..2b239a1d7 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/advanced-example-2-filtering-question.png differ diff --git a/_docs/doc-update-detection/permissions/images/advanced-example-2-results.png b/_docs/doc-update-detection/permissions/images/advanced-example-2-results.png new file mode 100644 index 000000000..e9a700216 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/advanced-example-2-results.png differ diff --git a/_docs/doc-update-detection/permissions/images/advanced-example-2-sandboxing-options.png b/_docs/doc-update-detection/permissions/images/advanced-example-2-sandboxing-options.png new file mode 100644 index 000000000..2982560a1 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/advanced-example-2-sandboxing-options.png differ diff --git a/_docs/doc-update-detection/permissions/images/change-permissions.png b/_docs/doc-update-detection/permissions/images/change-permissions.png new file mode 100644 index 000000000..3c9f263ca Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/change-permissions.png differ diff --git a/_docs/doc-update-detection/permissions/images/collection-detail.png b/_docs/doc-update-detection/permissions/images/collection-detail.png new file mode 100644 index 000000000..bbcda41a5 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/collection-detail.png differ diff --git a/_docs/doc-update-detection/permissions/images/collection-permissions.png b/_docs/doc-update-detection/permissions/images/collection-permissions.png new file mode 100644 index 000000000..0a8f315d4 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/collection-permissions.png differ diff --git a/_docs/doc-update-detection/permissions/images/create-new-folder-modal.png b/_docs/doc-update-detection/permissions/images/create-new-folder-modal.png new file mode 100644 index 000000000..3b90cd19d Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/create-new-folder-modal.png differ diff --git a/_docs/doc-update-detection/permissions/images/dashboard-no-permissions.png b/_docs/doc-update-detection/permissions/images/dashboard-no-permissions.png new file mode 100644 index 000000000..26a8b317f Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/dashboard-no-permissions.png differ diff --git a/_docs/doc-update-detection/permissions/images/edit-user-details.png b/_docs/doc-update-detection/permissions/images/edit-user-details.png new file mode 100644 index 000000000..43355a76a Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/edit-user-details.png differ diff --git a/_docs/doc-update-detection/permissions/images/enterprise-add-snippet.png b/_docs/doc-update-detection/permissions/images/enterprise-add-snippet.png new file mode 100644 index 000000000..77a9c8732 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/enterprise-add-snippet.png differ diff --git a/_docs/doc-update-detection/permissions/images/grant-sandboxed-access.png b/_docs/doc-update-detection/permissions/images/grant-sandboxed-access.png new file mode 100644 index 000000000..0aa0ceb67 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/grant-sandboxed-access.png differ diff --git a/_docs/doc-update-detection/permissions/images/pinned-items.png b/_docs/doc-update-detection/permissions/images/pinned-items.png new file mode 100644 index 000000000..efd9c4500 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/pinned-items.png differ diff --git a/_docs/doc-update-detection/permissions/images/select-user-attribute.png b/_docs/doc-update-detection/permissions/images/select-user-attribute.png new file mode 100644 index 000000000..51902cd88 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/select-user-attribute.png differ diff --git a/_docs/doc-update-detection/permissions/images/snippet-folder.png b/_docs/doc-update-detection/permissions/images/snippet-folder.png new file mode 100644 index 000000000..d8dc63c85 Binary files /dev/null and b/_docs/doc-update-detection/permissions/images/snippet-folder.png differ diff --git a/_docs/doc-update-detection/permissions/impersonation.md b/_docs/doc-update-detection/permissions/impersonation.md new file mode 100644 index 000000000..bde6b008e --- /dev/null +++ b/_docs/doc-update-detection/permissions/impersonation.md @@ -0,0 +1,77 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Permissions +title: 'Impersonation access' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/permissions/impersonation.md' +--- + +# Impersonation permissions + +{% include plans-blockquote.html feature="Impersonation access" %} + +> For now, impersonation access is only available for PostgreSQL, Redshift, and Snowflake. + +> If you're using views in PostgresSQL, the row-level security policies on views will only work on Postgres versions 15 and higher. + +This page covers the [View data](./data#view-data-permissions) permission level called Impersonation. + +**Impersonation access** allows admins to "outsource" View data permissions to roles in your database. Admins can associate user attributes with database-defined roles and their privileges. If someone is in a group with their View data permission set to Impersonation, the person will be able to view and query data based on the privileges granted to the role specified by their user attribute. + +## Setting up connection impersonation + +> \*\*For impersonation to work for Redshift databases, the user account Metabase uses to [connect to your Redshift database](../databases/connections/redshift) must be a superuser, as Metabase will need to be able to run the [SET SESSION AUTHORIZATION](https://docs.aws.amazon.com/redshift/latest/dg/r_SET_SESSION_AUTHORIZATION) command, which can only be run by a database superuser. + +For impersonation access to work, you'll first need to set up roles in your database for Metabase to impersonate, then configure Metabase to impersonate those roles when people view or query data. + +### In your database, set up roles + +1. Create a new role (in Redshift, this would be a new user). +2. Grant that role privileges. + +For exactly how to create a new role in your database and grant that role privileges, you'll need to consult your database's documentation. We also have some docs on [users, roles, and privileges](../databases/users-roles-privileges) that can help you get started. + +### In your Metabase, set up impersonation and specify a user attribute + +1. **Create a [new group](../people-and-groups/managing#groups)**, or select an existing group. + +2. **Assign a [user attribute](../people-and-groups/managing#adding-a-user-attribute) to people in that group.** You'll use this user attribute to associate people in that group with a role that you created in your database. For example, if you created a role named `sales` in your database with access to a subset of tables relevant to the sales team, you would add a user attribute called `db_role` (or whatever you want to call the attribute) and assign the value `sales` to the person's `db_role`. The value of the attribute (`sales` in this case) should match the name of the role in your database. Only some databases enforce case sensitivity, so you might want to make sure the attribute's value and the database's role match exactly. + +3. **Apply the impersonation access to that group.**. Hit Cmd/Ctrl + K to bring up the command palette. Search for **Permissions**. Or go to **Admin settings** > **Permissions** > **Data**. + +4. Select the database you want to set permissions on. + +5. Find the group that you want to associate with the database role you created. Under **View data** setting for that group, select **Impersonation**. + +6. From the dropdown, select the user attribute that you added that maps to the role you want the group to use when querying the database. + +7. Save your changes. + +## People in a group with impersonation access to data do not necessarily share the same privileges + +Metabase will use whatever role you specify in the user attribute for each person. E.g., if you select the `db_role` attribute for impersonation, one person's `db_role` could be `sales`, another person's could be `engineering`, or whatever other value that maps to a valid role in your database. + +## Use impersonation to set up row-level SQL access + +You can use impersonation to give people access to the native/SQL editor, while restricting their access to data based on a specific database role. And not just table-level access, but row-level access---or however you define access for that role in your database. Effectively, you can use impersonation to set up data sandbox-like access to your data, while letting people use the SQL editor to query that data. The difference is that, _instead of setting up a data sandbox in Metabase, you need to set up that row-level security via the privileges granted to a role in your database._ + +If instead you want to give a group SQL access to some, but not all, of the schemas or tables in that database, you can create an additional role in your database that only includes a subset of those tables---or even specific row-level access---and then use Metabase's impersonation feature to associate a user attribute with that role. Essentially what Metabase will do is take the user attribute and pass that attribute as a string into a `SET ROLE` or `USE ROLE` command for the database _before_ Metabase executes the query. + +Connection impersonation doesn't apply to people in the Metabase admins group, as their more permissive privileges take precedence. + +For more about how to set this up, check out [Use Impersonation to get row-level permissions with both GUI and SQL queries](/learn/metabase-basics/administration/permissions/impersonation). + +## Metabase gives people the most permissive access to data across all of their groups + +So if a person is in two groups with different permissions for the same database: + +- Red group with impersonated access that limits what they can see. +- Blue group with View data set to "Can view" and Create queries set to "Query builder and native". + +Blue group's more permissive access would override the impersonated access. + +## Further reading + +- [Use Impersonation to get row-level permissions with both GUI and SQL queries](/learn/metabase-basics/administration/permissions/impersonation) diff --git a/_docs/doc-update-detection/permissions/introduction.md b/_docs/doc-update-detection/permissions/introduction.md new file mode 100644 index 000000000..cac99bbfa --- /dev/null +++ b/_docs/doc-update-detection/permissions/introduction.md @@ -0,0 +1,86 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Permissions +title: 'Permissions introduction' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/permissions/introduction.md' +redirect_from: + - /docs/doc-update-detection/administration-guide/05-setting-permissions +--- + +# Permissions introduction + +There are always going to be sensitive bits of information in your data, and thankfully Metabase provides a rich set of tools to ensure that people on your team only see the data they’re supposed to. + +If instead you're wondering about what data Metabase the company can see, check out our page on [data privacy and security](/security). + +## Key points regarding permissions + +- Permissions are granted to [groups](../people-and-groups/managing#groups), not people. +- People can be in more than one group. +- If a person is in multiple groups, they will have the _most permissive_ access granted to them across all of their groups. For example, if a person is in three groups, and any one of those groups has Curate access to a collection, then that person will have curate access to that collection. + +## What you can set permissions on + +- [Data permissions](#data-permissions) +- [Collection permissions](#collection-permissions) +- [Application permissions](#application-permissions) +- [Snippet folder permissions](#snippet-folder-permissions) + +### Data permissions + +[Data permissions](./data) allow you to set permissions on database and their schemas and tables. + +- [View data](./data#view-data-permissions) +- [Create queries](./data#create-queries-permissions) +- [Download results](./data#download-results-permissions) +- [Manage database](./data#manage-database-permissions) + +### Collection permissions + +[Collection permissions][collections] dictate which groups can view/edit items in collections, including: + +- Questions +- Dashboards +- Models +- Metrics +- Events +- Timelines + +### Application permissions + +[Application permissions](application) (available on [Pro and Enterprise plans](/pricing/)) dictate access to Metabase application-level features, including: + +- **Settings**: The Settings tab in the Admin panel. +- **Monitoring access**: The Tools and Troubleshooting tabs in the Admin panel. +- **Subscriptions and Alerts**. Which groups can create/edit dashboard subscriptions and alerts. + +### Snippet folder permissions + +For plans that include [Snippet Folders][snippet-folders], you can also set permissions on those folders. + +## Changing permissions + +Whenever you change permissions for a group, make sure you: + +- Save your changes. +- Click yes to confirm your choices. + +## Further reading + +- [Managing people and groups](../people-and-groups/managing) +- [Permissions guide][permissions] +- [Troubleshooting permissions][troubleshooting-permissions] + +[collections]: ../exploration-and-organization/collections +[dashboard-subscriptions]: ../dashboards/subscriptions +[data-permissions]: ./data +[data-sandboxing]: ./data-sandboxes +[permissions]: /learn/metabase-basics/administration/permissions +[sandbox-columns]: /learn/metabase-basics/administration/permissions/data-sandboxing-column-permissions +[sandbox-rows]: /learn/metabase-basics/administration/permissions/data-sandboxing-row-permissions +[slack-integration]: ../configuring-metabase/slack +[snippet-folders]: ../questions/native-editor/snippets +[troubleshooting-permissions]: ../troubleshooting-guide/permissions diff --git a/_docs/doc-update-detection/permissions/no-self-service-deprecation.md b/_docs/doc-update-detection/permissions/no-self-service-deprecation.md new file mode 100644 index 000000000..59ca17750 --- /dev/null +++ b/_docs/doc-update-detection/permissions/no-self-service-deprecation.md @@ -0,0 +1,119 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Permissions +title: 'Migrating from legacy permissions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/permissions/no-self-service-deprecation.md' +--- + +# Migrating from legacy permissions + +In Metabase 50, we overhauled our data permissions system to make it more expressive and easier to reason about. This page explains what changed and why. + +**The TL;DR: we split the old Data access setting into two settings: [View data](./data#can-view-data-permission) and [Create Queries](./data#create-queries-permissions). Your data permissions may look different, but the access hasn't changed.** + +## How Metabase migrated your permissions + +If you're migrating from Metabase 50 or earlier, Metabase will (with [one exception](#the-no-self-service-deprecated-view-access-level)) automatically update your permissions to the new system. While group permissions will be slightly different (and we hope easier to reason about), your groups will have the same levels of access as before. + +## Why we updated our permissions system + +The original Data access permission setting contained five levels of access: unrestricted, impersonated, granular, no self-service, and block. These levels aren’t at the same axis. They combined on one axis, whether you could view data, and on another axis, whether you could query that data. This created a two-dimensional setting: + +- **No self-service.** Restricts groups from using the query builder to create or edit questions. +- **Sandbox and block.** Restricts view _and_ query builder access to the underlying data. + +Mixing two axes (querying + viewing) to a single permissions setting could yield unexpected behavior. For example, by changing access from "Sandboxed" to "No self-service", an admin might think that they would be _restricting_ that group's access to data. But in that case, the group could potentially see _more_ data, provided the group also had access to collections with existing models, questions, or dashboards. + +## What our overhaul of data permissions accomplishes + +- Splits [view access](./data#view-data-permissions) and [query access](./data#create-queries-permissions) into two permission dimensions. This splitting allows admins to, for example, sandbox tables with or without access to the query builder (previously it wasn't possible to configure sandboxing as view only). +- Makes permissions easier to reason about. A more restrictive permission never gives more access than a less restrictive one. + +## Migration table from old permissions to new + +This table is just if you're interested in Metabase archeologically. Metabase handles the migration for you. + +Before, Metabase had **Data access** and **Native query editing**. Now, Metabase has [View data](./data#view-data-permissions) and [Create queries](./data#create-queries-permissions). Here's how Metabase migrated each pairing to the new system. + +| **Data access** | **Native query editing** | **>** | **View data** | **Create queries** | +| -------------------------- | ------------------------ | ----- | -------------------- | ----------------------------- | +| Unrestricted | Yes | **>** | Can view | Query builder and native code | +| Unrestricted | No | **>** | Can view | Query builder | +| No self-service | No | **>** | Can view | No | +| Blocked | No | **>** | Blocked | No | +| Impersonated | Yes | **>** | Impersonated | Query builder and native code | +| Impersonated | No | **>** | Impersonated | Query builder | +| Unrestricted (granular) | No | **>** | Can view | Query builder (granular) | +| Sandboxed (granular) | No | **>** | Sandboxed (granular) | Query builder (granular) | +| No self-service (granular) | No | **>** | Can view | No (granular) | + +## The `No self-service (deprecated)` View access level + +If you see the `No self-service (deprecated)` permission setting in **View data** for any group, you should manually change it at some point. + +For any group that has their **View data** access set to `No self-service (deprecated)`, you'll need to change the **View data** permission to one of the new options: + +- [Can view](./data#can-view-data-permission) +- [Impersonated](./data#impersonated-view-data-permission) +- [Sandboxed](./data#sandboxed-view-data-permission) +- [Blocked](./data#blocked-view-data-permission) + +If you take no action, Metabase will change any groups with View data access set to `No self-service (deprecated)` to `Blocked` in a future release. We're defaulting to "Blocked", the least permissive View data access, to prevent any unintended access to data. But this change to Blocked could cause people to lose access to data they previously had access to. + +### Why we couldn't migrate this setting manually + +In the old permissions system, consider people in multiple groups. + +- **Unrestricted** data access meant that blocks, sandboxes, or impersonations from your other groups DO NOT affect you. +- **No Self Service** data access meant that blocks, sandboxes, or impersonations from your other groups DO affect you. + +Say you have the following groups in the old permissions framework: + +| | **Group A** | **Group B** | **Group C** | **Group D** | **Group E** | +| --------------- | ------------ | --------------- | ----------- | ----------- | ------------ | +| **Data Access** | Unrestricted | No self-service | Blocked | Sandboxed | Impersonated | + +If you’re a member of Group A and one of Group C, D, or E, you’ll have full, unrestricted access to the data, with no blocks, sandboxes, or impersonations applied. + +If you’re a member of Group B and one of Group C, D, or E, you’ll have limited access to the data: either blocked, sandboxed, or impersonated. + +We could migrate the permissions like so: + +| | **Group A** | **Group B** | **Group C** | **Group D** | **Group E** | +| ------------------ | ------------------ | ----------- | ----------- | ------------------ | ------------------ | +| **View data** | Can view | ? | Blocked | Sandboxed | Impersonated | +| **Create queries** | Query Builder only | No | No | Query Builder only | Query Builder only | + +We can't really make a call on what Group B's View data should be. If we switch it to **Can view**, the person won't be affected by the Blocked, Sandboxed, or Impersonated settings in their other group. If we set it to **Blocked**, they could lose access to data that you think they should have access to. So we created an interim setting, `No self-service (legacy)` to manage this (temporarily) awkward transition. + +### For some permission setups with groups that have "No self-service" and "Sandboxed" data access, you may need to create a new group to replicate the setup in 50 or higher + +In Metabase 49, the (more permissive) "No self-service" data access couldn't override the (less permissive) "Sandboxed" access, you could set up Metabase 49 in ways that were difficult to reason about. + +In the new permission system starting in Metabase 50, more permissive settings _always_ override less permissive settings. This consistent behavior makes permissions a _lot_ easier to reason about. One consequence of this improvement, however, is that in order to recreate certain permissions setups when upgrading to Metabase 50, you may need to create an _additional_ group. + +For example, let's say you have two groups in Metabase 49 under the old data access permission, the All users group and the Foo group. + +**Permission setup in 49:** + +- All users group has "No self-service" data access to all of the tables in the Sample Database. +- Foo group has "Sandboxed" access to the tables in the Sample Database. + +This data access setup in 49 would allow people to view questions and dashboards in collections they have access to. People in the Foo group, however, would get a sandboxed view of the items. In this case, the less permissive "Sandboxed" data access in the Foo group overrode the more permissive "No self-service" in the All users group. + +Starting with Metabase 50, however, more permissive settings _always_ override less permissive settings. So in order to keep Foo's sandboxes in tact, we'd need to make the All users group have a View data permission setting that is _less_ permissive than the "Sandboxed" setting. So we'll need to set the View data permission for All users to "Blocked." + +But if you still want everyone else who _isn't_ in the Foo group to view items in collections they have access to, you'll need to create an additional group, Bar, that contains everyone _except for_ people in the Foo group, and grant that Bar group "Can view" access to the Sample database. The Bar group's "Can view" access will override the All Users group's "Blocked" setting, and they'll be able to view the questions and dashboards. Meanwhile, Foo group still has its sandboxes. Here's a summary of the settings for 50 that you'd need: + +**Permission setup in 50:** + +- All users group is "Blocked" for all tables in the Sample database. +- Foo group has View data permission of "Sandboxed" for all tables in the Sample database. +- **Create a new group**, Bar, that includes everyone in the All users group _except for_ people in the Foo group. Set this Bar group's View data permission to "Can view" for the Sample database. + +## Further reading + +- [Data permissions](./data) diff --git a/_docs/doc-update-detection/permissions/notifications.md b/_docs/doc-update-detection/permissions/notifications.md new file mode 100644 index 000000000..4505454ae --- /dev/null +++ b/_docs/doc-update-detection/permissions/notifications.md @@ -0,0 +1,63 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Permissions +title: 'Notification permissions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/permissions/notifications.md' +--- + +# Notification permissions + +Notifications in Metabase include [alerts](../questions/alerts) and [dashboard subscriptions](../dashboards/subscriptions#setting-up-a-dashboard-subscription). + +## Who can edit dashboard subscriptions and alerts + +What you can do with alerts and dashboard subscriptions depends on whether you're in the Administrators group or in a sandboxed group. + +- [All Users group](#all-users-group-notification-permissions) +- [Sandboxed group](#sandboxed-accounts-notification-permissions) +- [Administrators group](#administrators-group-notification-permissions) + +### All Users group notification permissions + +Everyone's in the All Users group. Which means that everyone can: + +- Create [alerts](../questions/alerts) and [dashboard subscriptions](../dashboards/subscriptions#setting-up-a-dashboard-subscription). +- Add new recipients to dashboard subscriptions that they created. Non-admins can only add themselves to alerts. +- Unsubscribe from any alert or subscription in their [Account settings](../people-and-groups/account-settings). + +When a notification creator adds new recipients to an alert or subscription, Metabase will display data to the recipients using the **creator's** [data permissions](../permissions/data) and [collection permissions](../permissions/collections). + +### Sandboxed accounts notification permissions + +Same as everyone in the All Users group, but with a special case: **people in sandboxed groups will only see themselves in the list of recipients** when creating an alert or subscription. + +### Administrators group notification permissions + +People in the admin group can: + +- View all subscriptions and alerts. +- Add or remove recipients from an existing subscription or alert. Admins can safely add and remove recipients without changing the permissions of the alert or subscription. For example, if an admin adds Anya to a subscription created by Beau, Anya will receive emails with the same data that Beau can see (not what the admin can see). +- Delete subscriptions or alerts. + +## What notification recipients can see + +Notification **recipients** can see whatever the notification **creator** can see. For example, if: + +- Beau creates a subscription to a dashboard saved in their [personal collection](../exploration-and-organization/collections#your-personal-collection). +- Beau adds Anya to the dashboard subscription. +- Anya will see the dashboard results in her email, even though she lacks permissions to view that dashboard in Beau's personal collection. + +## More control over email options + +On [Enterprise](/product/enterprise) and [Pro](/product/pro) plans, Admins can: + +- Limit email recipients to [approved domains for notifications](../configuring-metabase/email#approved-domains-for-notifications). +- [Limit which recipients Metabase suggests](../configuring-metabase/email#suggest-recipients-on-dashboard-subscriptions-and-alerts) when people set up a subscription or alert. + +## Further reading + +- [Dashboard subscriptions](../dashboards/subscriptions) +- [Alerts](../questions/alerts) diff --git a/_docs/doc-update-detection/permissions/snippets.md b/_docs/doc-update-detection/permissions/snippets.md new file mode 100644 index 000000000..7b0325d9a --- /dev/null +++ b/_docs/doc-update-detection/permissions/snippets.md @@ -0,0 +1,97 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Permissions +title: 'Snippet folder permissions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/permissions/snippets.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/sql-snippets +--- + +# Snippet folder permissions + +{% include plans-blockquote.html feature="Snippet controls" %} + +This article covers **Snippet folders**, which allow you to organize and set permissions on [Snippets](../questions/native-editor/snippets). + +Folder permissions should not be considered a security feature, but instead a feature that helps organize and standardize snippets. Although folders are distinct and separate from Collections, they both serve an organizational function: Collections gather and permission dashboards and questions; folders gather and permission snippets. For more info, see the [discussion on permissions below](#permissions). + +## Folders + +Folders work similarly to a file system. You can add snippets to folders, and put folders inside of other folders. You can nest as many folders as your Metabase instance can handle or the laws of physics allow (whichever yields first). + +The **Top folder** is the snippet sidebar's default folder. It is the root folder that contains all folders and snippets. + +### Creating a new Snippet folder + +You can create a Snippet folder from the **Snippets** menu in the [SQL editor](../questions/native-editor/writing-sql). + +![Create new snippet folder](./images/snippet-folder.png) + +1. Click on the **Snippets** menu icon (the snippet icon looks like a block of text or code with three uneven horizontal lines). +2. Click on the **+** icon and select **New folder**. +3. Give your folder a name, and optionally **Add a description** and/or place the folder in an existing folder (the **Folder this should be in** option). + +![Create new folder modal](./images/create-new-folder-modal.png) + +### Creating a new Snippet + +On [some plans](/pricing/), when creating a Snippet, you'll also see an additional option to add that snippet to an existing folder (the **Folder this should be in** option). + +![Add a snippet enterprise modal](./images/enterprise-add-snippet.png) + +The default location is the **Top folder**, which is the root folder for all snippets and folders. You can add a snippet to a folder at any time (or relocate a snippet to another folder, provided you have Edit permission to both folders). + +Note that snippet names must be unique; folders do not affect this requirement. + +## Permissions + +Administrators (and only administrators) can set snippet visibility and editability by placing snippets in **folders**, then granting groups one of three permission levels with respect to those folders. If you're familiar with [collection permissions](./collections#setting-permissions-for-collections), the functionality is similar. For more on how collection and folder permissions work together, see [how folder permissions work](#how-folder-permissions-work) below. + +### Changing permissions on a folder + +Administrators can set the permissions on a folder by clicking on the ellipsis (**...**) next to a folder, and selecting **Change permissions**. + +You can additionally change the currently selected folder by mousing over to the top of the Snippets sidebar, clicking on the ellipsis (**...**) to the left of the **+**, and selecting **Change permissions**. When at the **Top folder**, selecting the **...** at the top of the sidebar will give Administrators the option to set permissions for all snippets, folders, and sub-folders. + +When changing permissions on a folder that has sub-folders, you have an option to extend those permissions to that folder's sub-folders by toggling the **Also change sub-folders** setting. + +### Options for folder permissions + +![Change permissions](./images/change-permissions.png) + +There are three options for changing snippet folder permissions: + +- **Edit access (green checkmark icon)**. The default setting. When a folder is created, all users (who have SQL editor permissions for at least one database) can view, edit, and archive or unarchive the folder's snippets. +- **View access (yellow eye icon)**. Users in groups with view access can view snippets in the folder, but not edit or archive/unarchive them. They can, of course, copy snippet code and create new snippets, with no effect on the existing snippets. +- **Revoke access (red X icon)**. Users in groups with neither edit nor view permissions to a snippet folder will not see that folder's snippets in the sidebar, nor will any snippets in that folder appear in typeahead suggestions for those users. Note that if people have access to a question with a snippet they don't have permission to, they will still be able to get results from that question. See the discussion below on [how folder permissions work](#how-folder-permissions-work). + +### Archiving does not affect permissions + +Archiving or unarchiving snippets does not affect a snippet's permissions. If, for example, only one group, say the Accounting group, has edit permissions on a folder, only people in the Accounting group (and admins) would be able to archive and unarchive snippets in that folder, as archiving and unarchiving is considered editing the snippet. + +### How folder permissions work + +As with collection permissions, folder permissions are additive, meaning that the more permissive access overrules less permissive access. See [Setting permissions](./start) for a more detailed discussion. + +But snippet folder permissions require some more effort to unpack, as permissions for snippet folders must work in conjunction with permissions for data and collections. + +Here's the basic rule: data is more sensitive than code, so permissions that apply to data will take precedence over permissions that apply to code. Let's work through an example to illustrate how this works in practice. + +#### Permissions example + +Consider the following scenario (and here's a sentence that merits slow reading): a group could have permission to a Collection that contains a question that uses a snippet housed in a folder that the group does _not_ have permissions to. To rephrase: people in that group have permissions to run questions in a collection, but they do not have permission to a folder containing a snippet used in one of the collection's questions. How will Metabase resolve permissions in this case? + +In three parts: + +1. **People in that group can run the question and get results**. They have permission to see that data (the question results), so they should be able to see that data. The group's permission to the collection takes precedence over permissions to the folder (the snippet code). +2. **The snippet would not show up in the Snippet sidebar**. However, just because people in that group can run the question without issue, they still don't have permission to the snippet's folder, so they wouldn't be able to see or edit that snippet (or the snippet's folder) in the Snippet sidebar. +3. **People with SQL query access can still run the snippet if they know its name, regardless if they have permissions to the snippet's folder**. They wouldn't be able to view or edit the snippet, but they could include it in a query if they knew its name, e.g, `{% raw %}{{snippet: Example snippet I don't have permissions to but can still use }}{% endraw %}`. + +Because of how snippet folder permissions work, we recommend that you consider snippet folder permissions as an additional tool for snippet organization, not as method of preventing access to the SQL code those snippets contain. Use folder permissions to keep the snippet sidebar tidy by exposing teams to folders relevant to their analytical domain, and restrict editing permissions to key snippets in your organization to keep important SQL code accurate and safe from bugs introduced by unvetted edits. + +## Further reading + +- [Snippets](/learn/metabase-basics/querying-and-dashboards/sql-in-metabase/snippets). diff --git a/_docs/doc-update-detection/permissions/start.md b/_docs/doc-update-detection/permissions/start.md new file mode 100644 index 000000000..e370b4447 --- /dev/null +++ b/_docs/doc-update-detection/permissions/start.md @@ -0,0 +1,41 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: Permissions +title: 'Permissions overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/permissions/start.md' +--- + +# Permissions overview + +Metabase has a simple, but powerful permissions system. + +## [Permissions introduction](./introduction) + +Get a lay of the permissions land. + +## [Data permissions](./data) + +Restricting group access to databases, schemas, and tables. + +## [Collection permissions](./collections) + +Granting group access to collections of questions, dashboards, models, and sub-collections. + +## [Application permissions](./application) + +Granting group access to different Metabase features. + +## [Data sandboxing](./data-sandboxes) + +Creating data sandboxes to restrict access to rows and columns in tables. + +## [Snippet folder permissions](./snippets) + +Organize snippets into folders that require permissions to view. + +## [Notification permissions](./notifications) + +Notes on how permissions interact with dashboard subscriptions and alerts. diff --git a/_docs/doc-update-detection/questions/alerts.md b/_docs/doc-update-detection/questions/alerts.md new file mode 100644 index 000000000..e538e573f --- /dev/null +++ b/_docs/doc-update-detection/questions/alerts.md @@ -0,0 +1,153 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Alerts +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/alerts.md' +redirect_from: + - /docs/doc-update-detection/users-guide/15-alerts + - /docs/doc-update-detection/questions/sharing/alerts +--- + +# Alerts + +Set up an alert to send the results of questions to people via email or Slack, or to a webhook. + +Alerts are for questions only. If you instead want to get the results of a dashboard sent to you, check out [dashboard subscriptions](../dashboards/subscriptions). + +## Prerequisite for alerts + +To start using alerts, an administrator will need to have set up at least one of the following notification channels. + +- [Email](../configuring-metabase/email) +- [Slack](../configuring-metabase/slack) +- [Webhooks](../configuring-metabase/webhooks) + +## Creating an alert + +![Get alerts](./images/get-alerts-about-this.png) + +To create an alert: + +1. Save your question. +2. Click on the sharing icon in the top-right of the screen. +3. Select **Create an alert**. +4. Select what you want to be alerted about. The alert options will depend on the question's visualization. See [types of alerts](#types-of-alerts). +5. Select when you want Metabase to check the results. Metabase can check for results by the minute, hourly, daily, weekly, monthly, or on a custom schedule that you set using the Quartz [cron syntax](https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html). +6. Select the alert's destination: [email](../configuring-metabase/email), [Slack](../configuring-metabase/slack), or to a [webhook](../configuring-metabase/webhooks). + +You'll also have the option to only send the alert once. To test the alert, you can hit the **Send now** button. But just make sure that the question returns results. If the question doesn't return any results, Metabase won't send the alert. + +## Types of alerts + +- [Results alerts](#results-alerts): when a question returns any result. +- [Goal line alerts](#goal-line-alerts) when a time series crosses a goal line. +- [Progress bar alerts](#progress-bar-alerts): when a progress bar reaches or goes below its goal. + +## Results alerts + +Metabase can send you an alert on a schedule when one of your questions returns _any_ result. This kind of alert is also particularly useful if you have a question that doesn't _usually_ return any results, but you want to know when the question _does_ return results. + +For example, you might have a table called `Reviews`, and you want to know any time a customer leaves a bad review, which you consider to be anything below three stars. To set up an alert for this situation, you'd go and create a raw data question (i.e., a question that returns a list of reviews), and add a filter to only include results with fewer than three stars. + +You probably don't want to be alerted about all the bad reviews you've _ever_ gotten, but just recent ones. So you can add a filter to only include results from yesterday or today, depending on how often you want to check for these bad reviews. At this point, when you check the results of this question, it probably won't return any results, which is a good thing. + +Save the question, create an alert, and select how often you want Metabase to check this question for results. That's it! + +## Goal line alerts + +_Requires a [bar, line, or area chart](./visualizations/line-bar-and-area-charts) with a goal line._ + +Goal line alerts are useful when you're doing things like tracking daily active users (DAU) and you want to know when you reach a certain number of DAU, or when you're tracking orders per week and you want to know whenever the number of orders ever goes below a certain threshold. + +To start, you'll need a line, area, or bar chart displaying a number over time. + +Next, you need to set up a goal line on your chart. Open up the visualization settings by clicking the **gear** icon in the bottom-left. Then click on the **Display** tab, and turn on the **Show goal** setting. Choose a value for your goal (and optionally a label) and click Done. + +You can choose: + +- Whether you want Metabase to alert you when the time series goes above the goal line or when it goes below the goal line. +- Whether you want Metabase to alert you every time the time series crosses a goal line, or only the first time it crosses the goal line. +- How often you want Metabase to check to see if the goal line has been crossed. + +Click Done, and your alert will be all set up! + +If you need to edit or unsubscribe from the alert you set up, just click that same icon. You'll see the Edit and Unsubscribe buttons. This is also where you'll see alerts about this question that admins might have added you to. + +Metabase will email you when: + +- You set up an alert +- You've been unsubscribed from an alert +- One of your alerts has stopped working +- You unsubscribed from an alert +- An admin added you to an alert + +## Progress bar alerts + +_Requires the [progress bar visualization](./visualizations/progress-bar)._ + +If you want to set up an alert when a single number reaches a goal, you can use a progress bar visualization. + +1. Create a question that returns a single number as its result, +2. Choose the Progress Bar chart type, +3. In Visualization settings, select a goal value +4. Save your question, +5. Create an alert by clicking on the Sharing icon in top right + +You'll see the options for when you want to get alerts about this progress bar: + +- Whether to alert when the progress bar reaches the goal line or below the goal, +- Whether to alert only the first time the progress bar reaches the goal line, or every time +- How often you want Metabase to check to see if the goal has been reached. + +## Editing and deleting alerts + +To edit or delete alerts on a question, click on the Sharing icon in the top right corner. What you can edit depends on whether you're an admin. + +Everyone: + +- Everyone can edit alerts that they've personally set up (but not alerts set up by other people). +- Everyone can view and unsubscribe from all alerts they receive by clicking on the **gear** icon in the upper right and navigating to **Account settings** > **Notifications**. + +Admins: + +- Admins can edit and delete any alert. This can't be undone, so be careful! +- Admins can add or remove recipients on any alert, even ones that they didn't create themselves. +- Admins can bulk manage alerts per person from the [People menu in Admin settings](../people-and-groups/managing#unsubscribe-from-all-subscriptions-and-alerts). + +## Avoid changing the name of the alerted channel in Slack + +Once you set up an alert to a Slack channel, avoid changing the name of that channel in Slack. If you rename the channel in Slack, but you want Metabase to continue to send alerts to that renamed channel, you'll need to update the alert in Metabase to point to the new channel name. + +## Alert expiration and special cases + +Some circumstances will automatically change or delete alerts: + +- **You rename the target Slack channel**. Well, technically the alert won't get deleted, but Metabase will no longer have anywhere to send the alerts to. You'll need to update the alert's target channel in Metabase to the new channel's name. +- **If a goal line is removed from the question powering a "Goal line" alert**, the alert will change to a "Results" type alert. +- **If the question is deleted**, Metabase will delete any alerts set up for that question. + +Alerts will continue to work _even if the person who set up the alert no longer has an active account_. For example, if an alert with multiple recipients (or to a Slack channel) was set up by someone whose account has since been deactivated, that alert will continue to work (though Metabase will stop sending the alerts to the deactivated account). + +## Admins can see all alerts + +{% include plans-blockquote.html feature="Usage analytics" %} + +Admins can view a list of all alerts and dashboard subscriptions that people have set up in your Metabase in the **Usage analytics** collection. See [Usage analytics](../usage-and-performance-tools/usage-analytics#alerts-model). + +## How permissions work with alerts + +See [Notification permissions](../permissions/notifications). + +### Sending alerts to private Slack channels + +See [Sending alerts and subscriptions to private Slack channels](../configuring-metabase/slack#sending-alerts-and-subscriptions-to-private-slack-channels). + +## Further reading + +- [Dashboard subscriptions](../dashboards/subscriptions) +- [Setting up email](../configuring-metabase/email) +- [Setting up Slack](../configuring-metabase/slack) +- [Usage analytics](../usage-and-performance-tools/usage-analytics) diff --git a/_docs/doc-update-detection/questions/exporting-results.md b/_docs/doc-update-detection/questions/exporting-results.md new file mode 100644 index 000000000..3c8b18713 --- /dev/null +++ b/_docs/doc-update-detection/questions/exporting-results.md @@ -0,0 +1,99 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Exporting results' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/exporting-results.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/exporting-results +--- + +# Exporting results + +You can export the results of a question or dashboard. + +## Exporting results of a question + +To export the results of a questions, click on the **Download** button in the lower right of a question. + +![Exporting results of a question](./images/exporting-the-results-of-a-question.png) +You can export the results of a question as: + +- .csv +- .xlsx +- .json +- .png (if a chart) + +You can choose between downloading the results as: + +- **Formatted**: With any [formatting changes](../data-modeling/formatting) you've applied in Metabase. +- **Unformatted**: Metabase will export the raw results of the question without applying any of the [formatting you applied](../data-modeling/formatting) to the columns in the question. For example, if you formatted a floating point number to display only the first two decimal digits in the table results, exporting the unformatted results would include additional decimal digits (if any) found in the raw results. + +If you don't see the option to export results, you may not have [permissions to download results](../permissions/data#download-results-permissions). + +## Exporting pivot tables + +If you're exporting a pivot table, you'll have the option to keep the table pivoted. By default, Metabase will export the unpivoted results. + +## Export limits + +You can export (download) up to 1 million rows. + +You can change this limit with an environment variable: [`MB_DOWNLOAD_ROW_LIMIT`](../configuring-metabase/environment-variables). + +### Cell character limit in Excel exports + +Just something to be aware of: when exporting results to an Excel document (.xlsx), Metabase will limit the numbers of characters per cell to `32,767`, which is the [character limit enforced by Excel](https://support.microsoft.com/en-us/office/excel-specifications-and-limit-1672b34d-7043-467e-8e27-269d656771c3). So if you have a bonkers number of characters in a single cell, Metabase will truncate the number of characters to fit within that limit. + +## Exporting data via a public link + +You can also create a [public link](../embedding/public-links#public-link-to-export-question-results-in-csv-xlsx-json) that people can use to download data in a specific format, as well as [raw, unformatted question results](../embedding/public-links#exporting-raw-unformatted-question-results). + +## Exporting question data via alerts + +You can also export data by setting up an [alert](./alerts). + +## Exporting results of a dashboard + +You can export the results of a dashboard and its cards in different ways. + +- [Export dashboard as PDF](#export-dashboard-as-pdf) +- [Exporting dashboard card](#exporting-results-of-a-dashboard-card) +- [Exporting via dashboard subscriptions](#exporting-results-of-a-dashboard-via-dashboard-subscriptions) + +### Export dashboard as PDF + +You can export a dashboard as a PDF. Click on the **Sharing** button, then select **Export as PDF**. + +![Exporting a dashboard as a PDF](./images/export-dashboard-as-pdf.png) + +The PDF will only include screenshots of the charts as they are visible on the dashboard. + +### Exporting results of a dashboard card + +To export the results of a particular card, hover over the dashboard card, click on the three dot menu (**...**), and select **Download results**. + +![Export results of a dashboard card](./images/download-card-results.png) + +From here you can select: + +- .csv +- .xlsx +- .json +- .png (if a chart) + +To export the raw, unformatted results, hold down the `option` key for Macs, or `Alt` key for Windows, then click on the download file format. + +If you don't see this option, you may not have [permissions to download results](../permissions/data#download-results-permissions). + +### Exporting results of a dashboard via dashboard subscriptions + +You can use [dashboard subscriptions](../dashboards/subscriptions) to regularly export data from all questions on a dashboard, and include those results as an attachment. + +## Further reading + +- [Alerts](./alerts) +- [Dashboard subscriptions](../dashboards/subscriptions) +- [Tables](./visualizations/table) diff --git a/_docs/doc-update-detection/questions/images/02-widget.png b/_docs/doc-update-detection/questions/images/02-widget.png new file mode 100644 index 000000000..73ea0194f Binary files /dev/null and b/_docs/doc-update-detection/questions/images/02-widget.png differ diff --git a/_docs/doc-update-detection/questions/images/SQL-filter-widget.png b/_docs/doc-update-detection/questions/images/SQL-filter-widget.png new file mode 100644 index 000000000..1232072f7 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/SQL-filter-widget.png differ diff --git a/_docs/doc-update-detection/questions/images/SQLInterface.png b/_docs/doc-update-detection/questions/images/SQLInterface.png new file mode 100644 index 000000000..4aa8972ff Binary files /dev/null and b/_docs/doc-update-detection/questions/images/SQLInterface.png differ diff --git a/_docs/doc-update-detection/questions/images/VisualizeChoices.png b/_docs/doc-update-detection/questions/images/VisualizeChoices.png new file mode 100644 index 000000000..059481584 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/VisualizeChoices.png differ diff --git a/_docs/doc-update-detection/questions/images/add-comparison.png b/_docs/doc-update-detection/questions/images/add-comparison.png new file mode 100644 index 000000000..0af2d9234 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/add-comparison.png differ diff --git a/_docs/doc-update-detection/questions/images/after-sql-formatting.png b/_docs/doc-update-detection/questions/images/after-sql-formatting.png new file mode 100644 index 000000000..6caab952c Binary files /dev/null and b/_docs/doc-update-detection/questions/images/after-sql-formatting.png differ diff --git a/_docs/doc-update-detection/questions/images/aggregation-expression.png b/_docs/doc-update-detection/questions/images/aggregation-expression.png new file mode 100644 index 000000000..925e86e5f Binary files /dev/null and b/_docs/doc-update-detection/questions/images/aggregation-expression.png differ diff --git a/_docs/doc-update-detection/questions/images/area.png b/_docs/doc-update-detection/questions/images/area.png new file mode 100644 index 000000000..45f242313 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/area.png differ diff --git a/_docs/doc-update-detection/questions/images/auto-format.png b/_docs/doc-update-detection/questions/images/auto-format.png new file mode 100644 index 000000000..5deab8067 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/auto-format.png differ diff --git a/_docs/doc-update-detection/questions/images/bar.png b/_docs/doc-update-detection/questions/images/bar.png new file mode 100644 index 000000000..517e099c2 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/bar.png differ diff --git a/_docs/doc-update-detection/questions/images/before-sql-formatting.png b/_docs/doc-update-detection/questions/images/before-sql-formatting.png new file mode 100644 index 000000000..4696bb5b5 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/before-sql-formatting.png differ diff --git a/_docs/doc-update-detection/questions/images/bin-by-latlong.png b/_docs/doc-update-detection/questions/images/bin-by-latlong.png new file mode 100644 index 000000000..89c702e95 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/bin-by-latlong.png differ diff --git a/_docs/doc-update-detection/questions/images/build-a-funnel-query.png b/_docs/doc-update-detection/questions/images/build-a-funnel-query.png new file mode 100644 index 000000000..4e8914c4c Binary files /dev/null and b/_docs/doc-update-detection/questions/images/build-a-funnel-query.png differ diff --git a/_docs/doc-update-detection/questions/images/bulk-filter-modal.png b/_docs/doc-update-detection/questions/images/bulk-filter-modal.png new file mode 100644 index 000000000..c8c059701 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/bulk-filter-modal.png differ diff --git a/_docs/doc-update-detection/questions/images/chart-formatting-options.png b/_docs/doc-update-detection/questions/images/chart-formatting-options.png new file mode 100644 index 000000000..b74c0b523 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/chart-formatting-options.png differ diff --git a/_docs/doc-update-detection/questions/images/column-header-formatting.png b/_docs/doc-update-detection/questions/images/column-header-formatting.png new file mode 100644 index 000000000..d96567b3b Binary files /dev/null and b/_docs/doc-update-detection/questions/images/column-header-formatting.png differ diff --git a/_docs/doc-update-detection/questions/images/column-selection.png b/_docs/doc-update-detection/questions/images/column-selection.png new file mode 100644 index 000000000..7729242d3 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/column-selection.png differ diff --git a/_docs/doc-update-detection/questions/images/combo-chart-data-1.png b/_docs/doc-update-detection/questions/images/combo-chart-data-1.png new file mode 100644 index 000000000..59b2cec27 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/combo-chart-data-1.png differ diff --git a/_docs/doc-update-detection/questions/images/combo-chart-data-2.png b/_docs/doc-update-detection/questions/images/combo-chart-data-2.png new file mode 100644 index 000000000..b6371aad8 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/combo-chart-data-2.png differ diff --git a/_docs/doc-update-detection/questions/images/combo-chart.png b/_docs/doc-update-detection/questions/images/combo-chart.png new file mode 100644 index 000000000..f3868f1f7 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/combo-chart.png differ diff --git a/_docs/doc-update-detection/questions/images/conditional-formatting.png b/_docs/doc-update-detection/questions/images/conditional-formatting.png new file mode 100644 index 000000000..58ffeba79 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/conditional-formatting.png differ diff --git a/_docs/doc-update-detection/questions/images/count-and-average.png b/_docs/doc-update-detection/questions/images/count-and-average.png new file mode 100644 index 000000000..335fde93e Binary files /dev/null and b/_docs/doc-update-detection/questions/images/count-and-average.png differ diff --git a/_docs/doc-update-detection/questions/images/cumulative-date-category.png b/_docs/doc-update-detection/questions/images/cumulative-date-category.png new file mode 100644 index 000000000..62f6d5ab8 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/cumulative-date-category.png differ diff --git a/_docs/doc-update-detection/questions/images/cumulative-multiple-datetimes.png b/_docs/doc-update-detection/questions/images/cumulative-multiple-datetimes.png new file mode 100644 index 000000000..ca2a963b4 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/cumulative-multiple-datetimes.png differ diff --git a/_docs/doc-update-detection/questions/images/cumulative-no-datetime-order.png b/_docs/doc-update-detection/questions/images/cumulative-no-datetime-order.png new file mode 100644 index 000000000..2165c7968 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/cumulative-no-datetime-order.png differ diff --git a/_docs/doc-update-detection/questions/images/cumulative-no-datetime.png b/_docs/doc-update-detection/questions/images/cumulative-no-datetime.png new file mode 100644 index 000000000..dc47eac75 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/cumulative-no-datetime.png differ diff --git a/_docs/doc-update-detection/questions/images/custom-column.png b/_docs/doc-update-detection/questions/images/custom-column.png new file mode 100644 index 000000000..698c975bc Binary files /dev/null and b/_docs/doc-update-detection/questions/images/custom-column.png differ diff --git a/_docs/doc-update-detection/questions/images/custom-expression-editor.png b/_docs/doc-update-detection/questions/images/custom-expression-editor.png new file mode 100644 index 000000000..8d808377b Binary files /dev/null and b/_docs/doc-update-detection/questions/images/custom-expression-editor.png differ diff --git a/_docs/doc-update-detection/questions/images/data-picker.png b/_docs/doc-update-detection/questions/images/data-picker.png new file mode 100644 index 000000000..72e246f8a Binary files /dev/null and b/_docs/doc-update-detection/questions/images/data-picker.png differ diff --git a/_docs/doc-update-detection/questions/images/detail.png b/_docs/doc-update-detection/questions/images/detail.png new file mode 100644 index 000000000..2e5aff237 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/detail.png differ diff --git a/_docs/doc-update-detection/questions/images/diff-and-percentage.png b/_docs/doc-update-detection/questions/images/diff-and-percentage.png new file mode 100644 index 000000000..3449b835b Binary files /dev/null and b/_docs/doc-update-detection/questions/images/diff-and-percentage.png differ diff --git a/_docs/doc-update-detection/questions/images/download-card-results.png b/_docs/doc-update-detection/questions/images/download-card-results.png new file mode 100644 index 000000000..f18be9aec Binary files /dev/null and b/_docs/doc-update-detection/questions/images/download-card-results.png differ diff --git a/_docs/doc-update-detection/questions/images/drill-through-menu.png b/_docs/doc-update-detection/questions/images/drill-through-menu.png new file mode 100644 index 000000000..156397325 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/drill-through-menu.png differ diff --git a/_docs/doc-update-detection/questions/images/editor.png b/_docs/doc-update-detection/questions/images/editor.png new file mode 100644 index 000000000..fa8b1b061 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/editor.png differ diff --git a/_docs/doc-update-detection/questions/images/explore-results.png b/_docs/doc-update-detection/questions/images/explore-results.png new file mode 100644 index 000000000..4e8601e99 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/explore-results.png differ diff --git a/_docs/doc-update-detection/questions/images/export-dashboard-as-pdf.png b/_docs/doc-update-detection/questions/images/export-dashboard-as-pdf.png new file mode 100644 index 000000000..af403c3df Binary files /dev/null and b/_docs/doc-update-detection/questions/images/export-dashboard-as-pdf.png differ diff --git a/_docs/doc-update-detection/questions/images/exporting-the-results-of-a-question.png b/_docs/doc-update-detection/questions/images/exporting-the-results-of-a-question.png new file mode 100644 index 000000000..627fb656c Binary files /dev/null and b/_docs/doc-update-detection/questions/images/exporting-the-results-of-a-question.png differ diff --git a/_docs/doc-update-detection/questions/images/filter-expression.png b/_docs/doc-update-detection/questions/images/filter-expression.png new file mode 100644 index 000000000..fc910e27e Binary files /dev/null and b/_docs/doc-update-detection/questions/images/filter-expression.png differ diff --git a/_docs/doc-update-detection/questions/images/filter-step.png b/_docs/doc-update-detection/questions/images/filter-step.png new file mode 100644 index 000000000..af569cf4d Binary files /dev/null and b/_docs/doc-update-detection/questions/images/filter-step.png differ diff --git a/_docs/doc-update-detection/questions/images/function-browser.png b/_docs/doc-update-detection/questions/images/function-browser.png new file mode 100644 index 000000000..1257bb174 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/function-browser.png differ diff --git a/_docs/doc-update-detection/questions/images/funnel-as-sql.png b/_docs/doc-update-detection/questions/images/funnel-as-sql.png new file mode 100644 index 000000000..cbad6d22b Binary files /dev/null and b/_docs/doc-update-detection/questions/images/funnel-as-sql.png differ diff --git a/_docs/doc-update-detection/questions/images/funnel-settings.png b/_docs/doc-update-detection/questions/images/funnel-settings.png new file mode 100644 index 000000000..ef9a3c041 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/funnel-settings.png differ diff --git a/_docs/doc-update-detection/questions/images/funnel.png b/_docs/doc-update-detection/questions/images/funnel.png new file mode 100644 index 000000000..3fff9554f Binary files /dev/null and b/_docs/doc-update-detection/questions/images/funnel.png differ diff --git a/_docs/doc-update-detection/questions/images/gauge-format.png b/_docs/doc-update-detection/questions/images/gauge-format.png new file mode 100644 index 000000000..b5eeb3af9 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/gauge-format.png differ diff --git a/_docs/doc-update-detection/questions/images/gauge-labeled.png b/_docs/doc-update-detection/questions/images/gauge-labeled.png new file mode 100644 index 000000000..52782b5e4 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/gauge-labeled.png differ diff --git a/_docs/doc-update-detection/questions/images/gauge.png b/_docs/doc-update-detection/questions/images/gauge.png new file mode 100644 index 000000000..ed3c01792 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/gauge.png differ diff --git a/_docs/doc-update-detection/questions/images/get-alerts-about-this.png b/_docs/doc-update-detection/questions/images/get-alerts-about-this.png new file mode 100644 index 000000000..322de387b Binary files /dev/null and b/_docs/doc-update-detection/questions/images/get-alerts-about-this.png differ diff --git a/_docs/doc-update-detection/questions/images/goal-line.png b/_docs/doc-update-detection/questions/images/goal-line.png new file mode 100644 index 000000000..34ac0d8d0 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/goal-line.png differ diff --git a/_docs/doc-update-detection/questions/images/grid-map.png b/_docs/doc-update-detection/questions/images/grid-map.png new file mode 100644 index 000000000..bad9f3b0e Binary files /dev/null and b/_docs/doc-update-detection/questions/images/grid-map.png differ diff --git a/_docs/doc-update-detection/questions/images/group-by-week-of-year.png b/_docs/doc-update-detection/questions/images/group-by-week-of-year.png new file mode 100644 index 000000000..525b22ab8 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/group-by-week-of-year.png differ diff --git a/_docs/doc-update-detection/questions/images/highlight_and_save_as_snippet.gif b/_docs/doc-update-detection/questions/images/highlight_and_save_as_snippet.gif new file mode 100644 index 000000000..e30aeaf41 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/highlight_and_save_as_snippet.gif differ diff --git a/_docs/doc-update-detection/questions/images/histogram-bins.png b/_docs/doc-update-detection/questions/images/histogram-bins.png new file mode 100644 index 000000000..bdd9c8b98 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/histogram-bins.png differ diff --git a/_docs/doc-update-detection/questions/images/histogram.png b/_docs/doc-update-detection/questions/images/histogram.png new file mode 100644 index 000000000..2e246dd0b Binary files /dev/null and b/_docs/doc-update-detection/questions/images/histogram.png differ diff --git a/_docs/doc-update-detection/questions/images/info-sidesheet.png b/_docs/doc-update-detection/questions/images/info-sidesheet.png new file mode 100644 index 000000000..580cdf343 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/info-sidesheet.png differ diff --git a/_docs/doc-update-detection/questions/images/join-a-b-c.png b/_docs/doc-update-detection/questions/images/join-a-b-c.png new file mode 100644 index 000000000..aadfea585 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/join-a-b-c.png differ diff --git a/_docs/doc-update-detection/questions/images/join-operator.png b/_docs/doc-update-detection/questions/images/join-operator.png new file mode 100644 index 000000000..c70b54b7a Binary files /dev/null and b/_docs/doc-update-detection/questions/images/join-operator.png differ diff --git a/_docs/doc-update-detection/questions/images/join-pick-data.png b/_docs/doc-update-detection/questions/images/join-pick-data.png new file mode 100644 index 000000000..a3a27346a Binary files /dev/null and b/_docs/doc-update-detection/questions/images/join-pick-data.png differ diff --git a/_docs/doc-update-detection/questions/images/join-step.png b/_docs/doc-update-detection/questions/images/join-step.png new file mode 100644 index 000000000..14e526d5d Binary files /dev/null and b/_docs/doc-update-detection/questions/images/join-step.png differ diff --git a/_docs/doc-update-detection/questions/images/joining-on-multiple-columns.png b/_docs/doc-update-detection/questions/images/joining-on-multiple-columns.png new file mode 100644 index 000000000..1881079e7 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/joining-on-multiple-columns.png differ diff --git a/_docs/doc-update-detection/questions/images/latlong-binned-result.png b/_docs/doc-update-detection/questions/images/latlong-binned-result.png new file mode 100644 index 000000000..5b957401d Binary files /dev/null and b/_docs/doc-update-detection/questions/images/latlong-binned-result.png differ diff --git a/_docs/doc-update-detection/questions/images/legend.png b/_docs/doc-update-detection/questions/images/legend.png new file mode 100644 index 000000000..5ddf1b86d Binary files /dev/null and b/_docs/doc-update-detection/questions/images/legend.png differ diff --git a/_docs/doc-update-detection/questions/images/line-options.png b/_docs/doc-update-detection/questions/images/line-options.png new file mode 100644 index 000000000..de0eaa640 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/line-options.png differ diff --git a/_docs/doc-update-detection/questions/images/map-alternative.png b/_docs/doc-update-detection/questions/images/map-alternative.png new file mode 100644 index 000000000..1482ced23 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/map-alternative.png differ diff --git a/_docs/doc-update-detection/questions/images/map-tiles.png b/_docs/doc-update-detection/questions/images/map-tiles.png new file mode 100644 index 000000000..c3b766df6 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/map-tiles.png differ diff --git a/_docs/doc-update-detection/questions/images/map-types.png b/_docs/doc-update-detection/questions/images/map-types.png new file mode 100644 index 000000000..0d3f17cd4 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/map-types.png differ diff --git a/_docs/doc-update-detection/questions/images/map.png b/_docs/doc-update-detection/questions/images/map.png new file mode 100644 index 000000000..bedffed94 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/map.png differ diff --git a/_docs/doc-update-detection/questions/images/metrics-in-tooltip.png b/_docs/doc-update-detection/questions/images/metrics-in-tooltip.png new file mode 100644 index 000000000..6a2d1b8c7 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/metrics-in-tooltip.png differ diff --git a/_docs/doc-update-detection/questions/images/multiple-metrics.png b/_docs/doc-update-detection/questions/images/multiple-metrics.png new file mode 100644 index 000000000..8fc3065da Binary files /dev/null and b/_docs/doc-update-detection/questions/images/multiple-metrics.png differ diff --git a/_docs/doc-update-detection/questions/images/multiple-summarize-steps.png b/_docs/doc-update-detection/questions/images/multiple-summarize-steps.png new file mode 100644 index 000000000..f9e483c83 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/multiple-summarize-steps.png differ diff --git a/_docs/doc-update-detection/questions/images/native-editor.png b/_docs/doc-update-detection/questions/images/native-editor.png new file mode 100644 index 000000000..2b8d0552e Binary files /dev/null and b/_docs/doc-update-detection/questions/images/native-editor.png differ diff --git a/_docs/doc-update-detection/questions/images/notebook-editor.png b/_docs/doc-update-detection/questions/images/notebook-editor.png new file mode 100644 index 000000000..aa9c23a86 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/notebook-editor.png differ diff --git a/_docs/doc-update-detection/questions/images/number.png b/_docs/doc-update-detection/questions/images/number.png new file mode 100644 index 000000000..c42ac28d5 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/number.png differ diff --git a/_docs/doc-update-detection/questions/images/paginate-table-on-dashboard-card.png b/_docs/doc-update-detection/questions/images/paginate-table-on-dashboard-card.png new file mode 100644 index 000000000..c748cf391 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/paginate-table-on-dashboard-card.png differ diff --git a/_docs/doc-update-detection/questions/images/pie-other-slice.png b/_docs/doc-update-detection/questions/images/pie-other-slice.png new file mode 100644 index 000000000..124523a47 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/pie-other-slice.png differ diff --git a/_docs/doc-update-detection/questions/images/pie-sunburst-demo.png b/_docs/doc-update-detection/questions/images/pie-sunburst-demo.png new file mode 100644 index 000000000..a0f0c88f8 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/pie-sunburst-demo.png differ diff --git a/_docs/doc-update-detection/questions/images/pin-data-shape.png b/_docs/doc-update-detection/questions/images/pin-data-shape.png new file mode 100644 index 000000000..f72c67d11 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/pin-data-shape.png differ diff --git a/_docs/doc-update-detection/questions/images/pin-map-with-tooltip.png b/_docs/doc-update-detection/questions/images/pin-map-with-tooltip.png new file mode 100644 index 000000000..abc35c63d Binary files /dev/null and b/_docs/doc-update-detection/questions/images/pin-map-with-tooltip.png differ diff --git a/_docs/doc-update-detection/questions/images/pivot-table-notebook.png b/_docs/doc-update-detection/questions/images/pivot-table-notebook.png new file mode 100644 index 000000000..e29b37a68 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/pivot-table-notebook.png differ diff --git a/_docs/doc-update-detection/questions/images/pivot-table-options.png b/_docs/doc-update-detection/questions/images/pivot-table-options.png new file mode 100644 index 000000000..187f227d8 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/pivot-table-options.png differ diff --git a/_docs/doc-update-detection/questions/images/pivot.png b/_docs/doc-update-detection/questions/images/pivot.png new file mode 100644 index 000000000..d1620bf8f Binary files /dev/null and b/_docs/doc-update-detection/questions/images/pivot.png differ diff --git a/_docs/doc-update-detection/questions/images/plain-pie.png b/_docs/doc-update-detection/questions/images/plain-pie.png new file mode 100644 index 000000000..cac0cc060 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/plain-pie.png differ diff --git a/_docs/doc-update-detection/questions/images/preview-table.png b/_docs/doc-update-detection/questions/images/preview-table.png new file mode 100644 index 000000000..d7a63f2a2 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/preview-table.png differ diff --git a/_docs/doc-update-detection/questions/images/progress-bar-elements.png b/_docs/doc-update-detection/questions/images/progress-bar-elements.png new file mode 100644 index 000000000..80ffc13a4 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/progress-bar-elements.png differ diff --git a/_docs/doc-update-detection/questions/images/progress-with-format.png b/_docs/doc-update-detection/questions/images/progress-with-format.png new file mode 100644 index 000000000..55497ce33 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/progress-with-format.png differ diff --git a/_docs/doc-update-detection/questions/images/progress.png b/_docs/doc-update-detection/questions/images/progress.png new file mode 100644 index 000000000..e161f5fda Binary files /dev/null and b/_docs/doc-update-detection/questions/images/progress.png differ diff --git a/_docs/doc-update-detection/questions/images/question.png b/_docs/doc-update-detection/questions/images/question.png new file mode 100644 index 000000000..1a5cd8a84 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/question.png differ diff --git a/_docs/doc-update-detection/questions/images/read-a-funnel.png b/_docs/doc-update-detection/questions/images/read-a-funnel.png new file mode 100644 index 000000000..7a1f4f502 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/read-a-funnel.png differ diff --git a/_docs/doc-update-detection/questions/images/region-map-query.png b/_docs/doc-update-detection/questions/images/region-map-query.png new file mode 100644 index 000000000..aa686f728 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/region-map-query.png differ diff --git a/_docs/doc-update-detection/questions/images/region-maps.png b/_docs/doc-update-detection/questions/images/region-maps.png new file mode 100644 index 000000000..78c020807 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/region-maps.png differ diff --git a/_docs/doc-update-detection/questions/images/rolling-average.png b/_docs/doc-update-detection/questions/images/rolling-average.png new file mode 100644 index 000000000..dddcf6f85 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/rolling-average.png differ diff --git a/_docs/doc-update-detection/questions/images/row.png b/_docs/doc-update-detection/questions/images/row.png new file mode 100644 index 000000000..94e426df2 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/row.png differ diff --git a/_docs/doc-update-detection/questions/images/sankey-data-options.png b/_docs/doc-update-detection/questions/images/sankey-data-options.png new file mode 100644 index 000000000..92ba39f00 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/sankey-data-options.png differ diff --git a/_docs/doc-update-detection/questions/images/sankey-gray-edges.png b/_docs/doc-update-detection/questions/images/sankey-gray-edges.png new file mode 100644 index 000000000..56df08738 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/sankey-gray-edges.png differ diff --git a/_docs/doc-update-detection/questions/images/sankey-left-aligned.png b/_docs/doc-update-detection/questions/images/sankey-left-aligned.png new file mode 100644 index 000000000..c9b2d2a3a Binary files /dev/null and b/_docs/doc-update-detection/questions/images/sankey-left-aligned.png differ diff --git a/_docs/doc-update-detection/questions/images/sankey-right-aligned.png b/_docs/doc-update-detection/questions/images/sankey-right-aligned.png new file mode 100644 index 000000000..5d1bf7fa5 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/sankey-right-aligned.png differ diff --git a/_docs/doc-update-detection/questions/images/sankey-summarize-count-source-target.png b/_docs/doc-update-detection/questions/images/sankey-summarize-count-source-target.png new file mode 100644 index 000000000..7648a0130 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/sankey-summarize-count-source-target.png differ diff --git a/_docs/doc-update-detection/questions/images/scatter.png b/_docs/doc-update-detection/questions/images/scatter.png new file mode 100644 index 000000000..91060d975 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/scatter.png differ diff --git a/_docs/doc-update-detection/questions/images/search-dropdown.png b/_docs/doc-update-detection/questions/images/search-dropdown.png new file mode 100644 index 000000000..5f1aeb67f Binary files /dev/null and b/_docs/doc-update-detection/questions/images/search-dropdown.png differ diff --git a/_docs/doc-update-detection/questions/images/select-region-map.png b/_docs/doc-update-detection/questions/images/select-region-map.png new file mode 100644 index 000000000..6e279a6be Binary files /dev/null and b/_docs/doc-update-detection/questions/images/select-region-map.png differ diff --git a/_docs/doc-update-detection/questions/images/show-row-index.png b/_docs/doc-update-detection/questions/images/show-row-index.png new file mode 100644 index 000000000..f6a59a745 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/show-row-index.png differ diff --git a/_docs/doc-update-detection/questions/images/snippet_sidebar_and_insertion.gif b/_docs/doc-update-detection/questions/images/snippet_sidebar_and_insertion.gif new file mode 100644 index 000000000..16941df34 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/snippet_sidebar_and_insertion.gif differ diff --git a/_docs/doc-update-detection/questions/images/sort-step.png b/_docs/doc-update-detection/questions/images/sort-step.png new file mode 100644 index 000000000..ea865a53b Binary files /dev/null and b/_docs/doc-update-detection/questions/images/sort-step.png differ diff --git a/_docs/doc-update-detection/questions/images/sql-sidebar.png b/_docs/doc-update-detection/questions/images/sql-sidebar.png new file mode 100644 index 000000000..181200aaa Binary files /dev/null and b/_docs/doc-update-detection/questions/images/sql-sidebar.png differ diff --git a/_docs/doc-update-detection/questions/images/stacked-100.png b/_docs/doc-update-detection/questions/images/stacked-100.png new file mode 100644 index 000000000..d20461561 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/stacked-100.png differ diff --git a/_docs/doc-update-detection/questions/images/stacked-bar-chart.png b/_docs/doc-update-detection/questions/images/stacked-bar-chart.png new file mode 100644 index 000000000..1ff7acb0c Binary files /dev/null and b/_docs/doc-update-detection/questions/images/stacked-bar-chart.png differ diff --git a/_docs/doc-update-detection/questions/images/state-field-filter.png b/_docs/doc-update-detection/questions/images/state-field-filter.png new file mode 100644 index 000000000..f66b4c178 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/state-field-filter.png differ diff --git a/_docs/doc-update-detection/questions/images/sum-of-totals-for-previous-period.png b/_docs/doc-update-detection/questions/images/sum-of-totals-for-previous-period.png new file mode 100644 index 000000000..123c3b864 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/sum-of-totals-for-previous-period.png differ diff --git a/_docs/doc-update-detection/questions/images/summarize-by-week-of-year.png b/_docs/doc-update-detection/questions/images/summarize-by-week-of-year.png new file mode 100644 index 000000000..ef294da62 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/summarize-by-week-of-year.png differ diff --git a/_docs/doc-update-detection/questions/images/summarize-step.png b/_docs/doc-update-detection/questions/images/summarize-step.png new file mode 100644 index 000000000..c1d23d964 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/summarize-step.png differ diff --git a/_docs/doc-update-detection/questions/images/summarize-timeseries-breakout.png b/_docs/doc-update-detection/questions/images/summarize-timeseries-breakout.png new file mode 100644 index 000000000..f3d5fb490 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/summarize-timeseries-breakout.png differ diff --git a/_docs/doc-update-detection/questions/images/summarize-timeseries.png b/_docs/doc-update-detection/questions/images/summarize-timeseries.png new file mode 100644 index 000000000..cbaef351e Binary files /dev/null and b/_docs/doc-update-detection/questions/images/summarize-timeseries.png differ diff --git a/_docs/doc-update-detection/questions/images/sunburst-metric-options.png b/_docs/doc-update-detection/questions/images/sunburst-metric-options.png new file mode 100644 index 000000000..707e82393 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/sunburst-metric-options.png differ diff --git a/_docs/doc-update-detection/questions/images/sunburst-settings-showcase.png b/_docs/doc-update-detection/questions/images/sunburst-settings-showcase.png new file mode 100644 index 000000000..dc9697c66 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/sunburst-settings-showcase.png differ diff --git a/_docs/doc-update-detection/questions/images/sunburst-two-levels.png b/_docs/doc-update-detection/questions/images/sunburst-two-levels.png new file mode 100644 index 000000000..e2ebcfafb Binary files /dev/null and b/_docs/doc-update-detection/questions/images/sunburst-two-levels.png differ diff --git a/_docs/doc-update-detection/questions/images/switch-to-editor.png b/_docs/doc-update-detection/questions/images/switch-to-editor.png new file mode 100644 index 000000000..287678689 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/switch-to-editor.png differ diff --git a/_docs/doc-update-detection/questions/images/tooltip.png b/_docs/doc-update-detection/questions/images/tooltip.png new file mode 100644 index 000000000..6e0dab42a Binary files /dev/null and b/_docs/doc-update-detection/questions/images/tooltip.png differ diff --git a/_docs/doc-update-detection/questions/images/trend-lines.png b/_docs/doc-update-detection/questions/images/trend-lines.png new file mode 100644 index 000000000..21ce33f61 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/trend-lines.png differ diff --git a/_docs/doc-update-detection/questions/images/trend-settings.png b/_docs/doc-update-detection/questions/images/trend-settings.png new file mode 100644 index 000000000..2f1b7fb7e Binary files /dev/null and b/_docs/doc-update-detection/questions/images/trend-settings.png differ diff --git a/_docs/doc-update-detection/questions/images/unpinned-from-zero-y-axis.png b/_docs/doc-update-detection/questions/images/unpinned-from-zero-y-axis.png new file mode 100644 index 000000000..b37449e7a Binary files /dev/null and b/_docs/doc-update-detection/questions/images/unpinned-from-zero-y-axis.png differ diff --git a/_docs/doc-update-detection/questions/images/view-the-sql.png b/_docs/doc-update-detection/questions/images/view-the-sql.png new file mode 100644 index 000000000..5d118de41 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/view-the-sql.png differ diff --git a/_docs/doc-update-detection/questions/images/visualize-native.png b/_docs/doc-update-detection/questions/images/visualize-native.png new file mode 100644 index 000000000..25cba6560 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/visualize-native.png differ diff --git a/_docs/doc-update-detection/questions/images/viz-options.png b/_docs/doc-update-detection/questions/images/viz-options.png new file mode 100644 index 000000000..b215f39ef Binary files /dev/null and b/_docs/doc-update-detection/questions/images/viz-options.png differ diff --git a/_docs/doc-update-detection/questions/images/waterfall-chart.png b/_docs/doc-update-detection/questions/images/waterfall-chart.png new file mode 100644 index 000000000..25562fffc Binary files /dev/null and b/_docs/doc-update-detection/questions/images/waterfall-chart.png differ diff --git a/_docs/doc-update-detection/questions/images/week-instance.png b/_docs/doc-update-detection/questions/images/week-instance.png new file mode 100644 index 000000000..347454663 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/week-instance.png differ diff --git a/_docs/doc-update-detection/questions/images/week-iso.png b/_docs/doc-update-detection/questions/images/week-iso.png new file mode 100644 index 000000000..82cf0608b Binary files /dev/null and b/_docs/doc-update-detection/questions/images/week-iso.png differ diff --git a/_docs/doc-update-detection/questions/images/week-us.png b/_docs/doc-update-detection/questions/images/week-us.png new file mode 100644 index 000000000..6177879f0 Binary files /dev/null and b/_docs/doc-update-detection/questions/images/week-us.png differ diff --git a/_docs/doc-update-detection/questions/images/year-over-year-sum-totals.png b/_docs/doc-update-detection/questions/images/year-over-year-sum-totals.png new file mode 100644 index 000000000..335ce262b Binary files /dev/null and b/_docs/doc-update-detection/questions/images/year-over-year-sum-totals.png differ diff --git a/_docs/doc-update-detection/questions/introduction.md b/_docs/doc-update-detection/questions/introduction.md new file mode 100644 index 000000000..e0d6e30c4 --- /dev/null +++ b/_docs/doc-update-detection/questions/introduction.md @@ -0,0 +1,120 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Questions +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/introduction.md' +redirect_from: + - /docs/doc-update-detection/users-guide/04-asking-questions + - /docs/doc-update-detection/users-guide/06-sharing-answers +--- + +# Questions + +![Metabase question](./images/question.png) + +Questions in Metabase are queries, their results, and their visualization. Questions are the basic analytical unit in Metabase. You can think about questions as saved queries that you can display as tables or charts. You can organize questions into collections and dashboards. You can [embed questions](../embedding/start), share links to them, export their results, and have them alert you when results are interesting. + +## Creating a new question + +You can create a new question from scratch, or build off of an existing question. To create a question from scratch, you can click on **+ New** and select how you want to query your data: either with the graphical query builder, or the SQL/native editor. + +### Query builder + +![Query builder editor](./images/editor.png) + +Selecting **Question** will take you to the [editor in the graphical query builder](./query-builder/editor). + +### Native editor + +![Native editor](./images/native-editor.png) + +Selecting **SQL/native code** will open the [native code editor](./native-editor/writing-sql). + +Even if you know SQL, you should still check out the [graphical query builder](./query-builder/editor), as you can use it to build [interactive charts](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). + +### From an existing question + +You can also build a new question from an existing question. You won't overwrite the existing question, so feel free to play around. You can use either the [query builder](./query-builder/editor) or the [native code editor](./native-editor/referencing-saved-questions-in-queries). + +Some kinds of saved questions, however, can't be used as source data: + +- Druid questions +- Mongo questions +- Questions that use `Cumulative Sum` or `Cumulative Count` aggregations +- Questions that have columns that are named the same or similar thing, like `Count` and `Count 2` + +## Saving questions + +Once you've built your query and [visualized its results](./visualizations/visualizing-results), you can save a question to a [dashboard](../dashboards/introduction) (the default), or to a [collection](../exploration-and-organization/collections). You'll need to name the question, include an optional description, and save it to a dashboard or a collection. + +### Saving questions to dashboards + +Questions that live in a dashboard are only visible in that dashboard. These questions can't be used in other dashboards. When you save a question to a dashboard, you'll need to arrange the card on one of the dashboard's tab, then save the dashboard. + +### Saving questions to collections + +Questions saved to a collection can be added to multiple dashboards. Moving a question from one collection to another collection won't have any effect on the dashboards the question has been added to. In order to save a question to a collection, you'll need to be in a group with [curate access](../permissions/collections#curate-access) to that collection. + +## Moving questions from collections to dashboards (and vice versa) + +Whether you can move a question in a collection into a dashboard depends on how many other dashboards use that question. + +You can move the question from a collection into a dashboard if either: + +- No other dashboards use that question. +- The other dashboards that use that question live in collections you have [curate access](../permissions/collections#curate-access) to. In this case, Metabase will tell you which other dashboards use that question, and you'll have to decide whether you're okay with removing the question from those dashboards. + +## Info about your question + +Once you save a question, you can click on the **info** icon in the upper right to see some metadata about your question: + +![Info sidesheet](./images/info-sidesheet.png) + +### Overview tab + +- Description, which you can add–descriptions even support Markdown! +- Who created the question, and who edited it last +- The collection or dashboard the question is saved in +- The data the question is based on. +- The question's Entity ID (which you can use with [Serialization](../installation-and-operation/serialization) to keep IDs consistent across multiple Metabases). + +### History tab + +See [history](../exploration-and-organization/history). + +## Downloading your question's results + +See [exporting results](./exporting-results). + +## Verifying a question + +See [content verification](../exploration-and-organization/content-verification). + +## Bookmark a question + +Click the **bookmark** icon to pin a question to your Metabase sidebar. See [Bookmarks](../exploration-and-organization/exploration#bookmarks). + +## Turning a question into a model + +You can turn a question saved to a collection into a model to let others know that the results make a good starting point for new questions. (You can't turn a question saved to a _dashboard_ into a model; you'll first need to move the question to a collection). See [models](../data-modeling/models). + +## Caching question results + +{% include plans-blockquote.html feature="Caching question results" %} + +See [caching per question](../configuring-metabase/caching#question-caching-policy). + +## Setting up alerts + +You can set up questions to run periodically and notify you if the results are interesting. Check out [alerts](./alerts). + +## Viewing events on your chart + +If your results are a time series, you can display events on along the x-axis. See [events and timelines](../exploration-and-organization/events-and-timelines). + +## Deleting a question + +See [delete and restore](../exploration-and-organization/delete-and-restore). diff --git a/_docs/doc-update-detection/questions/native-editor/referencing-saved-questions-in-queries.md b/_docs/doc-update-detection/questions/native-editor/referencing-saved-questions-in-queries.md new file mode 100644 index 000000000..8788df8e3 --- /dev/null +++ b/_docs/doc-update-detection/questions/native-editor/referencing-saved-questions-in-queries.md @@ -0,0 +1,77 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Referencing models and saved questions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/native-editor/referencing-saved-questions-in-queries.md' +redirect_from: + - /docs/doc-update-detection/users-guide/referencing-saved-questions-in-queries +--- + +# Referencing models and saved questions + +With SQL databases, we can use a [model][model] or an existing question as the basis for a new query, or as a common table expression [CTE][cte]. + +For example, let's say we have a lot of data spread across a number of tables, but people are most interested in a subset of that data. We can perform a complicated query once to return those results, and save that question as a model, which people can refer to in their queries just like they would with any other table. + +## Search for models and questions as you type + +First, create and save a question or model that returns the result set you'd like to make available for people to query. + +To reference that question or model in a SQL query, use typeahead search in a variable prefixed with `#`. + +Type `{% raw %}{{#your search term }} {% endraw %}` and Metabase will display a list of models and questions relevant to your search term. + +![Typeahead search dropdown for referencing questions and models in SQL queries](../images/search-dropdown.png) + +You can also find the question or model ID by navigating in Metabase to the model or question you'd like to reference in your query. The ID is in the URL in your browser's address bar. The ID will be the number after `/model/` or `/question/`. E.g., for `https://metabase.example.com/model/12345-example-name`, the model's ID would be `12345`. + +Only the `#` and `ID` is required. Metabase just displays the model or question name to make the query more readable. + +## Model, table, or saved question as a Common Table Expression (CTE) + +The same syntax can be used in [Common Table Expressions (CTEs)](/learn/grow-your-data-skills/learn-sql/working-with-sql/sql-cte) (with SQL databases that support CTEs): + +```sql +WITH gizmo_orders AS {% raw %}{{#5-gizmo-orders-in-2019}}{% endraw %} +SELECT count(*) +FROM gizmo_orders +``` + +When this query is run, the `{% raw %}{{#5-gizmo-orders-in-2019}}{% endraw %}` tag will be substituted with the SQL query of the referenced question, surrounded by parentheses. So it'll look like this under the hood: + +```sql +WITH + gizmo_orders AS ( + SELECT + * + FROM + orders AS o + INNER JOIN products AS p ON o.product_id = p.id + WHERE + p.category = 'Gizmo' + AND o.created_at BETWEEN '2019-01-01' AND '2019-12-31' + ) +SELECT + count(*) +FROM + gizmo_orders +``` + +## Limitations and tradeoffs + +- You can only reference a model or saved question in a query when working with a SQL database like PostgreSQL, MySQL, Snowflake or SQL Server. +- The model or saved question you select has to be one that's based on the same database as the one you've currently selected in the native query editor. +- You cannot refer to variables in sub-queries. You only have access to the _results_ of the model or saved question, not the model or saved question's query. For example, if you have a saved question that uses a [field filter](/learn/metabase-basics/querying-and-dashboards/sql-in-metabase/field-filters), you won't be able to reference that variable. If you need to change how the saved question has filtered the results, you'll need to update (or duplicate) that question and apply the filter. + +## Further reading + +- [Models](../../data-modeling/models) +- [Snippets](/learn/metabase-basics/querying-and-dashboards/sql-in-metabase/sql-snippets) +- [Snippets vs Saved Questions vs. Views](/learn/metabase-basics/querying-and-dashboards/sql-in-metabase/organizing-sql) +- [SQL troubleshooting guide](../../troubleshooting-guide/sql). + +[cte]: /learn/grow-your-data-skills/learn-sql/working-with-sql/sql-cte +[model]: ../../data-modeling/models diff --git a/_docs/doc-update-detection/questions/native-editor/snippets.md b/_docs/doc-update-detection/questions/native-editor/snippets.md new file mode 100644 index 000000000..079fb1f39 --- /dev/null +++ b/_docs/doc-update-detection/questions/native-editor/snippets.md @@ -0,0 +1,111 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Snippets +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/native-editor/snippets.md' +redirect_from: + - /docs/doc-update-detection/users-guide/sql-snippets + - /docs/doc-update-detection/questions/native-editor/sql-snippets +--- + +# Snippets + +![Highlight and save as snippet](../images/highlight_and_save_as_snippet.gif) + +**Snippets** are reusable bits of SQL or native queries. Anyone with permissions to the [SQL editor](./writing-sql) can create and edit snippets, which are then available for all SQL authors. + +For example, if you frequently perform queries that involve multiple tables, you can save the SQL code that joins those tables as a snippet so that you (and others in your organization) can reuse that code in multiple questions. + +## How to create a snippet + +Here's a simple query with a join using the **Sample Database** included with Metabase. + +```sql +SELECT * +FROM orders AS o +LEFT JOIN products AS p +ON o.product_id = p.id +``` + +Let's save everything after FROM as a snippet to reuse in other queries. + +In the **SQL editor**: + +1. **Highlight a section of SQL** that you want to save. In this case, we'll select the following SQL code: + + ```sql + orders AS o + LEFT JOIN products AS p + ON o.product_id = p.id + ``` + +2. **Right-click on the highlighted section.** +3. **Select Save as snippet** to create a snippet. A modal will pop up with the SQL statement you highlighted. +4. **Edit, name, and describe your snippet**. Snippet names must be unique. Click the save button to create the snippet. + +In this case, we named the snippet "Orders and Products". The snippet will now be available for anyone to use. Here's what the snippet looks like in the SQL editor: + +```sql +SELECT * +FROM {% raw %}{{snippet: Orders and Products}}{% endraw %} +``` + +When writing in the SQL editor, you can now start typing `{% raw %}{{snippet:}}{% endraw %}` and Metabase will present autocomplete options for available snippets. + +Note: if you use aliases in a snippet, you'll need to observe those aliases outside of the snippet as well. For example, if a snippet aliases `products AS p`, code outside of the snippet will need to use the alias `p` to reference columns in that table (as in `p.column_name`). + +## Snippet menu + +![Snippet sidebar and insertion](../images/snippet_sidebar_and_insertion.gif) + +The SQL editor **sidebar** has a **Snippets** menu to list available and archived snippets. + +Click on the snippet icon on the right side of the SQL editor, below the Data Reference book icon and the Variables χ icon. Metabase will slide out a sidebar menu that lists available snippets. + +From the Snippets menu, you can: + +- **Create a snippet.** Click on the `+` in the upper right of the Snippets sidebar to create a new snippet. +- **Preview snippets.** Click on the down arrow to the right of a snippet to see its description and a preview of its SQL code. There's also an option to edit the snippet. +- **Insert a snippet.** Click on a snippet's name to insert it into your query at the cursor's current location. +- **Search for snippets**. If you've saved over 15 snippets, a **Search** icon (the classic magnifying glass) will appear to the left of the `+` button. Note that search results only include snippets the user has permissions for. Snippet folders do not populate the search results. +- [**Edit a snippet.**](#editing-snippets) You can change a snippet's name, description and code. +- [**Archive and unarchive a snippet.**](#archiving-snippets) From the Edit modal, you can archive a snippet, which removes the snippet from the snippet menu and autocomplete options in the SQL editor. + +## Editing snippets + +You can **edit** a snippet at any time by selecting the snippet from the Snippets sidebar menu in the SQL editor. Click on the down arrow to the right of the snippet, then click **Edit**. You can change the SQL code, snippet name, and snippet description. + +Editing snippets is a great way to make changes to many questions at once. If, for example, you've saved the SQL code to pull user data from tables X, Y, and Z as the snippet `User Data`, but you need to change how that data is pulled (such as by adding data from another column or table), you can update the SQL code in the snippet, and all questions that use the snippet `User Data` will have the updated code. + +**Editing a snippet's name**. Changing a snippet's name will update the snippet's name in every question that uses that snippet. It won't break any existing questions (the underlying SQL remains unchanged), but be aware that other users may be caught off guard to discover you renamed a snippet they use frequently from "Orders and Products" to "All the things", or whatever. + +**Editing a snippet's SQL.** Here's where we have to remind you that with great power comes great responsibility. There is one major caveat when editing snippets, worthy of a callout: + +> **Caution: if you edit a snippet and include broken code, you will break every question that uses that snippet.** Make sure to test your code before saving it to an existing snippet. + +## Archiving snippets + +**Archiving** snippets can help keep dated or less relevant snippets out of the way. When you archive a snippet, the snippet no longer populates in the snippet autocomplete dropdown, and the snippet will no longer show up in the main list of snippets in the **SQL editor** sidebar. + +Archiving a snippet does not affect any existing queries that use the snippet, so you can safely archive a snippet without impacting any questions. + +You can access an archived snippet from the snippet sidebar menu by clicking on the archived button in the bottom left of the sidebar. + +Although there is no way to delete a snippet, you can archive and unarchive a snippet at any time. + +Note: two snippets cannot share the same name, as even if a snippet is archived, that snippet might still be active in questions. + +## Snippet permissions + +Any user who has SQL editor permissions to at least one of your connected databases will be able to view the snippets sidebar, and will be able to create, edit, and archive or unarchive any and all snippets — even snippets intended to be used with databases the user lacks SQL editing access to. + +Some plans contain additional functionality for organizing snippets into folders and setting permissions on those folders. See our [docs on Snippet folders and permissions](../../permissions/snippets). + +## Learn more + +- [Snippets](/learn/metabase-basics/querying-and-dashboards/sql-in-metabase/sql-snippets) +- [Snippets vs Saved Questions vs Views](/learn/metabase-basics/querying-and-dashboards/sql-in-metabase/organizing-sql). +- If you're having trouble with your SQL query, go to the [SQL troubleshooting guide](../../troubleshooting-guide/sql). diff --git a/_docs/doc-update-detection/questions/native-editor/sql-parameters.md b/_docs/doc-update-detection/questions/native-editor/sql-parameters.md new file mode 100644 index 000000000..f711c4b9d --- /dev/null +++ b/_docs/doc-update-detection/questions/native-editor/sql-parameters.md @@ -0,0 +1,448 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'SQL parameters' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/native-editor/sql-parameters.md' +redirect_from: + - /docs/doc-update-detection/users-guide/13-sql-parameters +--- + +# SQL parameters + +You can create SQL templates by adding variables to your SQL queries in the [Native/SQL editor][sql-editor]. These variables will create filter widgets that you can use to change the variable's value in the query. You can also add parameters to your question's URL to set the filters' values, so that when the question loads, those values are inserted into the variables. + +![Variables](../images/02-widget.png) + +## Defining variables + +Typing `{% raw %}{{variable_name}}{% endraw %}` in your native query creates a variable called `variable_name`. + +Field Filters, a special type of filter, have a [slightly different syntax](#field-filter-syntax). + +This example defines a **Text** variable called `category`: + +```sql +{% raw %} +SELECT + count(*) +FROM + products +WHERE + category = {{category}} +{% endraw %} +``` + +Metabase will read the variable and attach a filter widget to the query, which people can use to change the value inserted into the `cat` variable with quotes. So if someone entered "Gizmo" into the filter widget, the query Metabase would run would be: + +```sql +SELECT + count(*) +FROM + products +WHERE + category = 'Gizmo' +``` + +If you're writing a native MongoDB query, your query would look more like this, with the `cat` variable being defined inside of the `match` clause. + +``` +{% raw %}[{ $match: { category: {{cat}} } }]{% endraw %} +``` + +## Setting SQL variables + +To set a SQL variable to a value, you can either: + +- Enter a value into the filter widget, and re-run the question, or +- Add a parameter to the URL and load the page. + +To add a value to the URL, follow this syntax: + +``` +?variable_name=value +``` + +For example, to set the `{% raw %}{{cat}}{%endraw%}` variable on a question to the value "Gizmo", your URL would look something like: + +``` +https://metabase.example.com/question/42-eg-question?cat=Gizmo +``` + +To set multiple variables, separate parameters with an ampersand (`&`): + +``` +https://metabase.example.com/question/42-eg-question?cat=Gizmo&maxprice=50 +``` + +## SQL variable types + +When you define a variable, the **Variables** side panel will appear. You can set a type for a variable, which changes the kind of filter widget that Metabase presents. + +There are four types of variables: + +- **Text**: a plain input box. +- **Number**: a plain input box. +- **Date**: a simple date picker. If you want a more expressive date picker, like specifying a range, you'll want to use a Field Filter. +- **[Field Filter](#the-field-filter-variable-type)**: different filter widgets, depending on the mapped field. + +That last variable type, [Field Filter](#the-field-filter-variable-type), is special; it lets you create "smart" filter widgets, like a search box, or a dropdown menu of values, or a dynamic date picker that allows you to specify a date range. + +You can include multiple variables in the query, and Metabase will add multiple filter widgets to the question. When you have multiple filter widgets, you can click on a filter widget and drag it around to rearrange the order. + +## The Field Filter variable type + +Setting a variable to the **Field Filter** type allows you to map the variable to a field in any table in the current database. Field filters let you create a "smart" filter widget that makes sense for that field. + +Field Filter variables should be used inside of a `WHERE` clause in SQL, or a `$match` clause in MongoDB. + +### Field Filter compatible types + +Field Filters ONLY work with the following field types: + +- Category +- Entity Name +- Entity Key +- Foreign Key +- City +- State +- ZIP or Postal Code + +The field can also be a date or timestamp, which can be left as "No semantic type" in the [Table Metadata](../../data-modeling/metadata-editing). + +When you set the **Variable type** to "Field Filter", Metabase will present an option to set the **Field to map to**, as well as the **Filter widget type**. The options available for the Filter widget type depend on the field's type. For example, if you map to a field of type Category, you'll see options for either "Category" or None. If you map to a Date Field, you'll see options for None, Month and year, Quarter and year, Single date, Date range, or Date filter. + +If you're not seeing the option to display a filter widget, make sure the mapped field is set to one of the above types, and then try manually syncing your database from the "Databases" section of the Admin Panel to force Metabase to scan and cache the field's values. + +If you want to map a Field Filter to a field that isn't one of the compatible types listed above, you'll need an Admin to change the field type for that column. See [metadata editing](../../data-modeling/metadata-editing). + +## Field Filter syntax + +Let's say you want to create a Field Filter that filters the `People` table by state, and you want people to be able to select multiple states at a time. Here's the query: + +The syntax for Field Filters differs from a Text, Number, or Date variable. + +```sql +{% raw %} +SELECT + * +FROM + PEOPLE +WHERE + {{state}} +{% endraw %} +``` + +Then, in the side panel, select the "Field Filter" variable type, and choose which field to map your variable to (in this case, `State`). + +Note the lack of the column and operator (like `=`). The reason you need to structure Field Filters this way is to handle cases where Metabase generates the code for you. For example, for handling cases where someone selects multiple values in the filter widget, or a range of dates. With Field Filters, you can't control the generated SQL, so if you need greater control, you should use one (or more) Text, Number, or Date variables. + +A MongoDB native query example might look like this: + +``` +{% raw %}[ {$match: {{date_var}} } ]{% endraw %} +``` + +For a more in-depth guide, check out [Field Filters: create smart filter widgets for SQL questions][field-filter]. + +### Field filters in BigQuery and Oracle + +Make sure your SQL dialect matches the database you've selected. Common issues involving how tables are quoted in the query: + +| Database | Dialect quirk | Example | +| -------- | --------------------------------------------------- | -------------------------- | +| BigQuery | Schemas and tables must be quoted with backticks. | `` FROM `dataset.table` `` | +| Oracle | Schemas and tables must be quoted in double quotes. | `FROM schema.table` | + +For more help, see [Troubleshooting SQL error messages](../../troubleshooting-guide/error-message#sql-editor). + +## How to create different types of filter widgets + +The kind of filter widget that Metabase displays when you create a Field Filter widget depends on a setting for that field in Metabase called **Filtering on this field**. Admins can set this field option to: + +- Plain input box +- Search box +- A list of all values (also known as a dropdown menu) + +Date fields will either have a simple date filter (for Date variables) or a dynamic date picker (for Field Filters mapped to a date field). + +If you want to change the filter widget for a particular field, you'll need to ask an Admin to update that field in [the Table Metadata](../../data-modeling/metadata-editing) and set the desired "Filtering on this field" option. + +### Filter widget with plain input box + +Create a simple **Text** or **Number** variable. Additionally, you can use a Field Filter with a field that has its **Filtering on this field** value set to "Plain input box". + +Note: to guard against SQL injection attacks, Metabase converts whatever is in the Search box to a string. If you want to use wildcards, check out [our Learn article][basic-input]. + +### Filter widget with search box + +- Include a SQL variable in your query. +- Set the **Variable type** to **Field Filter**. +- Set the **Field to map to** to a field of type "Category" that has its **Filtering on this field** option set to "Search box" + +### Filter widget with dropdown menu and search + +To create a dropdown menu with search and a list of all values, you need to: + +- Include a SQL variable in your query. +- Set the **Variable type** to **Field Filter**. +- Set the **Field to map to** to a field of type "Category" that has its **Filtering on this field** option set to "A list of all values". +- Set the **Filter widget type** to "Category". + +If the field you want to create a dropdown for is not set to the type "Category" with **Filtering on this field** set to "A list of all values", an Admin will need to update the settings for that field. For example, if you want to create a dropdown menu for an incompatible field type like an Email field, an admin will need to change that field type to "Category", set the **Filtering on this field** option to **A list of all values**, then re-scan the values for that field. + +If however, there are too many different values in that column to display in a dropdown menu, Metabase will simply display a search box instead. So if you have a lot of email addresses, you may just get a search box anyway. The dropdown menu widgets work better when there's a small set of values to choose from (like the fifty U.S. states). + +## Field filter limitations + +Some things that could trip you up when trying to set up a Field Filter variable. + +### Field Filters don't work with table aliases + +You won't be able to select values from field filters in queries that use table aliases for joins or CTEs. + +The reason is that field filters generate SQL based on the mapped field; Metabase doesn't parse the SQL, so it can't tell what an alias refers to. You have three options for workarounds, depending on the complexity of your query. + +1. Use full table names. +2. Replace CTEs with subqueries. +3. Create a view in your database, and use the view as the basis of your query. + +### Field Filters must be connected to fields included in the query + +Your main query should be aware of all the tables that your Field Filter variable is pointing to, otherwise you'll get a SQL syntax error. For example, let's say that your main query includes a field filter like this: + +```sql +{% raw %} +SELECT + * +FROM + ORDERS +WHERE + {{ product_category }} +{% endraw %} +``` + +Let's say the `{% raw %}{{ product_category }}{% endraw %}` variable refers to another question that uses the `Products` table. For the field filter to work, you'll need to include a join to `Products` in your main query. + +```sql +{% raw %} +SELECT + * +FROM + ORDERS + JOIN PRODUCTS ON ORDERS.product_id = PRODUCTS.id +WHERE + {{ product_category }} +{% endraw %} +``` + +## Customizing dropdown lists and search box values + +With Text and Field filter variables, you can tell Metabase what values people can choose from when using a filter with a dropdown list or search box. + +1. In the native editor, add a {% raw %}{{variable}}{% endraw %} in double braces. +2. If the sidebar doesn't open, you can click on the **{x}** icon on the right to open the **Variables** sidebar. +3. In the **Settings** tab, set the **Variable type** to either "Text" or "Field Filter". +4. In the sidebar, go to **How should users filter on this variable?** Pick either **Dropdown list** or **Search box**. +5. Next to the option you chose, click **Edit**. +6. Metabase will pop up a modal where you can select **Where the values should come from**. + +You can choose: + +- **From connected fields** If you selected the Field filter variable type, you'll also have the option to use the connected field. +- **From another model or question**. If you select this option, you'll need to pick a model or question, then a field from that model or question that Metabase will use to supply the values for that dropdown or search box. For example, if you want the dropdown to list the different plans an account could be on, you could select an "Account" model you created, and select the field "Plan" to power that dropdown. The dropdown would then list all of the distinct plan options that appear in the "Plan" column in the Accounts model. +- **Custom list**. Enter each item on a line. You can enter any string values you like. + +You can also [change a dashboard filter's selectable values](../../dashboards/filters#change-a-filters-selectable-values). + +## Setting a default value in the filter widget + +In the variables sidebar, you can set a default value for your variable. This value will be inserted into the corresponding filter widget by default (even if the filter widget is empty). You'll need to insert a new value into the filter widget to override the default. + +## Setting complex default values in the query + +You can also define default values directly in your query by enclosing comment syntax inside the end brackets of an optional parameter. + +```sql +WHERE column = [[ {% raw %}{{ your_parameter }}{% endraw %} --]] your_default_value +``` + +The comment will "activate" whenever you pass a value to `your_parameter`. + +This is useful when defining complex default values (for example, if your default value is a function like `CURRENT_DATE`). Here's a PostgreSQL example that sets the default value of a Date filter to the current date using `CURRENT_DATE`: + +```sql +{% raw %} +SELECT + * +FROM + orders +WHERE + DATE(created_at) = [[ {{dateOfCreation}} --]] CURRENT_DATE +{% endraw %} +``` + +If you pass a value to the variable, the `WHERE` clause runs, including the comment syntax that comments out the default `CURRENT_DATE` function. + +Note that the hash (`--`) used to comment the text might need to be replaced by the comment syntax specific to the database you're using. + +## Requiring a value for a filter widget + +In the **Variable** settings sidebar, you can toggle the **Always require a value** option. If you turn this on: + +- You must enter a default value. +- The default value will override any optional syntax in your code (like an optional `WHERE` clause). If no value is passed to the filter, Metabase will run the query using the default value. Click on the **Eye** icon in the editor to preview the SQL Metabase will run. + +## Making variables optional + +You can make a clause optional in a query. For example, you can create an optional `WHERE` clause that contains a SQL variable, so that if no value is supplied to the variable (either in the filter or via the URL), the query will still run as if there were no `WHERE` clause. + +To make a variable optional in your native query, put `[[ .. ]]` brackets around the entire clause containing the `{% raw %}{{variable}}{% endraw %}`. If someone inputs a value in the filter widget for the `variable`, Metabase will place the clause in the template; otherwise Metabase will ignore the clause and run the query as though the clause didn't exist. + +In this example, if no value is given to `cat`, then the query will just select all the rows from the `products` table. But if `cat` does have a value, like "Widget", then the query will only grab the products with a category type of Widget: + +```sql +{% raw %} +SELECT + count(*) +FROM + products +[[WHERE category = {{cat}}]] +{% endraw %} +``` + +### Your SQL must also be able to run without the optional clause in `[[ ]]` + +You need to make sure that your SQL is still valid when no value is passed to the variable in the bracketed clause. + +For example, excluding the `WHERE` keyword from the bracketed clause will cause an error if there's no value given for `cat`: + +```sql +-- this will cause an error: +{% raw %} +SELECT + count(*) +FROM + products +WHERE + [[category = {{cat}}]] +{% endraw %} +``` + +That's because when no value is given for `cat`, Metabase will try to execute SQL as if the clause in `[[ ]]` didn't exist: + +```sql +SELECT + count(*) +FROM + products +WHERE +``` + +which is not a valid SQL query. + +Instead, put the entire `WHERE` clause in `[[ ]]`: + +```sql +{% raw %} +SELECT + count(*) +FROM + products +[[WHERE + category = {{cat}}]] +{% endraw %} +``` + +When there's no value given for `cat`, Metabase will just execute: + +```sql +{% raw %} +SELECT + count(*) +FROM + products +{% endraw %} +``` + +which is still a valid query. + +### You need at least one `WHERE` when using multiple optional clauses + +To use multiple optional clauses, you must include at least one regular `WHERE` clause followed by optional clauses, each starting with `AND`: + +```sql +{% raw %} +SELECT + count(*) +FROM + products +WHERE + TRUE + [[AND id = {{id}}] + [[AND {{category}}]] +{% endraw %} +``` + +That last clause uses a Field filter (note the lack of a column in the `AND` clause). When using a field filter, you must exclude the column in the query; you need to map the variable in the side panel. + +### Optional variables in MongoDB + +If you're using MongoDB, you can make an clause optional like so: + +``` +{% raw %} +[ + [[{ + $match: {category: {{cat}}} + },]] + { + $count: "Total" + } +] +{% endraw %} +``` + +Or with multiple optional filters: + +``` +{% raw %} +[ + [[{ $match: {{cat}} },]] + [[{ $match: { price: { "$gt": {{minprice}} } } },]] + { + $count: "Total" + } +] +{% endraw %} +``` + +## Connecting a SQL question to a dashboard filter + +In order for a saved SQL/native question to be usable with a dashboard filter, the question must contain at least one variable. + +The kind of dashboard filter that can be used with the SQL question depends on the field. For example, if you have a field filter called `{% raw %}{{var}}{% endraw %}` and you map it to a State field, you can map a Location dashboard filter to your SQL question. In this example, you'd create a new dashboard (or go to an existing dashboard), click the **Pencil icon** to enter **Dashboard edit mode**, add the SQL question that contains your State Field Filter variable, add a new dashboard filter (or edit an existing Location filter), then click the dropdown on the SQL question card to see the State Field Filter. + +If you add a **Date** variable to the question, then it's only possible to use the dashboard filter option **Single Date**. So if you are trying to use one of the other Time options on the dashboard, you'll need to change the variable to a [Field Filter](#the-field-filter-variable-type) variable and map it to a date column. + +![Field filter](../images/state-field-filter.png) + +More on [Dashboard filters][dashboard-filters]. + +## Further reading + +- [Create filter widgets for charts using SQL variables][sql-variables]. +- [Field Filters: create smart filter widgets for SQL questions][field-filter]. +- [Troubleshooting SQL][troubleshooting-sql]. +- [Troubleshooting filters][troubleshooting-filters]. +- [Dashboard filters][dashboard-filters]. + +[sql-editor]: ./writing-sql +[dashboard-filters]: ../../dashboards/filters +[field-filter]: /learn/metabase-basics/querying-and-dashboards/sql-in-metabase/field-filters +[sql-variables]: /learn/metabase-basics/querying-and-dashboards/sql-in-metabase/sql-variables +[troubleshooting-filters]: ../../troubleshooting-guide/filters +[troubleshooting-sql]: ../../troubleshooting-guide/sql +[basic-input]: /learn/grow-your-data-skills/learn-sql/working-with-sql/sql-variables diff --git a/_docs/doc-update-detection/questions/native-editor/writing-sql.md b/_docs/doc-update-detection/questions/native-editor/writing-sql.md new file mode 100644 index 000000000..ec2cd0c04 --- /dev/null +++ b/_docs/doc-update-detection/questions/native-editor/writing-sql.md @@ -0,0 +1,119 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'SQL editor' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/native-editor/writing-sql.md' +redirect-from: + - /docs/latest/users-guide/writing-sql +--- + +# SQL editor + +If you ever need to ask questions that can't be expressed using the query builder, you can use [SQL][sql-gloss] instead. + +## What's SQL? + +SQL (pronounced "sequel", or sometimes as S.Q.L. — people argue about this) stands for Structured Query Language, and is a widely used standard for getting data from databases. We won't try to teach you all about SQL right now, but to learn more about it, check out [Working with SQL][learn-sql]. + +Even if you don't understand SQL or how to use it, it's worthwhile to get an idea of how it works inside Metabase, because sometimes other people will share SQL-based questions that might be useful to you. + +## Starting a new SQL query + +Select **+ New** in the main nav bar. If you have the [permissions](../../permissions/data) to use the SQL editor, you'll see an option to start a new **SQL query** next to a little console icon. + +After clicking **SQL query**, you'll see an editor where you can write and run queries in SQL (or your database's native querying language). + +![SQL editor](../images/SQLInterface.png) + +To try it out, make sure you've selected the [Sample Database][sample-database-gloss], then paste in this short SQL query: + +```sql +SELECT + sum(subtotal), + created_at +FROM orders +GROUP BY created_at; +``` + +Don't worry if you don't understand this just yet. Click the blue **Run query** button to execute your query. + +You'll notice that the table that comes back is the same as if you had used the [query builder](../query-builder/editor) to ask for the sum of `Subtotal` in the `Orders` table, grouped by the `Created At` date. + +### Running query selections + +You can run your SQL query by pressing **ctrl + enter** on Windows and Linux, or **⌘ + return** on a Mac. You can also run only part of a query by highlighting the part you'd like to run before clicking the run button or using the run shortcut key. + +Questions asked using SQL can be saved, downloaded, converted to models, and added to dashboards just like questions asked using the query builder. + +You can also [refer to models and saved questions][ref-models] in your SQL queries. + +## Use `??` instead of `?` operator + +If you're using the `?` JSON operator in PostgreSQL, use the equivalent `??` operator instead. + +This is due to limitations of JDBC that interprets a single question mark `?` as a parameter placeholder. + +## Format SQL queries + +You can format your SQL queries by clicking on the "document" icon in the editor sidebar. + +| Before format | After format | +| --------------------------------------------------------------------- | ------------------------------------------------------------------- | +| ![a SQL query before formatting](../images/before-sql-formatting.png) | ![a SQL query after formatting](../images/after-sql-formatting.png) | + +The formatter works only for SQL queries, and isn’t available for SQLite and SQL Server. + +## Using SQL filters + +If you or someone else wrote a SQL query that includes [variables][variable-gloss], that question might have filter widgets at the top of the screen above the editor. Filter widgets let you modify the SQL query before it's run, changing the results you might get. + +![SQL filter](../images/SQL-filter-widget.png) + +Writing SQL queries that use variables or parameters can be very powerful, but it's also a bit more advanced, so that topic has its own page if you'd like to [learn more](./sql-parameters). + +## Snippets + +You can use [Snippets](snippets) to save, reuse, and share SQL code across multiple questions that are composed using the SQL editor. + +## How Metabase executes SQL queries + +When you run a query from the SQL editor, Metabase sends the query to your database exactly as it is written. Any results or errors displayed in Metabase are the same as the results or errors that you would get if you ran the query directly against your database. If the SQL syntax of your query doesn’t match the SQL dialect used by your database, your database won’t be able to run the query. + +## Question version history + +For questions, [dashboards](../../dashboards/start), and [models](../../data-modeling/models), Metabase keeps a version history for the previous fifteen versions of that item. + +See [History](../../exploration-and-organization/history). + +## Explore SQL question results using the Query Builder + +On saved SQL questions without [parameters](./sql-parameters), you'll get the **Explore results** button. It will create a new Query Builder question that uses the SQL question results as a data source. + +![Explore results button](../images/explore-results.png) + +## Drill-though in SQL questions + +Visualizations created with SQL have limited [drill-through][drill-through] capabilities: + +- You can filter results of SQL queries by clicking on data points, zoom in on time series or maps, and use some [column header actions](../visualizations/table#column-heading-options-for-filtering-and-summarizing). +- You won't be able to drill down to unaggregated records, change time granularity, or break out by categories or locations. + +## Caching results + +See [Caching question policies](../../configuring-metabase/caching#question-caching-policy). + +## Learn more + +- [Best practices for writing SQL queries](/learn/grow-your-data-skills/learn-sql/working-with-sql/sql-best-practices) +- [SQL troubleshooting guide][troubleshooting-sql]. + +[learn-sql]: /learn/grow-your-data-skills/learn-sql/working-with-sql +[ref-models]: ./referencing-saved-questions-in-queries +[sample-database-gloss]: /glossary/sample_database +[sql-gloss]: /glossary/sql +[troubleshooting-sql]: ../../troubleshooting-guide/sql +[variable-gloss]: /glossary/variable +[drill-through]: /learn/metabase-basics/querying-and-dashboards/questions/drill-through diff --git a/_docs/doc-update-detection/questions/query-builder/editor.md b/_docs/doc-update-detection/questions/query-builder/editor.md new file mode 100644 index 000000000..99483681b --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/editor.md @@ -0,0 +1,141 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'The query builder' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/editor.md' +redirect_from: + - /docs/doc-update-detection/questions/query-builder/introduction +--- + +# The query builder + +Metabase includes a graphical query builder that lets you build interactive charts. + +With the query builder you can: + +- [Pick data](#picking-data) +- [Join tables](#joining-data) +- [Create custom columns](#custom-columns) +- [Filter data](./filters) +- [Summarize and group data](./summarizing-and-grouping) +- [Limit results](#setting-a-row-limit) + +When viewing a chart, you can also click through questions to explore the data in greater detail. + +![Drill-through menu](../images/drill-through-menu.png) + +The drill-through menu will present different options depending on what you click on. You can then optionally save any exploration as a new question. Full drill-through menu is only available for questions built using the query builder. Questions built with the SQL/native editor will have only have [limited drill-through actions](../native-editor/writing-sql#drill-though-in-sql-questions). For more on how drill-through works, check out [Creating interactive charts](/learn/metabase-basics/querying-and-dashboards/questions/drill-through). + +## Creating a new question with the query builder + +From the **+ New** dropdown, select **Question**, then pick your starting data: + +You can start a question from: + +- **A model**. A [model](../../data-modeling/models) is a special kind of saved question meant to be used as a good starting point for questions. Sometimes these are called derived tables, as they usually pull together data from multiple raw tables. +- **A metric**. [Metrics](../../data-modeling/metrics) are pre-defined calculations. If you pick a metric as a starting point for a question, Metabase will create a question with the same data source as the selected metric, and apply the metric. You'll be able to add more joins, filter, and summaries. +- **Tables**. You'll need to specify the database and the table in that database as the starting point for your question. +- A **saved question**. You can use the results of any question as the starting point for a new question. + +Note that there are some kinds of saved questions that can't be used as source data: + +- Druid questions +- Mongo questions +- Questions that use `Cumulative Sum` or `Cumulative Count` aggregations +- Questions that have columns that are named the same or similar thing, like `Count` and `Count 2` + +## The editor + +Once you select your data, Metabase will take you to the query builder's editor. Say you selected **Tables** > **Sample database** > **Orders**, then you'll see something like this: + +![Metabase query builder](../images/notebook-editor.png) + +This is the query builder's editor. It has three default steps. + +- [Picking data](#picking-data) +- [Filtering](./filters) +- [Summarizing and grouping by](./summarizing-and-grouping) + +You can also add steps for [joining data](./join), [custom columns](#custom-columns), and [sorting results](#sorting-results), and [limiting results](#setting-a-row-limit). + +To the right of each completed step is a **Preview** button (looks like a Play button - a triangle pointing to the right) that shows you the first 10 rows of the results of your question up to that step. + +![Previewing results](../images/preview-table.png) + +## Picking data + +The data section is where you select the data you want to work with. Here you'll pick a [model](../../data-modeling/models), a [metric](../../data-modeling/metrics), a table from a database, or a saved question. + +![data picker](../images/data-picker.png) + +You can see the data source in a new browser tab by Cmd/Ctrl+Clicking on the data source's name in the query builder. + +To choose which columns to include in your query, click on the arrow next to the data source. If you uncheck a column, you'll still be able to use the column while building a query (for example, in filters) but Metabase won't display the column in results. + +You can [hide columns](../visualizations/table#rearranging-adding-and-removing-columns) from the table views. + +> **Hiding columns should _not_ be used to secure sensitive information**. Hiding columns in table visualization settings only affects the visibility of the columns _in the visualization_, not in the query results. Even people with only "view data" permissions to the question will be able to change the visualization settings and unhide columns. To exclude a column from the results of a specific query, uncheck the column in the "Data" block of the query builder. + +## Joining data + +You can also select multiple tables from the same database by [joining them](./join). + +## Filtering data + +See [filters](./filters). + +## Visualizing your data + +Check out [visualizing results](../visualizations/visualizing-results). + +## Column heading drill-through + +When viewing a [table](../visualizations/table), clicking on the heading of a column gives you different options, depending on the columns data type. See [table](../visualizations/table#column-heading-options-for-filtering-and-summarizing). + +## Custom expressions + +Custom expressions allow you to use spreadsheet-like functions and simple arithmetic within or between aggregation functions. + +![Custom expression](../images/aggregation-expression.png) + +For example, you could do `Average(sqrt[FieldX]) + Sum([FieldY])` or `Max(floor([FieldX] - [FieldY]))`, where `FieldX` and `FieldY` are fields in the currently selected table. [Learn more about writing expressions](./expressions). + +## Custom columns + +![Custom column](../images/custom-column.png) + +Custom columns are helpful when you need to create a new column based on a calculation, such as subtracting the value of one column from another, or extracting a portion of an existing text column. Custom columns that you add aren't permanently added to your table; the columns will only be present in the given question. + +You can use the following math operators in your formulas: `+`, `–`, `*` (multiplication), and `/` (division), along with a whole host of spreadsheet-like functions. You can also use parentheses to clarify the order of operations. See [list of expressions](../query-builder/expressions-list). + +## Sorting results + +![Sorting](../images/sort-step.png) + +The sorting step lets you pick one or more columns to sort your results by. For each column you pick, you can also choose whether to sort ascending or descending; just click the arrow to change from ascending (up arrow) to descending (down arrow). + +## Setting a row limit + +The row limit step lets you cap how many rows you want from the previous results. When used in conjunction with sorting, limits can let you do things like create a top-10 list, by first sorting by one of the columns in your result, then adding a row limit of 10. Unlike other steps, the row limit step can only be added at the end of your question. If you do want to add more steps to limited results, you can always save the limited results as a question, then start a _new_ question based on those results. + +## Viewing the native query that powers your question + +![View the SQL](../images/view-the-sql.png) + +Under the hood, all Metabase questions are converted to SQL or another language native to your query engine. To view the native query that Metabase will run when you click **Visualize**, click the **View SQL** or **View query** button in the top right of the query builder. Metabase will preview the native query in a sidebar: + +![SQL sidebar](../images/sql-sidebar.png) + +To view the native query, you must have [query builder and native permissions](../../permissions/data). + +### Convert a query-builder question to SQL + +You can also convert the question to a [native editor question](../native-editor/writing-sql). From the query builder screen: + +1. Click the **Console** icon in the upper right of the query builder. +2. Click **Convert the question to SQL** option in the bottom right below the SQL code. + +Conversion is a one-way street: you can't convert a SQL question back into a query builder question. diff --git a/_docs/doc-update-detection/questions/query-builder/expressions-list.md b/_docs/doc-update-detection/questions/query-builder/expressions-list.md new file mode 100644 index 000000000..5a6a98c79 --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions-list.md @@ -0,0 +1,991 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'List of expressions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions-list.md' +redirect_from: + - /docs/doc-update-detection/users-guide/expressions-list +--- + +# List of expressions + +For an introduction to expressions, check out the [overview of custom expressions][expressions]. + +- [Aggregations](#aggregations) + + - [Average](#average) + - [Count](#count) + - [CountIf](./expressions/countif) + - [Distinct](#distinct) + - [DistinctIf](#distinctif) + - [Max](#max) + - [Median](#median) + - [Min](#min) + - [Percentile](#percentile) + - [Share](#share) + - [StandardDeviation](#standarddeviation) + - [Sum](#sum) + - [SumIf](./expressions/sumif) + - [Variance](#variance) + - [CumulativeSum](./expressions/cumulative) + - [CumulativeCount](./expressions/cumulative) + +- Functions + + - [Logical functions](#logical-functions) + + - [between](#between) + - [case](./expressions/case) + - [coalesce](./expressions/coalesce) + - [if](./expressions/case) + - [isNull](./expressions/isnull) + - [notNull](#notnull) + + - [Math functions](#math-functions) + + - [abs](#abs) + - [ceil](#ceil) + - [exp](#exp) + - [floor](#floor) + - [log](#log) + - [power](#power) + - [round](#round) + - [sqrt](#sqrt) + + - [String functions](#string-functions) + + - [concat](./expressions/concat) + - [contains](#contains) + - [date](#date) + - [doesNotContain](#doesnotcontain) + - [domain](#domain) + - [endsWith](#endswith) + - [host](#host) + - [in](#in) + - [isEmpty](./expressions/isempty) + - [integer](#integer) + - [lTrim](#ltrim) + - [length](#length) + - [lower](#lower) + - [notEmpty](#notempty) + - [path](#path) + - [regexextract](./expressions/regexextract) + - [replace](#replace) + - [splitPart](#splitpart) + - [rTrim](#rtrim) + - [startsWith](#startswith) + - [subdomain](#subdomain) + - [substring](./expressions/substring) + - [text](#text) + - [trim](#trim) + - [upper](#upper) + + - [Date functions](#date-functions) + + - [convertTimezone](./expressions/converttimezone) + - [datetimeAdd](./expressions/datetimeadd) + - [datetimeDiff](./expressions/datetimediff) + - [datetimeSubtract](./expressions/datetimesubtract) + - [day](#day) + - [dayName](#dayname) + - [hour](#hour) + - [interval](#interval) + - [minute](#minute) + - [month](#month) + - [monthName](#monthname) + - [now](./expressions/now) + - [quarter](#quarter) + - [quarterName](#quartername) + - [relativeDateTime](#relativedatetime) + - [second](#second) + - [week](#week) + - [weekday](#weekday) + - [year](#year) + + - [Window functions](#window-functions) + + - [Offset](./expressions/offset) + - [CumulativeCount](./expressions/cumulative) + - [CumulativeSum](./expressions/cumulative) + +- [Limitations](#limitations) + - [Database limitations](#database-limitations) + +## Aggregations + +Aggregation expressions take into account all values in a field. They can only be used in the **Summarize** section of the query builder. + +### Average + +Returns the average of the values in the column. + +Syntax: `Average(column)` + +Example: `Average([Quantity])` would return the mean for the `Quantity` field. + +### Count + +Returns the count of rows (also known as records) in the selected data. + +Syntax: `Count` + +Example: `Count` If a table or result returns 10 rows, `Count` will return `10`. + +### [CountIf](./expressions/countif) + +Only counts rows where the condition is true. + +Syntax: `CountIf(condition)` + +Example: `CountIf([Subtotal] > 100)` would return the number of rows where the subtotal were greater than 100. + +### Distinct + +The number of distinct values in this column. + +Syntax: `Distinct(column)` + +Example: `Distinct([Last Name])`. Returns the count of unique last names in the column. Duplicates (of the last name "Smith" for example) are not counted. + +### DistinctIf + +Returns the count of distinct values in a column where the condition is true. + +Syntax: `DistinctIf(column, condition)` + +Example: `DistinctIf([ID], [Category] = "Gizmo")` would return the count of unique IDs where the `Category` column is "Gizmo". + +### Max + +Returns the largest value found in the column. + +Syntax: `Max(column)` + +Example: `Max([Age])` would return the oldest age found across all values in the `Age` column. + +Related: [Min](#min), [Average](#average), [Median](#median). + +### Median + +Returns the median value of the specified column. + +Syntax: `Median(column)` + +Example: `Median([Age])` would find the midpoint age where half of the ages are older, and half of the ages are younger. + +Databases that don't support `median`: Druid, MariaDB, MongoDB, MySQL, SQLite, Vertica, and SQL Server. Presto only provides approximate results. + +Related: [Min](#min), [Max](#max), [Average](#average). + +### Min + +Returns the smallest value found in the column. + +Syntax: `Min(column)` + +Example: `Min([Salary])` would find the lowest salary among all salaries in the `Salary` column. + +Related: [Max](#max), [Median](#median), [Average](#average). + +### Percentile + +Returns the value of the column at the percentile value. + +Syntax: `Percentile(column, percentile-value)` + +Example: `Percentile([Score], 0.9)` would return the value at the 90th percentile for all values in that column. + +Databases that don't support `percentile`: Druid, H2, MariaDB, MySQL, MongoDB, SQL Server, SQLite, Vertica. Presto only provides approximate results. + +### Share + +Returns the percent of rows in the data that match the condition, as a decimal. + +Syntax: `Share(condition)` + +Example: `Share([Color] = "Blue")` would return the number of rows with the `Color` field set to `Blue`, divided by the total number of rows. + +### StandardDeviation + +Calculates the standard deviation of the column, which is a measure of the variation in a set of values. Low standard deviation indicates values cluster around the mean, whereas a high standard deviation means the values are spread out over a wide range. + +Syntax: `StandardDeviation(column)` + +Example: `StandardDeviation([Population])` would return the SD for the values in the `Population` column. + +Databases that don't support `StandardDeviation`: Druid, SQLite. + +### Sum + +Adds up all the values of the column. + +Syntax: `Sum(column)` + +Example: `Sum([Subtotal])` would add up all the values in the `Subtotal` column. + +### [SumIf](./expressions/sumif) + +Sums up the specified column only for rows where the condition is true. + +Syntax: `SumIf(column, condition)` + +Example:`SumIf([Subtotal], [Order Status] = "Valid")` would add up all the subtotals for orders with a status of "Valid". + +### Variance + +Returns the numeric variance for a given column. + +Syntax: `Variance(column)` + +Example: `Variance([Temperature])` will return a measure of the dispersion from the mean temperature for all temps in that column. + +Related: [StandardDeviation](#standarddeviation), [Average](#average). + +Databases that don't support `Variance`: Druid, SQLite. + +## Functions + +Function expressions apply to each individual value. They can be used to alter or filter values in a column, or create new, custom columns. + +## Logical functions + +Logical functions determine if a condition is satisfied or determine what value to return based on a condition. + +### between + +Returns true if the value of a date or number column falls within a specified range. Otherwise returns false. + +Syntax: `between(column, start, end)` + +Example: If you filtered with the expression `between([Created At], "2019-01-01", "2020-12-31")`, Metabase would return rows that returned true for that expression, in this case where the `Created At` date fell _within_ the range of January 1, 2019 and December 31, 2020, including the start (`2019-01-01`) and end (`2020-12-31`) dates. + +Related: [interval](#interval). + +### [case](./expressions/case) + +`case` (alias `if`) tests an expression against a list of cases and returns the corresponding value of the first matching case, with an optional default value if nothing else is met. + +Syntax: `case(condition, output, …)` + +Example: `case([Weight] > 200, "Large", [Weight] > 150, "Medium", "Small")` If a `Weight` is 250, the expression would return "Large". In this case, the default value is "Small", so any `Weight` 150 or less would return "Small". + +### [coalesce](./expressions/coalesce) + +Looks at the values in each argument in order and returns the first non-null value for each row. + +Syntax: `coalesce(value1, value2, …)` + +Example: `coalesce([Comments], [Notes], "No comments")`. If both the `Comments` and `Notes` columns are null for that row, the expression will return the string "No comments". + +### [if](./expressions/case) + +`if` is an alias for [case](./expressions/case). Tests an expression against a list of conditionals and returns the corresponding value of the first matching case, with an optional default value if nothing else is met. + +Syntax: `if(condition, output, ...)` + +Example: `if([Weight] > 200, "Large", [Weight] > 150, "Medium", "Small")` If a `Weight` is 250, the expression would return "Large". In this case, the default value is "Small", so any `Weight` 150 or less would return "Small". + +### [isNull](./expressions/isnull) + +Returns true if the column is null. + +Syntax: `isNull(column)` + +Example: `isNull([Tax])` would return true if no value were present in the column for that row. + +Related: [notNull](#notnull), [isEmpty](#isempty) + +### notNull + +Returns true if the column contains a value. + +Syntax: `notNull(column)` + +Example: `notNull([Tax])` would return true if there is a value present in the column for that row. + +Related: [isNull](#isnull), [notEmpty](#notempty) + +## Math functions + +Math functions implement common mathematical operations. + +### abs + +Returns the absolute (positive) value of the specified column. + +Syntax: `abs(column)` + +Example: `abs([Debt])`. If `Debt` were -100, `abs(-100)` would return `100`. + +### ceil + +Rounds a decimal up (ceil as in ceiling). + +Syntax: `ceil(column)` + +Example: `ceil([Price])`. `ceil(2.99)` would return 3. + +Related: [floor](#floor), [round](#round). + +### exp + +Returns [Euler's number](), e, raised to the power of the supplied number. (Euler sounds like "Oy-ler"). + +Syntax: `exp(column)` + +Example: `exp([Interest Months])` + +Related: [power](#power). + +### floor + +Rounds a decimal number down. + +Syntax: `floor(column)` + +Example: `floor([Price])`. If the `Price` were 1.99, the expression would return 1. + +Related: [ceil](#ceil), [round](#round). + +### log + +Returns the base 10 log of the number. + +Syntax: `log(column)` + +Example: `log([Value])`. + +### power + +Raises a number to the power of the exponent value. + +Syntax: `power(column, exponent)` + +Example: `power([Length], 2)`. If the length were `3`, the expression would return `9` (3 to the second power is 3\*3). + +Databases that don't support `power`: SQLite. + +Related: [exp](#exp). + +### round + +Rounds a decimal number either up or down to the nearest integer value. + +Syntax: `round(column)` + +Example: `round([Temperature])`. If the temp were `13.5` degrees centigrade, the expression would return `14`. + +Example: `round([Temperature] * 10) / 10`. If the temp were `100.75`, the expression would return `100.8`. + +### sqrt + +Returns the square root of a value. + +Syntax: `sqrt(column)` + +Example: `sqrt([Hypotenuse])`. + +Databases that don't support `sqrt`: SQLite. + +Related: [Power](#power). + +## String functions + +String functions manipulate or validate string data. + +### [concat](./expressions/concat) + +Combine two or more strings together. + +Syntax: `concat(value1, value2, …)` + +Example: `concat([Last Name], ", ", [First Name])` would produce a string of the format "Last Name, First Name", like "Palazzo, Enrico". + +### contains + +Checks to see if `string1` contains `string2` within it. + +Performs case-sensitive match by default. +You can pass an optional parameter `"case-insensitive"` to perform a case-insensitive match. + +Syntax: `contains(string1, string2)` for case-sensitive match. + +`contains(string1, string2, "case-insensitive")` for case-insensitive match. + +Example: `contains([Status], "Class")`. + +If `Status` were "Classified", the expression would return `true`. If the `Status` were "**c**lassified", the expression would return `false`, because the case does not match. + +Related: [doesNotContain](#doesnotcontain), [regexextract](#regexextract). + +### date + +> Only available for PostgreSQL. + +Converts an ISO 8601 date string to a date. The string _must_ be in a valid ISO 8601 format. + +Syntax: `date(value)` + +Example: `date("2025-03-20")` would return a date value so that you can use all the date features in the query builder: group by month, filter by previous 30 days, etc. + +ISO 8601 standard format: + +- Year (YYYY): 2025 +- Month (MM): 03 +- Day (DD): 25 +- Time separator (T) +- Hours (HH): 14 +- Minutes (MM): 30 +- Seconds (SS): 45 +- UTC timezone indicator (Z) + +Valid ISO 8601 examples include: + +- Date only: `2025-03-25` +- Date with time: `2025-03-25T14:30:45` +- Date with time and timezone offset: `2025-03-25T14:30:45+01:00` + +### doesNotContain + +Checks to see if `string1` contains `string2` within it. + +Performs case-sensitive match by default. +You can pass an optional parameter `"case-insensitive"` to perform a case-insensitive match. + +Syntax: `doesNotContain(string1, string2)` for case-sensitive match. + +`doesNotContain(string1, string2, "case-insensitive")` for case-insensitive match. + +Example: `doesNotContain([Status], "Class")`. If `Status` were "Classified", the expression would return `false`. + +Related: [contains](#contains), [regexextract](#regexextract). + +### domain + +Extracts the domain name from a URL or email. + +Syntax: `domain(urlOrEmail)` + +Example: `domain([Page URL])`. If the `[Page URL]` column had a value of `https://www.metabase.com`, `domain([Page URL])` would return `metabase`. `domain([Email])` would extract `metabase` from `hello@metabase.com`. + +Related: [host](#host), [path](#path), [subdomain](#subdomain). + +### endsWith + +Returns true if the end of the text matches the comparison text. + +Performs case-sensitive match by default. +You can pass an optional parameter `"case-insensitive"` to perform a case-insensitive match. + +Syntax: `endsWith(text, comparison)` for case-sensitive match. + +`endsWith(text, comparison, "case-insensitive")` for case-insensitive match. + +Example: `endsWith([Appetite], "hungry")` + +Related: [startsWith](#startswith), [contains](#contains), [doesNotContain](#doesnotcontain). + +### host + +Extracts the host, which is the domain and the TLD, from a URL or email. + +Syntax: `host(urlOrEmail)` + +Example: `host([Page URL])`. If the `[Page URL]` column had a value of `https://www.metabase.com`, `host([Page URL])` would return `metabase.com`. `host([Email])` would extract `metabase.com` from `hello@metabase.com`. + +Related: [domain](#domain), [path](#path), [subdomain](#subdomain). + +### [in](./expressions/in) + +Returns true if `value1` equals `value2` (or `value3`, etc., if specified). + +``` +in(value1, value2, ...) +``` + +`value1` is the column or value to check. + +`value2, ...` is the list of columns or values to check. + +Related: [contains](#contains), [startsWith](#startswith), [endsWith](#endswith). + +### [isEmpty](./expressions/isempty) + +Returns true if a _string column_ contains an empty string or is null. Calling this function on a non-string column will cause an error. You can use [isNull](#isnull) for non-string columns. + +Syntax: `isEmpty(column)` + +Example: `isEmpty([Feedback])` would return true if `Feedback` was an empty string (`''`) or did not contain a value. + +Related: [notEmpty](#notempty), [isNull](#isnull) + +### integer + +> Only available for PostgreSQL. + +Converts a string to an integer value. Useful if you want to do some math on numbers, but your data is stored as strings. + +Syntax: `integer(value)` + +Example: `integer("123")` would return `123` as an integer. The string must evaluate to an integer (so `integer("123.45")` would return an error.) + +### lTrim + +Removes leading whitespace from a string of text. + +Syntax: `lTrim(text)` + +Example: `lTrim([Comment])`. If the comment were `" I'd prefer not to"`, `lTrim` would return `"I'd prefer not to"`. + +Related: [trim](#trim) and [rTrim](#rtrim). + +### length + +Returns the number of characters in text. + +Syntax: `length(text)` + +Example: `length([Comment])`. If the `comment` were "wizard", `length` would return 6 ("wizard" has six characters). + +### lower + +Returns the string of text in all lower case. + +Syntax: `lower(text)` + +Example: `lower([Status])`. If the `Status` were "QUIET", the expression would return "quiet". + +Related: [upper](#upper). + +### notEmpty + +Returns true if a _string column_ contains a value that is not the empty string. Calling this function on a non-string column will cause an error. You can use [notNull](#notnull) on non-string columns. + +Syntax: `notEmpty(column)` + +Example: `notEmpty([Feedback])` would return true if `Feedback` contains a value that isn't the empty string (`''`). + +Related: [isEmpty](#isempty), [isNull](#isnull), [notNull](#notnull) + +### path + +Extracts the pathname from a URL. + +Syntax: `path(url)` + +Example: `path([Page URL])`. For example, `path("https://www.example.com/path/to/page.html?key1=value")` would return `/path/to/page.html`. + +Related: [domain](#domain), [host](#host), [subdomain](#subdomain). + +### [regexextract](./expressions/regexextract) + +> ⚠️ `regexextract` is unavailable for MongoDB, SQLite, and SQL Server. For Druid, `regexextract` is only available for the Druid-JDBC driver. + +Extracts matching substrings according to a regular expression. + +Syntax: `regexextract(text, regular_expression)` + +Example: `regexextract([Address], "[0-9]+")` + +Databases that don't support `regexextract`: H2, SQL Server, SQLite. + +Related: [contains](#contains), [doesNotContain](#doesnotcontain), [substring](#substring). + +### replace + +Replaces all occurrences of a search text in the input text with the replacement text. + +Syntax: `replace(text, find, replace)` + +Example: `replace([Title], "Enormous", "Gigantic")` + +### splitPart + +> Only available on PostgreSQL. + +Splits a string on a specified delimiter and returns the nth substring. + +Syntax: `splitPart(text, delimiter, position)` + +`text`: The column or text to return a portion of. + +`delimiter`: The pattern describing where each split should occur. + +`position`: Which substring to return after the split. Index starts at position 1. + +Example: `splitPart([Date string], " ", 1)`. If the value for `Date string` was `"2024-09-18 16:55:15.373733-07"`, `splitPart` would return `"2024-09-18"` because it split the data on space (`" "`, and took the first part (the substring at index 1)). + +Another example: `splitPart("First name, Middle Name, Last name", ", ", 3)` would return `"Last Name"` (because we used the comma and space `", "` as the delimiter to split the string into parts, and took the third substring). + +### rTrim + +Removes trailing whitespace from a string of text. + +Syntax: `rTrim(text)` + +Example: `rTrim([Comment])`. If the comment were "Fear is the mindkiller. ", the expression would return "Fear is the mindkiller." + +Related: [trim](#trim) and [lTrim](#ltrim). + +### startsWith + +Returns true if the beginning of the text matches the comparison text. Performs case-sensitive match by default. +You can pass an optional parameter `"case-insensitive"` to perform a case-insensitive match. + +Syntax: `startsWith(text, comparison)` for case-sensitive match. + +`startsWith(text, comparison, "case-insensitive")` for case-insensitive match. + +Example: `startsWith([Course Name], "Computer Science")` would return true for course names that began with "Computer Science", like "Computer Science 101: An introduction". + +It would return false for "Computer **s**cience 201: Data structures" because the case of "science" does not match the case in the comparison text. + +`startsWith([Course Name], "Computer Science", "case-insensitive")` would return true for both "Computer Science 101: An introduction" and "Computer science 201: Data structures". + +Related: [endsWith](#endswith), [contains](#contains), [doesNotContain](#doesnotcontain). + +### subdomain + +Extracts the subdomain from a URL. Ignores `www` (returns a blank string). + +Syntax: `subdomain(url)` + +Example: `subdomain([Page URL])`. If the `[Page URL]` column had a value of `https://status.metabase.com`, `subdomain([Page URL])` would return `status`. + +Related: [domain](#domain), [host](#host), [path](#path). + +### [substring](./expressions/substring) + +Returns a portion of the supplied text, specified by a starting position and a length. + +Syntax: `substring(text, position, length)` + +Example: `substring([Title], 1, 10)` returns the first 10 letters of a string (the string index starts at position 1). + +Related: [regexextract](#regexextract), [replace](#replace). + +### text + +> Only available for PostgreSQL. + +Converts a number or date to text (a string). Useful for applying text filters or joining with other columns based on text comparisons. + +Syntax: `text(value)` + +Example: `text(Created At])` would take a datetime (`Created At`) and return that datetime converted to a string (like `"2024-03-17 16:55:15.373733-07"`). + +### trim + +Removes leading and trailing whitespace from a string of text. + +Syntax: `trim(text)` + +Example: `trim([Comment])` will remove any whitespace characters on either side of a comment. + +### upper + +Returns the text in all upper case. + +Syntax: `upper(text)` + +Example: `upper([Status])`. If status were "hyper", `upper("hyper")` would return "HYPER". + +Related: [lower](#lower). + +## Date functions + +Date functions manipulate, extract, or create date and time values. + +### [convertTimezone](./expressions/converttimezone) + +Shifts a date or timestamp value into a specified time zone. + +Syntax: `convertTimezone(column, target, source)` + +Example: `convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Eastern")` would return the value `2022-12-28T09:00:00`, displayed as `December 28, 2022, 9:00 AM`. + +See the [database limitations](./expressions/converttimezone#limitations) for `convertTimezone`. + +### [datetimeAdd](./expressions/datetimeadd) + +Adds some unit of time to a date or timestamp value. + +Syntax: `datetimeAdd(column, amount, unit)` + +Example: `datetimeAdd("2021-03-25", 1, "month")` would return the value `2021-04-25`, displayed as `April 25, 2021`. + +`amount` must be an integer, not a fractional number. For example, you cannot add "half a year" (0.5). + +Related: [between](#between), [datetimeSubtract](#datetimesubtract). + +### [datetimeDiff](./expressions/datetimediff) + +Returns the difference between two datetimes in some unit of time. For example, `datetimeDiff(d1, d2, "day")` will return the number of days between `d1` and `d2`. + +Syntax: `datetimeDiff(datetime1, datetime2, unit)` + +Example: `datetimeDiff("2022-02-01", "2022-03-01", "month")` would return `1`. + +See the [database limitations](./expressions/datetimediff#limitations) for `datetimediff`. + +### [datetimeSubtract](./expressions/datetimesubtract) + +Subtracts some unit of time from a date or timestamp value. + +Syntax: `datetimeSubtract(column, amount, unit)` + +Example: `datetimeSubtract("2021-03-25", 1, "month")` would return the value `2021-02-25`, displayed as `February 25, 2021`. + +`amount` must be an integer, not a fractional number. For example, you cannot subtract "half a year" (0.5). + +Related: [between](#between), [datetimeAdd](#datetimeadd). + +### day + +Takes a datetime and returns the day of the month as an integer. + +Syntax: `day([datetime column])` + +Example: `day("2021-03-25T12:52:37")` would return the day as an integer, `25`. + +### dayName + +Returns the localized name of a day of the week, given the day's number (1-7). Respects the [first day of the week setting](../../configuring-metabase/localization#first-day-of-the-week). + +Syntax: `dayName(dayNumber)` + +Example: `dayName(1)` would return `Sunday`, unless you change the [first day of the week setting](../../configuring-metabase/localization#first-day-of-the-week). + +Related: [quarterName](#quartername), [monthName](#monthname). + +### hour + +Takes a datetime and returns the hour as an integer (0-23). + +Syntax: `hour([datetime column])` + +Example: `hour("2021-03-25T12:52:37")` would return `12`. + +### interval + +Checks a date column's values to see if they're within the relative range. + +Syntax: `interval(column, number, text)` + +Example: `interval([Created At], -1, "month")` + +The `number` must be an integer. You cannot use a fractional value. + +Related: [between](#between). + +### minute + +Takes a datetime and returns the minute as an integer (0-59). + +Syntax: `minute([datetime column])` + +Example: `minute("2021-03-25T12:52:37")` would return `52`. + +### month + +Takes a datetime and returns the month number (1-12) as an integer. + +Syntax: `month([datetime column])` + +Example: `month("2021-03-25T12:52:37")` would return the month as an integer, `3`. + +### monthName + +Returns the localized short name for the given month. + +Syntax: `monthName([Birthday Month])` + +Example: `monthName(10)` would return `Oct` for October. + +Related: [dayName](#dayname), [quarterName](#quartername). + +### [now](./expressions/now) + +Returns the current date and time using your Metabase [report timezone](../../configuring-metabase/localization#report-timezone). + +Syntax: `now` + +### quarter + +Takes a datetime and returns the number of the quarter in a year (1-4) as an integer. + +Syntax: `quarter([datetime column])` + +Example: `quarter("2021-03-25T12:52:37")` would return `1` for the first quarter. + +### quarterName + +Given the quarter number (1-4), returns a string like `Q1`. + +Syntax: `quarterName([Fiscal Quarter])` + +Example: `quarterName(3)` would return `Q3`. + +Related: [dayName](#dayname), [monthName](#monthname). + +### relativeDateTime + +Gets a timestamp relative to the current time. + +Syntax: `relativeDateTime(number, text)` + +`number`: Period of interval, where negative values are back in time. The `number` must be an integer. You cannot use a fractional value. + +`text`: Type of interval like `"day"`, `"month"`, `"year"` + +`relativeDateTime` can only be used as part of a conditional expression. + +Example: `[Orders → Created At] < relativeDateTime(-30, "day")` will filter for orders created over 30 days ago from current date. + +Related: [datetimeAdd](#datetimeadd), [datetimeSubtract](#datetimesubtract). + +### second + +Takes a datetime and returns the number of seconds in the minute (0-59) as an integer. + +Syntax: `second([datetime column])` + +Example: `second("2021-03-25T12:52:37")` would return the integer `37`. + +### timeSpan + +Gets a time interval of specified length. + +Syntax: `timeSpan(number, text)` + +`number`: Period of interval, where negative values are back in time. The `number` must be an integer. You cannot use a fractional value. + +`text`: Type of interval like `"day"`, `"month"`, `"year"` + +Example: `[Orders → Created At] + timeSpan(7, "day")` will return the date 7 days after the `Created At` date. + +### [week](./expressions/week) + +Takes a datetime and returns the week as an integer. + +Syntax: `week(column, mode)` + +Example: `week("2021-03-25T12:52:37")` would return the week as an integer, `12`. + +- column: the name of the column of the date or datetime value. +- mode: Optional. + - ISO: (default) Week 1 starts on the Monday before the first Thursday of January. + - US: Week 1 starts on Jan 1. All other weeks start on Sunday. + - Instance: Week 1 starts on Jan 1. All other weeks start on the day defined in your Metabase localization settings. + +Note that summarizing by week of year in the query builder uses a different mode of determining the first week, see [Week of year](./expressions/week) for more information. + +### weekday + +Takes a datetime and returns an integer (1-7) with the number of the day of the week. + +Syntax: `weekday(column)` + +- column: The datetime column. + +Example: + +``` +case( + weekday([Created At]) = 1, "Sunday", + weekday([Created At]) = 2, "Monday", + weekday([Created At]) = 3, "Tuesday", + weekday([Created At]) = 4, "Wednesday", + weekday([Created At]) = 5, "Thursday", + weekday([Created At]) = 6, "Friday", + weekday([Created At]) = 7, "Saturday") +``` + +### year + +Takes a datetime and returns the year as an integer. + +Syntax: `year([datetime column])` + +Example: `year("2021-03-25T12:52:37")` would return the year 2021 as an integer, `2,021`. + +## Window functions + +Window functions can only be used in the **Summarize** section. They cannot be used to create a custom column or a custom filter. + +### CumulativeCount + +For more info, check out our page on [cumulative functions](./expressions/cumulative). + +The additive total of rows across a breakout. + +Syntax: `CumulativeCount` + +### CumulativeSum + +For more info, check out our page on [cumulative functions](./expressions/cumulative). + +The rolling sum of a column across a breakout. + +Syntax: `CumulativeSum(column)` + +Example: `CumulativeSum([Subtotal])` + +Related: [Sum](#sum) and [SumIf](#sumif). + +### Offset + +> ⚠️ The `Offset` function is currently unavailable for MySQL/MariaDB, MongoDB, and Druid. + +For more info, check out our page on [Offset](./expressions/offset). + +Returns the value of an expression in a different row. `Offset` can only be used in the query builder's Summarize step (you cannot use `Offset` to create a custom column). + +Syntax: `Offset(expression, rowOffset)` + +The `expression` is the value to get from a different row. + +The `rowOffset` is the number relative to the current row. For example, `-1` for the previous row, or `1` for the next row. + +Example: `Offset(Sum([Total]), -1)` would get the `Sum([Total])` value from the previous row. + +## Limitations + +- [Aggregation expressions](#aggregations) can only be used in the **Summarize** section of the query builder. + +## Database limitations + +Limitations are noted for each aggregation and function above, and here there are in summary: + +**H2** (including Metabase Sample Database): `Median`, `Percentile`, `convertTimezone` and `regexextract`. + +**Athena**: `convertTimezone`. + +**Databricks**: `convertTimezone`. + +**Druid**: `Median`, `Percentile`, `StandardDeviation`, `power`, `log`, `exp`, `sqrt`, `Offset`. Function `regexextract` is only available for the Druid-JDBC driver. + +**MongoDB**: `Median`, `Percentile`, `power`, `log`, `exp`, `sqrt`, `Offset`, `regexextract` + +**MariaDB**: `Median`, `Percentile`, `Offset`. + +**MySQL**: `Median`, `Percentile`, `Offset`. + +**Presto**: `convertTimezone`. Only provides _approximate_ results for `Median` and `Percentile`. + +**SparkSQL**: `convertTimezone`. + +**SQL Server**: `Median`, `Percentile` and `regexextract`. + +**SQLite**: `exp`, `log`, `Median`, `Percentile`, `power`, `regexextract`, `StandardDeviation`, `sqrt` and `Variance`. + +**Vertica**: `Median` and `Percentile`. + +If you're using or maintaining a third-party database driver, please [refer to the wiki](https://github.com/metabase/metabase/wiki/What's-new-in-0.35.0-for-Metabase-driver-authors) to see how your driver might be impacted. + +Check out our tutorial on [custom expressions in the query builder](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) to learn more. + +[expressions]: ./expressions diff --git a/_docs/doc-update-detection/questions/query-builder/expressions.md b/_docs/doc-update-detection/questions/query-builder/expressions.md new file mode 100644 index 000000000..f2d63a30c --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions.md @@ -0,0 +1,123 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Custom expressions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions.md' +redirect_from: + - /docs/doc-update-detection/users-guide/expressions +--- + +# Custom expressions + +![Custom expression editor](../images/custom-expression-editor.png) + +[Custom expressions][expression-list] are like formulas in spreadsheet software like Excel, Google Sheets, and LibreOffice Calc. They are the power tools in the query builder's editor that allow you to ask more complicated questions. + +You can also skip to the [complete list of expressions][expression-list]. + +## Custom expressions to create filters, metrics, and custom columns + +To use the custom expression editor, create a **Custom Column** (where the custom expression is used as a Field Formula to calculate values for the new column), or click on **Filter** or **Summarize** and select **Custom Expression**. + +When using the query builder, you can use expressions to create new: + +- **Custom columns**. You could use `[Subtotal] / [Quantity]` to create a new column, which you could name "Item price". +- **Filters**. The expression `contains([comment], "Metabase")` would filter for rows where the `comment` field contained the word "Metabase". +- **Summaries**. Also known as metrics or aggregations. `Share([Total] > 50)` would return the percentage of orders with totals greater than 50 dollars. + +Type in your expression, give it a name, and click **Done**. If the Done button is grayed out, check that your expression is valid, and that you've given the expression a name (which you enter at the bottom of the expression editor). + +This page covers the basics of expressions. You can check out a [full list of expressions][expression-list] in Metabase, or walk through a tutorial that shows you how you can use [custom expressions in the notebook editor][custom-expressions]. + +## Types of expressions + +There are two basic types of expressions, **Aggregations** and **Functions**. Check out a [full list of expressions][expression-list]. + +### Aggregations + +[Aggregations][aggregations] take values from multiple rows to perform a calculation, such as finding the average value from all values in a column. Aggregations functions can only be used in the **Summarize** section of the notebook editor, because aggregations use values from all rows for that column. So while you could create a custom column with the formula `[Subtotal] + [Tax]`, you could _not_ write `Sum([Subtotal] + [Tax])`, unless you were creating a custom metric expression (that would add up all the subtotals and taxes together). + +### Functions + +[Functions][functions], by contrast, do something to each value in a column, like searching for a word in each value (`contains`), rounding each value up to the nearest integer (the `ceil` function), and so on. + +## Function browser + +![Function browser](../images/function-browser.png) + +The expression editor includes a function browser to help you find the function you need. To view the browser, flick on the **f** on the right of the expression editor. See also a [list of functions and aggregations](./expressions-list). + +## Auto-format + +![Auto-format expression](../images/auto-format.png) + +To format expressions, click on the auto-format button on the right side of the expression editor (the lightning bolt wrapped in braces). + +## Basic mathematical operators + +Use `+`, `-`, `*` (multiply), `/` (divide) on numeric columns with numeric values, like integers, floats, and double. You can use parentheses, `(` and `)`, to group parts of your expression. + +For example, you could create a new column that calculates the difference between the total and subtotal of a order: `[Total] - [Subtotal]`. + +To do math on timestamp columns, you can use [Date functions](expressions-list#date-functions) like [dateDiff](./expressions/datetimediff). + +## Conditional operators + +- `AND` +- `OR` +- `NOT` +- `>` +- `>=` (greater than or equal to) +- `<` +- `<=` (less than or equal to) +- `=` +- `!=` (not equal to) + +For example, you could create a filter for customers from California or Vermont: `[State] = "CA" OR [State] = "VT"`. + +You can also use conditionals with the `case` function (alias `if`): + +``` +case([Size] = "L", "LARGE", [SIZE] = "M", "MEDIUM", "SMALL") +``` + +See [`case`](./expressions/case). + +## Referencing other columns + +You can refer to columns in the current table, or to columns that are linked via a foreign key relationship. Column names should be included inside of square brackets, like this: `[Name of Column]`. Columns in connected tables can be referred to like this: `[ConnectedTableName.Column]`. + +## Referencing Segments and Metrics + +You can refer to saved [metrics](../../data-modeling/metrics) and [segments](../../data-modeling/segments) that are present in the currently selected table. You write these out the same as with columns, like this: `[Valid User Sessions]`. + +## Filter expressions and conditionals + +Some things to keep in mind about filter expressions and conditionals: + +- Filter expressions are different in that they must return a Boolean value (something that's either true or false). For example, you could write `[Subtotal] + [Tax] < 100`. Metabase would look at each row, add its subtotal and tax, the check if that sum is greater than 100. If it is, the statement evaluates as true, and Metabase will include the row in the result. If instead you were to (incorrectly) write `[Subtotal] + [Tax]`, Metabase wouldn't know what to do, as that expression doesn't evaluate to true or false. +- You can use functions inside of the conditional portion of the `CountIf` and `SumIf` aggregations, like so: `CountIf( round([Subtotal]) > 100 OR floor([Tax]) < 10 )`. + +## Working with dates in filter expressions + +If you want to work with dates in your filter expressions, the dates need to follow the format, `"YYYY-MM-DD"` — i.e., four characters for the year, two for the month, and two for the day, enclosed in quotes `"` and separated by dashes `-`. + +Example: + +`between([Created At], "2020-01-01", "2020-03-31") OR [Received At] > "2019-12-25"` + +This expression would return rows where `Created At` is between January 1, 2020 and March 31, 2020, or where `Received At` is after December 25, 2019. + +## List of expressions + +See a full list of [expressions][expression-list]. + +For a tutorial on expressions, see [Custom expressions in the query builder][custom-expressions]. + +[aggregations]: ./expressions-list#aggregations +[custom-expressions]: /learn/metabase-basics/querying-and-dashboards/questions/custom-expressions +[expression-list]: ./expressions-list +[functions]: ./expressions-list#functions diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/case.md b/_docs/doc-update-detection/questions/query-builder/expressions/case.md new file mode 100644 index 000000000..68510cead --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/case.md @@ -0,0 +1,350 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Case +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/case.md' +--- + +# Case + +`case` (alias `if`) checks if a value matches a list of conditions, and returns some output based on the first condition that's met. `if` and `case` work exactly the same. + +You can optionally tell `case` to return a default output if none of the conditions are met. If you don't set a default output, `case` will return `null` after checking all of your conditions (`null` values are displayed as blank values in Metabase). + +Use the `case` expression whenever you need to: + +- [bucket a range of values](#bucketing-data-for-frequency-tables-or-histograms), +- [label the rows in your dataset](#labeling-a-row-based-on-conditions-from-multiple-columns), or +- [aggregate rows based on conditional logic](#aggregating-data-based-on-conditions-from-multiple-columns). + +| Syntax | +| --------------------------------------------------------------------- | +| `case(condition1, output1, condition2, output2, ..., default_output)` | +| Returns the output from the first condition that's met. | + +| Example | +| ---------------------------------------------------------------------------------------------------------------- | +| `case(isempty("glass half full"), "empty glass", isnull("glass half full"), "missing glass", "glass half full")` | +| "glass half full" | + +## Bucketing data for frequency tables or histograms + +| Amount | Bucket | +| ------ | ------ | +| 6 | 0-9 | +| 18 | 10-19 | +| 31 | 30-39 | +| 57 | 50+ | + +where **Bucket** is a custom column with the expression: + +``` +case([Amount] >= 0 AND [Amount] <= 9, "0-9", + [Amount] >= 10 AND [Amount] <= 19, "10-19", + [Amount] >= 20 AND [Amount] <= 29, "20-29", + [Amount] >= 30 AND [Amount] <= 39, "30-39", + [Amount] >= 40 AND [Amount] <= 49, "40-49", "50+") +``` + +## Labeling a row based on conditions from multiple columns + +| Sighting ID | Has Wings | Has Face | Sighting Type | +| ----------- | --------- | -------- | ------------- | +| 1 | True | True | Bird | +| 2 | True | False | Plane | +| 3 | False | False | Superman | +| 4 | False | True | Unknown | + +where **Sighting Type** is a custom column with the expression: + +``` +case([Has Wings] = TRUE AND [Has Face] = TRUE, "Bird", + [Has Wings] = TRUE AND [Has Face] = FALSE, "Plane", + [Has Wings] = FALSE AND [Has Face] = TRUE, "Superman", "Unknown") +``` + +You can use the columns holding your "labels" to: + +- Apply [business definitions or business logic][business-logic] to your datasets. +- [Power a filter][filter-learn]. +- [Segment data for data sandboxing][data-sandboxing-docs]. + +## Aggregating data based on conditions from multiple columns + +You can combine `case` with [aggregate functions][aggregate-functions] to only aggregate rows that meet your conditions. + +For example, if we want to count the unique number of orders for each order date, but only those with a "Shipped" status: + +| Order ID | Order Date | Status | +| -------- | ---------- | --------- | +| 1 | 2022-04-01 | Paid | +| 1 | 2022-04-03 | Shipped | +| 2 | 2022-05-12 | Paid | +| 2 | 2022-05-12 | Cancelled | + +1. Create the custom expression `distinct(case([Status] = "Shipped", [Order ID]))` and name it "Total Orders Shipped". +2. Choose **Order Date** as the group by column. +3. Click **Visualize** to return the result: + +| Order Date | Total Orders Shipped | +| ---------- | -------------------- | +| 2022-04-01 | 1 | +| 2022-05-01 | 0 | + +## Accepted data types + +| [Data type][data-types] | Works with `case` | +| ----------------------- | ----------------- | +| String | ✅ | +| Number | ✅ | +| Timestamp | ✅ | +| Boolean | ✅ | +| JSON | ❌ | + +## Limitations + +All of the outputs must have the same data type. + +**Avoid:**: + +``` +case(condition1, "string", condition2, TRUE, condition3, 1) +``` + +**Do:**: + +``` +case(condition1, "string", condition2, "TRUE", condition3, "1") +``` + +## Related functions + +This section covers functions and formulas that can be used interchangeably with the Metabase `case` expression, with notes on how to choose the best option for your use case. + +**[Metabase expressions][custom-expressions-list]** + +- [Coalesce](#coalesce) +- [Countif](#countif) +- [Sumif](#sumif) + +**Other tools** + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +### Coalesce + +Using the table from the [Coalesce: Consolidating values](./coalesce#consolidating-values-from-different-columns) example: + +| Notes | Comments | `coalesce([Notes], [Comments] "No notes or comments.")` | +| -------------- | ----------------- | ------------------------------------------------------- | +| I have a note. | I have a comment. | I have a note. | +| | I have a comment. | I have a comment. | +| I have a note. | | I have a note. | +| | | No notes or comments. | + +The [Metabase `coalesce` expression](./coalesce) + +``` +coalesce([Notes], [Comments] "No notes or comments.") +``` + +is equivalent to the `case` expression + +``` +case(ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = FALSE, [Notes], + ISBLANK([Notes]) = TRUE AND ISBLANK([Comments]) = False, [Comments], + ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = TRUE, [Notes], + ISBLANK([Notes]) = TRUE AND ISBLANK([Comments]) = TRUE, "No notes or comments") +``` + +`coalesce` is much nicer to write if you don't mind taking the first value when both of your columns are non-blank. Use `case` if you want to define a specific output for this case (such as, "I have a note _and_ a comment"). + +### Countif + +Using the table from the [Aggregating data](#aggregating-data-based-on-conditions-from-multiple-columns) example: + +| Order ID | Order Date | Status | +| -------- | ---------- | --------- | +| 1 | 2022-04-01 | Paid | +| 1 | 2022-04-03 | Shipped | +| 2 | 2022-05-12 | Paid | +| 2 | 2022-05-12 | Cancelled | + +The [Metabase `countif` expression][countif] + +``` +countif(case([Status] = "Shipped")) +``` + +is equivalent to the `case` expression: + +``` +count(case([Status] = "Shipped", [Row ID])) +``` + +`countif` is equivalent to `case` when you are counting **all** rows in the table that meet your conditions. It is **not** equivalent if you want to count **unique** rows that meet your conditions. + +### Sumif + +Using an expanded version of the table from the [Aggregating data](#aggregating-data-based-on-conditions-from-multiple-columns) example: + +| Row ID | Order ID | Order Date | Status | Amount | +| ------ | -------- | ---------- | --------- | ------ | +| 1 | 1 | 2022-04-01 | Paid | \$20 | +| 2 | 1 | 2022-04-03 | Shipped | \$20 | +| 3 | 2 | 2022-05-12 | Paid | \$80 | +| 4 | 2 | 2022-05-12 | Cancelled | \$80 | + +The [Metabase `sumif` expression][sumif] + +``` +sumif([Amount], [Status] = "Shipped") +``` + +is equivalent to the `case` expression: + +``` +sum(case([Status] = "Shipped", [Amount])) +``` + +`sumif` is equivalent to `case` when you sum a single column for single condition. + +You should use `case` if you want to sum a second column under a second, separate condition. For example, if you want to sum the **Amount** column when **Status** = "Shipped" and another (hypothetical) column like **Refunded Amount** when **Status** = "Refunded". + +### SQL + +In most cases (unless you're using a NoSQL database), questions created from the [notebook editor][notebook-editor-def] are converted into SQL queries that run against your database or data warehouse. Metabase `case` expressions are converted into SQL `CASE WHEN` statements. + +Using the table from the [Labeling rows](#labeling-a-row-based-on-conditions-from-multiple-columns) example: + +| Sighting ID | Has Wings | Has Face | Sighting Type | +| ----------- | --------- | -------- | ------------- | +| 1 | True | True | Bird | +| 2 | True | False | Plane | +| 3 | False | False | Superman | +| 4 | False | True | Unknown | + +The SQL `CASE WHEN` statement: + +```sql +SELECT + CASE WHEN "Has Wings" = TRUE AND "Has Face" = TRUE THEN "Bird" + WHEN "Has Wings" = TRUE AND "Has Face" = FALSE THEN "Plane" + WHEN "Has Wings" = FALSE AND "Has Face" = TRUE THEN "Superman" + ELSE "Unknown" END +FROM mystery_sightings +``` + +is equivalent to the `case` expression used for **Sighting Type**: + +``` +case([Has Wings] = TRUE AND [Has Face] = TRUE, "Bird", + [Has Wings] = TRUE AND [Has Face] = FALSE, "Plane", + [Has Wings] = FALSE AND [Has Face] = TRUE, "Superman", "Unknown") +``` + +For example, this [SQL trick to order bar charts](/learn/metabase-basics/querying-and-dashboards/sql-in-metabase/sql-tricks-ordering-charts) could be written using a Metabase `case` expression instead. + +### Spreadsheets + +Using the table from the [Labeling rows](#labeling-a-row-based-on-conditions-from-multiple-columns) example: + +| Sighting ID | Has Wings | Has Face | Sighting Type | +| ----------- | --------- | -------- | ------------- | +| 1 | True | True | Bird | +| 2 | True | False | Plane | +| 3 | False | False | Superman | +| 4 | False | True | Unknown | + +The spreadsheet formula + +``` +=IF(AND(B2 = TRUE, C2 = TRUE), "Bird", + IF(AND(B2 = TRUE, C2 = FALSE), "Plane", + IF(AND(B2 = FALSE, C2 = TRUE), "Superman", "Unknown") + ) + ) +``` + +is equivalent to the `case` expression used for **Sighting Type**: + +``` +case([Has Wings] = TRUE AND [Has Face] = TRUE, "Bird", + [Has Wings] = TRUE AND [Has Face] = FALSE, "Plane", + [Has Wings] = FALSE AND [Has Face] = TRUE, "Superman", "Unknown") +``` + +### Python + +There are many ways to implement conditional logic using Python. We'll cover the approaches that make sense to convert into Metabase `case` expressions. + +Using the table from the [Labeling rows](#labeling-a-row-based-on-conditions-from-multiple-columns) example (and assuming it's in a dataframe called `df`): + +| Sighting ID | Has Wings | Has Face | Sighting Type | +| ----------- | --------- | -------- | ------------- | +| 1 | True | True | Bird | +| 2 | True | False | Plane | +| 3 | False | False | Superman | +| 4 | False | True | Unknown | + +**[numpy][numpy] select()** + +```python +conditions = [ + (df["has_wings"] == True) & (df["has_face"] == True), + (df["has_wings"] == True) & (df["has_face"] == False), + (df["has_wings"] == False) & (df["has_face"] == True)] + +outputs = ["Bird", "Plane", "Superman"] + +df["Sighting Type"] = np.select(conditions, outputs, default="Unknown") +``` + +**Helper function with [pandas][pandas] apply()** + +```python +def Identify(df): + if ((df["has_wings"] == True) & (df["has_face"] == True)): + return "Bird" + elif ((df["has_wings"] == True) & (df["has_face"] == False)): + return "Plane" + elif ((df["has_wings"] == False) & (df["has_face"] == True)): + return "Superman" + else: + return "Unknown" + +df["Sighting Type"]= df.apply(Identify, axis=1) +``` + +The approaches above are equivalent to the `case` expression used for **Sighting Type**: + +``` +case([Has Wings] = TRUE AND [Has Face] = TRUE, "Bird", + [Has Wings] = TRUE AND [Has Face] = FALSE, "Plane", + [Has Wings] = FALSE AND [Has Face] = TRUE, "Superman", "Unknown") +``` + +## Further reading + +- [Custom expressions documentation][custom-expressions-doc] +- [Custom expressions tutorial][custom-expressions-learn] + +[aggregate-functions]: ../expressions-list#aggregations +[business-logic]: /learn/grow-your-data-skills/analytics/avoiding-data-jargon#create-specific-language-and-shared-definitions +[countif]: ../expressions-list#countif +[custom-expressions-doc]: ../expressions +[custom-expressions-list]: ../expressions-list +[custom-expressions-learn]: /learn/metabase-basics/querying-and-dashboards/questions/custom-expressions +[data-sandboxing-docs]: ../../../permissions/data-sandboxes +[data-types]: /learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types +[filter-learn]: /learn/metabase-basics/querying-and-dashboards/questions/searching-tables +[notebook-editor-def]: /glossary/notebook_editor +[numpy]: https://numpy.org/doc/ +[pandas]: https://pandas.pydata.org/pandas-docs/stable/ +[sql-reference-guide]: /learn/grow-your-data-skills/learn-sql/debugging-sql/sql-syntax#common-sql-reference-guides +[sumif]: ./sumif diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/coalesce.md b/_docs/doc-update-detection/questions/query-builder/expressions/coalesce.md new file mode 100644 index 000000000..c06772b43 --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/coalesce.md @@ -0,0 +1,189 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Coalesce +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/coalesce.md' +--- + +# Coalesce + +`coalesce` looks at the values in a list (in order), and returns the first non-null value. + +This function is useful when you want to: + +- [fill in missing data](#filling-in-empty-or-null-values), +- [consolidate data from multiple columns](#consolidating-values-from-different-columns), or +- [create calculations across multiple columns](#creating-calculations-across-different-columns). + +| Syntax | Example | +| ------------------------------------------------------- | ----------------------------------------------- | +| `coalesce(value1, value2, …)` | `coalesce("null", "null", "bananas", "null" …)` | +| Returns the first non-null value from a list of values. | “bananas” | + +## Filling in empty or null values + +| left_table_col | right_table_col | `coalesce([right_table_col], 0)` | +| -------------- | --------------- | -------------------------------- | +| 1 | 1 | 1 | +| 2 | `null` | 0 | +| 3 | `null` | 0 | +| 4 | 4 | 4 | + +You may want to fill in empty or null values if you have: + +- Sparse data. +- `null` values created by a left join (the example shown above). + +For a more detailed example, see [Filling in data for missing report dates][missing-dates]. + +## Consolidating values from different columns + +| Notes | Comments | `coalesce([Notes], [Comments] "No notes or comments.")` | +| -------------- | ----------------- | ------------------------------------------------------- | +| I have a note. | I have a comment. | I have a note. | +| | I have a comment. | I have a comment. | +| I have a note. | | I have a note. | +| | | No notes or comments. | + +## Creating calculations across different columns + +| Subtotal | Discount | `coalesce([Subtotal], 0) - coalesce([Discount], 0)` | +| -------- | -------- | --------------------------------------------------- | +| 10.00 | 0.15 | 9.85 | +| 21.00 | | 21.00 | +| 16.00 | 1.60 | 14.40 | +| 4.00 | | 4.00 | + +Calculations in Metabase will return `null` if any of the input columns are `null`. This is because `null` values in your data represent "missing" or "unknown" information, which isn't necessarily the same as an amount of "0". That is, adding 1 + "unknown" = "unknown". + +If you want to treat "unknown" values as zeroes (or some other value that means "nothing" in your data), we recommend using `coalesce` to wrap the columns used in your calculations. + +## Accepted data types + +| [Data type][data-types] | Works with `coalesce` | +| ----------------------- | --------------------- | +| String | ✅ | +| Number | ✅ | +| Timestamp | ✅ | +| Boolean | ✅ | +| JSON | ❌ | + +## Limitations + +Use the same data types within a single `coalesce` function. If you want to coalesce values that have different data types: + +- Use the SQL `CAST` operator. +- [Change the data type from the Table Metadata page][cast-data-type]. + +If you want to use `coalesce` with JSON or JSONB data types, you'll need to flatten the JSON objects first. For more information, look up the JSON functions that are available in your SQL dialect. You can find some [common SQL reference guides here][sql-reference-guide]. + +## Related functions + +This section covers functions and formulas that can be used interchangeably with the Metabase `coalesce` expression, with notes on how to choose the best option for your use case. + +**Metabase expressions** + +- [case](#case) + +**Other tools** + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +All examples use the custom expression and sample data from the [Consolidating values](#consolidating-values-from-different-columns) example: + +| Notes | Comments | `coalesce([Notes], [Comments] "No notes or comments.")` | +| -------------- | ----------------- | ------------------------------------------------------- | +| I have a note. | I have a comment. | I have a note. | +| | I have a comment. | I have a comment. | +| I have a note. | | I have a note. | +| | | No notes or comments. | + +### Case + +The [Metabase `case` expression](./case) + +``` +case(ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = FALSE, [Notes], + ISBLANK([Notes]) = TRUE AND ISBLANK([Comments]) = False, [Comments], + ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = TRUE, [Notes], + ISBLANK([Notes]) = TRUE AND ISBLANK([Comments]) = TRUE, "No notes or comments") +``` + +is equivalent to the Metabase `coalesce` expression: + +``` +coalesce([Notes], [Comments] "No notes or comments.") +``` + +`coalesce` is much nicer to write if you don't mind taking the first value when both of your columns are non-blank. [Use `case` if you want to define a specific output][case-to-coalesce] (e.g., if you want to return "I have a note _and_ a comment" instead of "I have a note".). + +### SQL + +In most cases (unless you're using a NoSQL database), questions created from the [notebook editor][notebook-editor-def] are converted into SQL queries that run against your database or data warehouse. + +The SQL `coalesce` function + +```sql +SELECT + COALESCE(notes, comments, "no notes or comments") +FROM + sample_table; +``` + +is equivalent to the Metabase `coalesce` expression: + +``` +coalesce([Notes], [Comments] "No notes or comments.") +``` + +### Spreadsheets + +If your [notes and comments table](#consolidating-values-from-different-columns) is in a spreadsheet where "Notes" is in column A, and "Comments" is in column B, then the formula + +``` +=IF(ISBLANK($A2),$B2,IF(ISBLANK($B2),$A2,"No notes or comments.")) +``` + +is equivalent to the Metabase `coalesce` expression: + +``` +coalesce([Notes], [Comments] "No notes or comments.") +``` + +Alternatively, you may be used to working with a INDEX and MATCH in an array formula if you’re “coalescing” data across three or more columns in a spreadsheet. + +### Python + +Assuming the [notes and comments table](#consolidating-values-from-different-columns) is in a dataframe called `df`, the combination of `pandas` functions `combine_first()` and `fillna()` + +``` +df['custom_column'] = df['notes'].combine_first(df['comments'])\ + .fillna('No notes or comments.') +``` + +are equivalent to the Metabase `coalesce` expression: + +``` +coalesce([Notes], [Comments] "No notes or comments.") +``` + +## Further reading + +- [Custom expressions documentation][custom-expressions-doc] +- [Custom expressions tutorial][custom-expressions-learn] + +[case-to-coalesce]: ./case#coalesce +[cast-data-type]: ../../../data-modeling/metadata-editing#casting-to-a-specific-data-type +[custom-expressions-doc]: ../expressions +[custom-expressions-learn]: /learn/metabase-basics/querying-and-dashboards/questions/custom-expressions +[data-types]: /learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types +[missing-dates]: /learn/grow-your-data-skills/learn-sql/debugging-sql/sql-logic-missing-data#how-to-fill-in-data-for-missing-report-dates +[notebook-editor-def]: /glossary/notebook_editor +[numpy]: https://numpy.org/doc/ +[pandas]: https://pandas.pydata.org/pandas-docs/stable/ +[sql-reference-guide]: /learn/grow-your-data-skills/learn-sql/debugging-sql/sql-syntax#common-sql-reference-guides diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/concat.md b/_docs/doc-update-detection/questions/query-builder/expressions/concat.md new file mode 100644 index 000000000..01a349911 --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/concat.md @@ -0,0 +1,115 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Concat +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/concat.md' +--- + +# Concat + +`concat` concatenates data from two or more columns or values, and returns a string. + +## Syntax + +``` +concat(value1, value2, ...) +``` + +`value1`, `value2` ... can be columns or values. Metabase will convert non-string columns into strings before concatenating their values. + +### Example + +| Expression | Result | +| ---------------------------------------- | ------------------------ | +| `concat("Vienna", "Austria")` | `"ViennaAustria"` | +| `concat("Vienna", " is in " ,"Austria")` | `"Vienna is in Austria"` | +| `concat([City], " is in " ,[Country])` | `"Vienna is in Austria"` | + +### Metabase will use unformatted values for non-string columns + +When you use non-string columns in `concat`, Metabase will ignore any [formatting](../../../data-modeling/formatting) that you applied to the columns when converting the column to a string. + +For example, if you formatted a number to display only the first two decimal digits in the table results, the results of `concat` would still include additional decimal digits (if any) found in the raw results. + +| Formatted display | Value | `concat("Result:", " ", [Value])` | +| ----------------- | ------------------------- | --------------------------------- | +| `Kitten` | `Kitten` | `Result: Kitten` | +| `17` | `17` | `Result: 17` | +| `31.25` | `31.24823945` | `Result: 31.24823945` | +| `42%` | `0.42` | `Result: 0.42` | +| `January 1, 2024` | `2025-02-11 21:40:27.892` | `Result: 31.24823945` | + +## Accepted data types + +| [Data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types) | Works with `concat` | +| ------------------------------------------------------------------------------------------------------------------------------ | ------------------- | +| String | ✅ | +| Number | ✅ | +| Timestamp | ✅ | +| Boolean | ✅ | +| JSON | ✅ | + +Non-string types will be converted to strings. Regardless of the type of the value passed to `concat`, the result will be a string. + +## Related functions + +This section covers functions and formulas that work the same way as the Metabase `concat` expression, with notes on how to choose the best option for your use case. + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +### SQL + +In most cases (unless you're using a NoSQL database), questions created from the [notebook editor](/glossary/notebook_editor) are converted into SQL queries that run against your database or data warehouse. + +If our sample data is stored in a relational database: + +```sql +SELECT + CONCAT(City, ", ", Country) AS "Location" +FROM + richard_linklater_films; +``` + +is equivalent to the Metabase `concat` expression: + +``` +concat([City], ", ", [Country]) +``` + +### Spreadsheets + +If our sample data is in a spreadsheet where "City" is in column A, and "Country" in column B, we can create a third column "Location" like this: + +``` +=CONCATENATE(A2, ", ", B2) +``` + +which is equivalent to the Metabase `concat` expression: + +``` +concat([City], ", ", [Country]) +``` + +### Python + +Assuming the sample data is in a dataframe column called `df`: + +``` +df["Location"] = df["City"] + ", " + df["Country"] +``` + +is the same as the Metabase `concat` expression: + +``` +concat([City], ", ", [Country]) +``` + +## Further reading + +- [Custom expressions documentation](../expressions) +- [Custom expressions tutorial](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/converttimezone.md b/_docs/doc-update-detection/questions/query-builder/expressions/converttimezone.md new file mode 100644 index 000000000..6b310e6ff --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/converttimezone.md @@ -0,0 +1,257 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: ConvertTimezone +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/converttimezone.md' +--- + +# ConvertTimezone + +`convertTimezone` shifts a timestamp into a specified time zone by adding or subtracting the right interval from the timestamp. + +| Syntax | Example | +| --------------------------------------------------------------------- | --------------------------------------------------------------------------------- | +| `convertTimezone(column, target, source)` | `convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Eastern")` | +| Shifts a timestamp from the source time zone to the target time zone. | Returns the value `2022-12-28T09:00:00`, displayed as `December 28, 2022 9:00 AM` | + +Timestamps and time zones are rather nasty to work with (it's easy to make mistakes, and difficult to catch them), so you should only try to use `convertTimezone` if the interpretation of your data is sensitive to time-based cutoffs. + +For example, if you're tracking user logins over time, you probably won't run your business differently if some logins get counted on Mondays instead of Tuesdays. However, if you're using Metabase to do something precise, like your taxes, you (and the government) will probably care a lot more about the difference between transactions that occurred on Dec 31 vs. Jan 1. + +## Supported time zones + +Metabase supports [tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). + +## Parameters + +`column` can be any of: + +- The name of a timestamp column, +- a custom expression that returns a [timestamp](#accepted-data-types), or +- a string in the format `"YYYY-MM-DD` or `"YYYY-MM-DDTHH:MM:SS"`. + +`target`: + +- The name of the time zone you want to assign to your column. + +`source`: + +- The name of your column's current time zone. +- Required for columns or expressions with the data type `timestamp without time zone`. +- Optional for columns or expressions with the data type `timestamp with time zone`. +- For more info, see [Accepted data types](#accepted-data-types). + +We support [tz database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) time zone names (such as "Canada/Eastern" instead of "EST"). + +## Creating custom report dates + +Let's say that you have some time series data that's stored in one or more time zones (**Source Time**). You want to create custom reporting dates for a team that lives in EST. + +| Source Time | Team Report Time (EST) | +| --------------------------- | --------------------------- | +| December 28, 2022, 10:00:00 | December 28, 2022, 07:00:00 | +| December 28, 2022, 21:00:00 | December 28, 2022, 19:00:00 | +| December 27, 2022, 08:00:00 | December 27, 2022, 05:00:00 | + +If **Source Time** is stored as a `timestamp with time zone` or a `timestamp with offset`, you only need to provide the `target` time zone: + +``` +convertTimezone([Source Time], 'EST') +``` + +If **Source Time** is stored as a `timestamp without time zone`, you _must_ provide the `source` time zone (which will depend on your database time zone): + +``` +convertTimezone([Source Time], 'EST', 'UTC') +``` + +It's usually a good idea to label `convertTimezone` columns with the name of the target time zone (or add the target time zone to the metadata of a model). We promise this will make your life easier when someone inevitably asks why the numbers don't match. + +If you're not getting the results that you expect: + +- Check if you have the right [source time zone](#choosing-a-source-time-zone). +- Ask your database admin about `timestamp with time zone` vs. `timestamp without time zone` (for more info, see [Accepted data types](#accepted-data-types)). + +### Choosing a source time zone + +When you're doing time zone conversions, make sure you know the source time zone that you're working with. Different columns (and even different rows) in the same table, question, or model can be in different "source" time zones. + +| Possible source time zone | Description | Example | +| ------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| Client time zone | Time zone where an event happened. | A web analytics service might capture data in the local time zone of each person who visited your website. | +| Database time zone | Time zone metadata that's been added to timestamps in your database. | It's a common database practice to store all timestamps in UTC. | +| No time zone | Missing time zone metadata | Databases don't _require_ you to store timestamps with time zone metadata. | +| Metabase report time zone | Time zone that Metabase uses to _display_ timestamps. | Metabase can display dates and times in PST, even if the dates and times are stored as UTC in your database. | + +For example, say you have a table with one row for each person who visited your website. It's hard to tell, just from looking at `December 28, 2022, 12:00 PM`, whether the "raw" timestamp is: + +- stored using your database's time zone (usually UTC), +- stored without time zone metadata (for example, if the website visitor is in HKT, then the timestamp `December 28, 2022, 12:00 PM` might "implicitly" use Hong Kong time), +- _displayed_ in your Metabase report time zone. + +For more gory details, see [Limitations](#limitations). + +## Accepted data types + +| [Data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types) | Works with `convertTimezone` | +| ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------- | +| String | ❌ | +| Number | ❌ | +| Timestamp | ✅ | +| Boolean | ❌ | +| JSON | ❌ | + +We use "timestamp" and "datetime" to talk about any temporal data type that's supported by Metabase. + +If your timestamps are stored as strings or numbers in your database, an admin can [cast them to timestamps](../../../data-modeling/metadata-editing#casting-to-a-specific-data-type) from the Table Metadata page. + +To use `convertTimezone` without running into errors or pesky undetectable mistakes, you should know that there are a few varieties of `timestamp` data types: + +| Data type | Description | Example | +| ----------------------------- | ----------------------------------------- | ---------------------------------------------------- | +| `timestamp with time zone` | Knows about location. | `2022-12-28T12:00:00 AT TIME ZONE 'America/Toronto'` | +| `timestamp with offset` | Knows about the time difference from UTC. | `2022-12-28T12:00:00-04:00` | +| `timestamp without time zone` | No time zone info. | `2022-12-28T12:00:00` | + +Note that the first part of the timestamp is in UTC (same thing as GMT). The time zone or offset tells you how much time to add or subtract for a given time zone. + +`convertTimezone` will work with all three types of timestamps, but the output of `convertTimezone` will always be a `timestamp without time zone`. + +## Limitations + +`convertTimezone` is currently unavailable for the following databases: + +- Amazon Athena +- Databricks +- Druid +- MongoDB +- Presto +- SparkSQL +- SQLite +- Metabase Sample Database + +### Notes on source time zones + +Metabase displays timestamps without time zone or offset information, which is why you have to be so careful about the [source time zone](#choosing-a-source-time-zone) when using `convertTimezone`. + +The Metabase report time zone only applies to `timestamp with time zone` or `timestamp with offset` data types. For example: + +| Raw timestamp in your database | Data type | Report time zone | Displayed as | +| ---------------------------------------- | ----------------------------- | ---------------- | ---------------------- | +| `2022-12-28T12:00:00 AT TIME ZONE 'CST'` | `timestamp with time zone` | 'Canada/Eastern' | Dec 28, 2022, 7:00 AM | +| `2022-12-28T12:00:00-06:00` | `timestamp with offset` | 'Canada/Eastern' | Dec 28, 2022, 7:00 AM | +| `2022-12-28T12:00:00` | `timestamp without time zone` | 'Canada/Eastern' | Dec 28, 2022, 12:00 AM | + +The Metabase report time zone will not apply to the output of a `convertTimezone` expression. For example: + +``` +convertTimezone("2022-12-28T12:00:00 AT TIME ZONE 'Canada/Central'", "Canada/Pacific", "Canada/Central") +``` + +will produce a raw `timestamp without time zone` + +``` +2022-12-28T04:00:00 +``` + +and displayed in Metabase as + +``` +Dec 28, 2022, 4:00 AM +``` + +If you use `convertTimezone` on a `timestamp without time zone`, make sure to use 'UTC' as the `source` time zone, otherwise the expression will shift your timestamp by the wrong amount. For example, if our `timestamp without time zone` is only "implied" to be in CST, we should use 'UTC' as the `source` parameter to get the same result as above. + +For example, if we choose 'CST' as the `source` time zone for a `timestamp without time zone`: + +``` +convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Central") +``` + +we'll get the raw `timestamp without time zone` + +``` +2022-12-28T10:00:00 +``` + +displayed in Metabase as + +``` +Dec 28, 2022, 10:00 AM +``` + +## Related functions + +This section covers functions and formulas that work the same way as the Metabase `convertTimezone` expression, with notes on how to choose the best option for your use case. + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +### SQL + +When you run a question using the [query builder](/glossary/query_builder), Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results. + +If our [timestamp sample data](#creating-custom-report-dates) is a `timestamp without time zone` stored in a PostgreSQL database: + +```sql +SELECT source_time::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'EST' AS team_report_time_est +``` + +is the same as the `convertTimezone` expression with a `source` parameter set to 'UTC': + +``` +convertTimezone([Source Time], "Canada/Eastern", "UTC") +``` + +If `source_time` is a `timestamp with time zone` or `timestamp with offset` (for example, in a Snowflake database), then we don't need to specify a source time zone in SQL or in Metabase. + +```sql +SELECT convert_timezone('America/Toronto', source_time) AS team_report_time_est +``` + +is the same as + +``` +convertTimezone([Source Time], "Canada/Eastern") +``` + +Remember that the time zone names depend on your database. For example, Snowflake doesn't accept most time zone abbreviations (like EST). + +### Spreadsheets + +If our [timestamp sample data](#creating-custom-report-dates) is in a spreadsheet where "Source Time" is in column A, we can change it to EST by subtracting the hours explicitly: + +``` +A1 - TIME(5, 0, 0) +``` + +to get the same result as + +``` +convertTimezone([Client Time], "Canada/Eastern") +``` + +### Python + +If the [timestamp sample data](#creating-custom-report-dates) is stored in a `pandas` dataframe, you could convert the **Source Time** column to a `timestamp` object with time zone first(basically making a `timestamp without time zone` into a `timestamp with time zone`), then use `tz_convert` to change the time zone to EST: + +``` +df['Source Time (UTC)'] = pd.to_timestamp(df['Source Time'], utc=True) +df['Team Report Time (EST)'] = df['Source Time (UTC)'].dt.tz_convert(tz='Canada/Eastern') +``` + +to do the same thing as a nested `convertTimezone` expression + +``` +convertTimezone(convertTimezone([Source Time], "UTC"), "Canada/Eastern", "UTC") +``` + +## Further reading + +- [Custom expressions documentation](../expressions) +- [Custom expressions tutorial](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) +- [Time series analysis](/learn/metabase-basics/querying-and-dashboards/time-series/start) diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/countif.md b/_docs/doc-update-detection/questions/query-builder/expressions/countif.md new file mode 100644 index 000000000..f0425b4f1 --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/countif.md @@ -0,0 +1,293 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: CountIf +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/countif.md' +--- + +# CountIf + +`CountIf` counts the total number of rows in a table that match a condition. `CountIf` counts every row, not just unique rows. + +Syntax: `CountIf(condition)`. + +Example: in the table below, `CountIf([Plan] = "Basic")` would return 3. + +| ID | Plan | +| --- | -------- | +| 1 | Basic | +| 2 | Basic | +| 3 | Basic | +| 4 | Business | +| 5 | Premium | + +> [Aggregations](../expressions-list#aggregations) like `CountIf` should be added to the query builder's [**Summarize** menu](../../query-builder/summarizing-and-grouping) > **Custom Expression** (scroll down in the menu if needed). + +## Parameters + +`CountIf` accepts a [function](../expressions-list#functions) or [conditional statement](../expressions#conditional-operators) that returns a boolean value (`true` or `false`). + +## Multiple conditions + +We'll use the following sample data to show you `CountIf` with [required](#required-conditions), [optional](#optional-conditions), and [mixed](#some-required-and-some-optional-conditions) conditions. + +| ID | Plan | Active Subscription | +| --- | -------- | ------------------- | +| 1 | Basic | true | +| 2 | Basic | true | +| 3 | Basic | false | +| 4 | Business | false | +| 5 | Premium | true | + +### Required conditions + +To count the total number of rows in a table that match multiple required conditions, combine the conditions using the `AND` operator: + +``` +CountIf(([Plan] = "Basic" AND [Active Subscription] = true)) +``` + +This expression will return 2 on the sample data above (the total number of Basic plans that have an active subscription). + +### Optional conditions + +To count the total rows in a table that match multiple optional conditions, combine the conditions using the `OR` operator: + +``` +CountIf(([Plan] = "Basic" OR [Active Subscription] = true)) +``` + +Returns 4 on the sample data: there are three Basic plans, plus one Premium plan has an active subscription. + +### Some required and some optional conditions + +To combine required and optional conditions, group the conditions using parentheses: + +``` +CountIf(([Plan] = "Basic" OR [Plan] = "Business") AND [Active Subscription] = "false") +``` + +Returns 2 on the sample data: there are only two Basic or Business plans that lack an active subscription. + +> Tip: make it a habit to put parentheses around your `AND` and `OR` groups to avoid making required conditions optional (or vice versa). + +## Conditional counts by group + +In general, to get a conditional count for a category or group, such as the number of inactive subscriptions per plan, you'll: + +1. Write a `CountIf` expression with your conditions. +2. Add a [**Group by**](../../query-builder/summarizing-and-grouping) column in the query builder. + +Using the sample data: + +| ID | Plan | Active Subscription | +| --- | -------- | ------------------- | +| 1 | Basic | true | +| 2 | Basic | true | +| 3 | Basic | false | +| 4 | Business | false | +| 5 | Premium | true | + +Count the total number of inactive subscriptions per plan: + +``` +CountIf([Active Subscription] = false) +``` + +Alternatively, if your **Active Subscription** column contains `null` (empty) values that represent inactive plans, you could use: + +``` +CountIf([Payment], [Plan] != true) +``` + +> The "not equal" operator `!=` should be written as !=. + +To view your conditional counts by plan, set the **Group by** column to "Plan". + +| Plan | Total Inactive Subscriptions | +| -------- | ---------------------------- | +| Basic | 1 | +| Business | 1 | +| Premium | 0 | + +> Tip: when sharing your work with other people, it's helpful to use the `OR` filter, even though the `!=` filter is shorter. The inclusive `OR` filter makes it easier to understand which categories (e.g., plans) are included in your conditional count. + +## Accepted data types + +| [Data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types) | Works with `CountIf` | +| ------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| String | ❌ | +| Number | ❌ | +| Timestamp | ❌ | +| Boolean | ✅ | +| JSON | ❌ | + +`CountIf` accepts a [function](../expressions-list#functions) or [conditional statement](../expressions#conditional-operators) that returns a boolean value (`true` or `false`). + +## Related functions + +Different ways to do the same thing, because it's fun to try new things. + +**Metabase** + +- [case](#case) +- [CumulativeCount](#cumulativecount) + +**Other tools** + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +### case + +You can combine [`Count`](../expressions-list#count) with [`case`](./case): + +``` +Count(case([Plan] = "Basic", [ID])) +``` + +to do the same thing as `CountIf`: + +``` +CountIf([Plan] = "Basic") +``` + +The `case` version lets you count a different column when the condition isn't met. For example, if you've got data from different sources: + +| ID: Source A | Plan: Source A | ID: Source B | Plan: Source B | +| ------------ | -------------- | ------------ | -------------- | +| 1 | Basic | | | +| | | B | basic | +| | | C | basic | +| 4 | Business | D | business | +| 5 | Premium | E | premium | + +To count the total number of Basic plans across both sources, you could create a `case` expression to: + +- Count the rows in "ID: Source A" where "Plan: Source A = "Basic" +- Count the rows in "ID: Source B" where "Plan: Source B = "basic" + +``` +Count(case([Plan: Source A] = "Basic", [ID: Source A], + case([Plan: Source B] = "basic", [ID: Source B]))) +``` + +### CumulativeCount + +`CountIf` doesn't do running counts. You'll need to combine [CumulativeCount](../expressions-list#cumulativecount) with [`case`](./case). + +If our sample data is a time series: + +| ID | Plan | Active Subscription | Created Date | +| --- | -------- | ------------------- | ---------------- | +| 1 | Basic | true | October 1, 2020 | +| 2 | Basic | true | October 1, 2020 | +| 3 | Basic | false | October 1, 2020 | +| 4 | Business | false | November 1, 2020 | +| 5 | Premium | true | November 1, 2020 | + +And we want to get the running count of active plans like this: + +| Created Date: Month | Total Active Plans to Date | +| ------------------- | -------------------------- | +| October 2020 | 2 | +| November 2020 | 3 | + +Create an aggregation from **Summarize** > **Custom expression**: + +``` +CumulativeCount(case([Active Subscription] = true, [ID])) +``` + +You'll also need to set the **Group by** column to "Created Date: Month". + +### SQL + +When you run a question using the [query builder](/glossary/query_builder), Metabase will convert your query builder settings (filters, summaries, etc.) into a SQL query, and run that query against your database to get your results. + +If our [sample data](#multiple-conditions) is stored in a PostgreSQL database, the SQL query: + +```sql +SELECT COUNT(CASE WHEN plan = "Basic" THEN id END) AS total_basic_plans +FROM accounts +``` + +is equivalent to the Metabase expression: + +``` +CountIf([Plan] = "Basic") +``` + +If you want to get [conditional counts broken out by group](#conditional-counts-by-group), the SQL query: + +```sql +SELECT + plan, + COUNT(CASE WHEN active_subscription = false THEN id END) AS total_inactive_subscriptions +FROM accounts +GROUP BY + plan +``` + +The `SELECT` part of the SQl query matches the Metabase expression: + +``` +CountIf([Active Subscription] = false) +``` + +The `GROUP BY` part of the SQL query matches a Metabase [**Group by**](../../query-builder/summarizing-and-grouping) set to the "Plan" column. + +### Spreadsheets + +If our [sample data](#multiple-conditions) is in a spreadsheet where "ID" is in column A, the spreadsheet formula: + +``` +=CountIf(B:B, "Basic") +``` + +produces the same result as the Metabase expression: + +``` +CountIf([Plan] = "Basic") +``` + +### Python + +If our [sample data](#multiple-conditions) is in a `pandas` dataframe column called `df`, the Python code: + +```python +len(df[df['Plan'] == "Basic"]) +``` + +uses the same logic as the Metabase expression: + +``` +CountIf([Plan] = "Basic") +``` + +To get a [conditional count with a grouping column](#conditional-counts-by-group): + +```python +## Add your conditions + + df_filtered = df[df['Active subscription'] == false] + +## Group by a column, and count the rows within each group + + len(df_filtered.groupby('Plan')) +``` + +The Python code above will produce the same result as the Metabase `CountIf` expression (with the [**Group by**](../../query-builder/summarizing-and-grouping) column set to "Plan"). + +``` +CountIf([Active Subscription] = false) +``` + +## Further reading + +- [Custom expressions documentation](../expressions) +- [Custom expressions tutorial](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/cumulative.md b/_docs/doc-update-detection/questions/query-builder/expressions/cumulative.md new file mode 100644 index 000000000..7fbd34a2a --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/cumulative.md @@ -0,0 +1,140 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Cumulative count and sum' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/cumulative.md' +redirect_from: + - /docs/doc-update-detection/questions/expressions/cumulativesum + - /docs/doc-update-detection/questions/expressions/cumulativecount +--- + +# Cumulative count and sum + +Cumulative count computes the additive total count of rows across a breakout. Cumulative sum computes the rolling sum (also known as running total) of a column across a breakout. + +## Syntax + +You can use the predefined "Cumulative count" and "Cumulative sum" metrics, or a custom expression: + +``` +CumulativeCount +``` + +``` +CumulativeSum(column) +``` + +Cumulative metrics can only be used in the query builder's **Summarize** step — you can't use cumulative metrics to create a custom column or filter. + +## How cumulative metrics are computed + +Under the hood, cumulative metrics is computed in three steps: + +1. Group records using the breakout from the **Group by** block. +2. Count the rows in each group. +3. For each group, compute the cumulative total of the counts in all previous groups, including the current group. + +Because cumulative metrics use values from previous rows, the sort order in the breakout column matters. + +For example, if you have a table with data grouped by month, Metabase will compute the cumulative count like this: + +| Month | `Count` | `CumulativeCount` | +| -------- | ------- | ----------------- | +| July | 5 | 5 | +| November | 4 | 5+4 = 9 | +| March | 2 | 5 + 4 + 2 = 11 | + +If the sort is changed (while values remain the same), then the cumulative count changes as well: + +| Month | `Count` | `CumulativeCount` | +| -------- | ------- | ----------------- | +| March | 2 | 2 | +| July | 5 | 2 + 5 = 7 | +| November | 4 | 2 + 5 + 4 = 11 | + +When you have only one breakout in the query, Metabase will sort the data by the breakout column in ascending order (using the logic that your database uses for the column's data type). To change how Metabase accumulates the metric, you can add a **Sort** block by the breakout column. + +## Cumulative metrics with multiple breakouts + +Because cumulative metrics calculate their summaries based on previous rows, Metabase needs to determine what those previous rows are. Metabase will decide how to compute and display the cumulative metric first based on whether you're grouping by a datetime column, then by the order of other breakouts: + +### Queries with a datetime dimension + +If you use a datetime dimension in the **Group by** block, Metabase will accumulate along the datetime dimension, then break out by any other fields in the **Group by** block (in order): + +![Cumulative count by category, source, and created at](../../images/cumulative-date-category.png) + +If there are multiple datetime dimensions (including multiple groupings by the same datetime column), Metabase will accumulate along the the more granular dimension, regardless of their order. For example, if you're grouping by "Created At: Month" and "Viewed At: Week", Metabase will accumulate along "Viewed At: Week". + +![Cumulative count by two datetime fields](../../images/cumulative-multiple-datetimes.png) + +In queries with a datetime dimension, **Sort** blocks for non-datetime fields won't affect how Metabase computes the results. Sort blocks will only affect the order of breakouts in the results. + +### Queries without datetime dimension + +If there is no datetime field in the **Group by** block, Metabase will accumulate along the _last_ dimension specified in the **Group By** block, and break out by the other fields in their order, from left to right. + +![Cumulative count by two categorical dimensions](../../images/cumulative-no-datetime.png) + +By default, Metabase will use ascending sort for the dimension used for accumulation. You can add a **Sort** block for the accumulation dimension to change the order, which will change both how Metabase computes the cumulative metric and, how it presents the results. + +![Cumulative count by two categorical dimensions with order of accumulation changed](../../images/cumulative-no-datetime-order.png) + +Sorting by any field _other than_ the last (accumulation) field only affects the order of breakouts in the results. It won't change how Metabase computes the results. + +## Related functions + +### Cumulative count in SQL + +In SQL, you can use window functions to compute cumulative metrics. For example, to compute cumulative count of orders over months, you can use the following query: + +```sql +SELECT + created_month, + SUM(count(*)) OVER ( + ORDER BY + created_month ASC ROWS UNBOUNDED PRECEDING + ) AS "sum" +FROM + ( + SELECT + quantity, + DATE_TRUNC ('month', created_at) AS created_month + FROM + orders + ) +GROUP BY + created_month +ORDER BY + created_month ASC +``` + +### Cumulative sums in SQL + +For cumulative sums, you can use: + +```sql +SELECT + created_month, + SUM(SUM(quantity)) OVER ( + ORDER BY + created_month ASC ROWS UNBOUNDED PRECEDING + ) AS "sum" +FROM + ( + SELECT + quantity, + DATE_TRUNC ('month', created_at) AS created_month + FROM + orders + ) +GROUP BY + created_month +ORDER BY + created_month ASC +``` + +You can view the SQL generated by a query in the query builder by clicking on the **View the SQL** (**>\_**) button in the top right corner. diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/datetimeadd.md b/_docs/doc-update-detection/questions/query-builder/expressions/datetimeadd.md new file mode 100644 index 000000000..d985d0f77 --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/datetimeadd.md @@ -0,0 +1,179 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: DatetimeAdd +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/datetimeadd.md' +--- + +# DatetimeAdd + +`datetimeAdd` takes a datetime value and adds some unit of time to it. This function is useful when you're working with time series data that's marked by a "start" and an "end", such as sessions or subscriptions data. + +| Syntax | Example | +| ---------------------------------------------------------------------------------- | --------------------------------------- | +| `datetimeAdd(column, amount, unit)` | `datetimeAdd("2021-03-25", 1, "month")` | +| Takes a timestamp or date value and adds the specified number of time units to it. | `2021-04-25` | + +## Parameters + +`column` can be any of: + +- The name of a timestamp column, +- a custom expression that returns a [datetime](#accepted-data-types), or +- a string in the format `"YYYY-MM-DD"` or `"YYYY-MM-DDTHH:MM:SS"`(as shown in the example above). + +`unit` can be any of: + +- "year" +- "quarter" +- "month" +- "day" +- "hour" +- "minute" +- "second" +- "millisecond" + +`amount`: + +- An integer. You cannot use fractional values. For example, you cannot add "half a year" (0.5). +- May be a negative number: `datetimeAdd("2021-03-25", -1, "month")` will return `2021-04-25`. + +## Calculating an end date + +Let's say you're a coffee connoisseur, and you want to keep track of the freshness of your beans: + +| Coffee | Opened On | Finish By | +| ---------------------- | ----------------- | ----------------- | +| DAK Honey Dude | October 31, 2022 | November 14, 2022 | +| NO6 Full City Espresso | November 7, 2022 | November 21, 2022 | +| Ghost Roaster Giakanja | November 27, 2022 | December 11, 2022 | + +Here, **Finish By** is a custom column with the expression: + +``` +datetimeAdd([Opened On], 14, 'day') +``` + +## Checking if the current datetime is within an interval + +Let's say you want to check if today's date falls between a start date and an [end date](#calculating-an-end-date). Assume "today" is December 1, 2022. + +| Coffee | Opened On | Finish By | Still Fresh Today | +| ---------------------- | ----------------- | ----------------- | ----------------- | +| DAK Honey Dude | October 31, 2022 | November 14, 2022 | No | +| NO6 Full City Espresso | November 7, 2022 | November 21, 2022 | No | +| Ghost Roaster Giakanja | November 27, 2022 | December 11, 2022 | Yes | + +**Finish By** is a custom column with the expression: + +``` +datetimeAdd([Opened On], 14, 'day') +``` + +**Still Fresh Today** uses [case](../expressions/case) to check if the current date ([now](../expressions/now)) is [between](../expressions-list#between) the dates in **Opened On** and **Finish By**: + +``` +case(between(now, [Opened On], [Finish By]), "Yes", "No") +``` + +## Accepted data types + +| [Data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types) | Works with `datetimeAdd` | +| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------ | +| String | ❌ | +| Number | ❌ | +| Timestamp | ✅ | +| Boolean | ❌ | +| JSON | ❌ | + +We use "timestamp" and "datetime" to talk about any temporal data type that's supported by Metabase. For more info about these data types in Metabase, see [Timezones](../../../configuring-metabase/timezones#data-types). + +If your timestamps are stored as strings or numbers in your database, an admin can [cast them to timestamps](../../../data-modeling/metadata-editing#casting-to-a-specific-data-type) from the Table Metadata page. + +## Limitations + +If you're using MongoDB, `datetimeAdd` will only work on versions 5 and up. + +## Related functions + +This section covers functions and formulas that work the same way as the Metabase `datetimeAdd` expression, with notes on how to choose the best option for your use case. + +**[Metabase expressions](../expressions-list)** + +- [datetimeSubtract](#datetimesubtract) + +**Other tools** + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +### datetimeSubtract + +`datetimeSubtract` and `datetimeAdd` are interchangeable, since you can use a negative number for `amount`. It's generally a good idea to avoid double negatives (such as subtracting a negative number). + +``` +datetimeSubtract([Opened On], -14, "day") +``` + +does the same thing as + +``` +datetimeAdd([Opened On], 14, "day") +``` + +### SQL + +When you run a question using the [query builder](/glossary/query_builder), Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results. + +If our [coffee sample data](#calculating-an-end-date) is stored in a PostgreSQL database: + +```sql +SELECT opened_on + INTERVAL '14 days' AS finish_by +FROM coffee +``` + +is equivalent to the Metabase `datetimeAdd` expression: + +``` +datetimeAdd([Opened On], 14, "day") +``` + +### Spreadsheets + +If our [coffee sample data](#calculating-an-end-date) is in a spreadsheet where "Opened On" is in column A with a date format, the spreadsheet function + +``` +A:A + 14 +``` + +produces the same result as + +``` +datetimeAdd([Opened On], 14, "day") +``` + +Most spreadsheet tools require use different functions for different time units (for example, you'd use a different function to add "months" to a date). `datetimeAdd` makes it easy for you to convert all of those functions to a single consistent syntax. + +### Python + +Assuming the [coffee sample data](#calculating-an-end-date) is in a `pandas` dataframe column called `df`, you can import the `datetime` module and use the `timedelta` function: + +``` +df['Finish By'] = df['Opened On'] + datetime.timedelta(days=14) +``` + +is equivalent to + +``` +datetimeAdd([Opened On], 14, "day") +``` + +## Further reading + +- [Custom expressions documentation](../expressions) +- [Custom expressions tutorial](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) +- [Time series analysis](/learn/metabase-basics/querying-and-dashboards/time-series/start) diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/datetimediff.md b/_docs/doc-update-detection/questions/query-builder/expressions/datetimediff.md new file mode 100644 index 000000000..116d948ed --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/datetimediff.md @@ -0,0 +1,148 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: DatetimeDiff +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/datetimediff.md' +--- + +# DatetimeDiff + +`datetimeDiff` gets the amount of time between two datetime values, using the specified unit of time. Note that the difference is calculated in _whole_ units (see the example below). + +| Syntax | Example | +| -------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | +| `datetimeDiff(datetime1, datetime2, unit)` | `datetimeDiff("2022-02-01", "2022-03-01", "month")` | +| Gets the difference between two datetimes (datetime2 minus datetime 1) using the specified unit of time. | `1` | + +## Parameters + +`datetime1` and `datetime2` can be: + +- The name of a timestamp column, +- a custom expression that returns a [datetime](#accepted-data-types), or +- a string in the format `"YYYY-MM-DD"` or `"YYYY-MM-DDTHH:MM:SS"` (as shown in the example above). + +`unit` can be any of: + +- "year" +- "quarter" +- "month" +- "week" +- "day" +- "hour" +- "minute" +- "second" + +## Calculating age + +Let's say you're a cheesemaker, and you want to keep track of your ripening process: + +| Cheese | Aging Start | Aging End | Mature Age (Months) | +| ------------- | ---------------- | ---------------- | ------------------- | +| Provolone | January 19, 2022 | March 17, 2022 | 1 | +| Feta | January 25, 2022 | May 3, 2022 | 3 | +| Monterey Jack | January 27, 2022 | October 11, 2022 | 8 | + +**Mature Age (Months)** is a custom column with the expression: + +``` +datetimeDiff([Aging Start], [Aging End], "month") +``` + +To calculate the _current_ age of a cheese in months, you use [`now`](../expressions/now) as the second datetime parameter, like this: + +``` +datetimeDiff([Aging Start], now, "month") +``` + +To calculate the current age of a cheese in days, you'd use: + +``` +datetimeDiff([Aging Start], now, "day") +``` + +## Accepted data types + +| [Data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types) | Works with `datetimeDiff` | +| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | +| String | ❌ | +| Number | ❌ | +| Timestamp | ✅ | +| Boolean | ❌ | +| JSON | ❌ | + +We use "timestamp" and "datetime" to talk about any temporal data type that's supported by Metabase. For more info about these data types in Metabase, see [Timezones](../../../configuring-metabase/timezones#data-types). + +If your timestamps are stored as strings or numbers in your database, an admin can [cast them to timestamps](../../../data-modeling/metadata-editing#casting-to-a-specific-data-type) from the Table Metadata page. + +## Limitations + +`datetimeDiff` is currently unavailable for the following databases: + +- Druid + +## Related functions + +This section covers functions and formulas that work the same way as the Metabase `datetimeDiff` expression, with notes on how to choose the best option for your use case. + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +### SQL + +When you run a question using the [query builder](/glossary/query_builder), Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results. + +If our [cheese sample data](#calculating-age) is stored in a PostgreSQL database: + +```sql +SELECT DATE_PART('month', AGE(aging_end, aging_start)) AS mature_age_months +FROM cheese +``` + +is equivalent to the Metabase `datetimeDiff` expression: + +``` +datetimeDiff([Aging Start], [Aging End], "month") +``` + +Some databases, such as Snowflake and BigQuery, support functions like `DATEDIFF` or `DATE_DIFF`. For more info, check out our list of [common SQL reference guides](/learn/grow-your-data-skills/learn-sql/debugging-sql/sql-syntax#common-sql-reference-guides). + +### Spreadsheets + +If our [cheese sample data](#calculating-age) is in a spreadsheet where "Aging Start" is in column B and "Aging End" is in column C: + +``` +DATEDIF(B1, C1, "M") +``` + +produces the same result as + +``` +datetimeDiff([Aging Start], [Aging End], "month") +``` + +Yes, `DATEDIF` looks a bit wrong, but the spreadsheet function really is `DATEDIF()` with one "f", not `DATEDIFF()`. + +### Python + +Assuming the [cheese sample data](#calculating-age) is in a `pandas` dataframe column called `df`, you can subtract the dates directly and use `numpy`'s `timedelta64` to convert the difference to months: + +``` +df['Mature Age (Months)'] = (df['Aging End'] - df['Aging Start']) / np.timedelta64(1, 'M') +``` + +is equivalent to + +``` +datetimeDiff([Aging Start], [Aging End], "month") +``` + +## Further reading + +- [Custom expressions documentation](../expressions) +- [Custom expressions tutorial](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) +- [Time series analysis](/learn/metabase-basics/querying-and-dashboards/time-series/start) diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/datetimesubtract.md b/_docs/doc-update-detection/questions/query-builder/expressions/datetimesubtract.md new file mode 100644 index 000000000..6678a5aca --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/datetimesubtract.md @@ -0,0 +1,179 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: DatetimeSubtract +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/datetimesubtract.md' +--- + +# DatetimeSubtract + +`datetimeSubtract` takes a datetime value and subtracts some unit of time from it. You might want to use this function when working with time series data that's marked by a "start" and an "end", such as sessions or subscriptions data. + +| Syntax | Example | +| ----------------------------------------------------------------------------------------- | -------------------------------------------- | +| `datetimeSubtract(column, amount, unit)` | `datetimeSubtract("2021-03-25", 1, "month")` | +| Takes a timestamp or date value and subtracts the specified number of time units from it. | `2021-02-25` | + +## Parameters + +`column` can be any of: + +- The name of a timestamp column, +- a custom expression that returns a [datetime](#accepted-data-types), or +- a string in the format `"YYYY-MM-DD"` or `"YYYY-MM-DDTHH:MM:SS"` (as shown in the example above). + +`unit` can be any of: + +- "year" +- "quarter" +- "month" +- "day" +- "hour" +- "minute" +- "second" +- "millisecond" + +`amount`: + +- An integer. You cannot use fractional values. For example, you cannot subtract "half a year" (0.5). +- May be a negative number: `datetimeSubtract("2021-03-25", -1, "month")` will return `2021-04-25`. + +## Calculating a start date + +Let's say you're planning a fun night out. You know it takes 30 minutes to get from place to place, and you need to figure out what time you have to leave to get to each of your reservations: + +| Event | Arrive By | Depart At | +| ------- | -------------------------- | -------------------------- | +| Drinks | November 12, 2022 6:30 PM | November 12, 2022 6:00 PM | +| Dinner | November 12, 2022 8:00 PM | November 12, 2022 7:30 PM | +| Dancing | November 13, 2022 12:00 AM | November 12, 2022 11:30 PM | + +Here, **Depart At** is a custom column with the expression: + +``` +datetimeSubtract([Arrive By], 30, "minute") +``` + +## Checking if the current datetime is within an interval + +Say you want to check if the current datetime falls between a [start date](#calculating-a-start-date) and an end date. Assume the "current" datetime is November 12, 7:45 PM. + +| Event | Arrive By | Depart At | On My Way | +| ------- | -------------------------- | -------------------------- | --------- | +| Drinks | November 12, 2022 6:30 PM | November 12, 2022 6:00 PM | No | +| Dinner | November 12, 2022 8:00 PM | November 12, 2022 7:30 PM | Yes | +| Dancing | November 13, 2022 12:00 AM | November 12, 2022 11:30 PM | No | + +**Depart At** is a custom column with the expression: + +``` +datetimeSubtract([Arrive By], 30, "minute") +``` + +**On My Way** uses [case](../expressions/case) to check if the current datetime ([now](../expressions/now)) is [between](../expressions-list#between) the datetimes in **Arrive By** and **Depart At**: + +``` +case(between(now, [Depart At], [Arrive By]), "Yes", "No") +``` + +## Accepted data types + +| [Data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types) | Works with `datetimeSubtract` | +| ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- | +| String | ❌ | +| Number | ❌ | +| Timestamp | ✅ | +| Boolean | ❌ | +| JSON | ❌ | + +We use "timestamp" and "datetime" to talk about any temporal data type that's supported by Metabase. For more info about these data types in Metabase, see [Timezones](../../../configuring-metabase/timezones#data-types). + +If your timestamps are stored as strings or numbers in your database, an admin can [cast them to timestamps](../../../data-modeling/metadata-editing#casting-to-a-specific-data-type) from the Table Metadata page. + +## Limitations + +If you're using MongoDB, `datetimeSubtract` will only work on versions 5 and up. + +## Related functions + +This section covers functions and formulas that work the same way as the Metabase `datetimeSubtract` expression, with notes on how to choose the best option for your use case. + +**[Metabase expressions](../expressions-list)** + +- [datetimeAdd](#datetimeadd) + +**Other tools** + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +### datetimeAdd + +`datetimeSubtract` and `datetimeAdd` are interchangeable, since you can use a negative number for `amount`. We could use either expression for our [events example](#calculating-a-start-date), but you should try to avoid "double negatives" (such as subtracting a negative number). + +``` +datetimeAdd([Arrive By], -30, "minute") +``` + +does the same thing as + +``` +datetimeSubtract([Arrive By], 30, "minute") +``` + +### SQL + +When you run a question using the [query builder](/glossary/query_builder), Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results. + +If our [events sample data](#calculating-a-start-date) is stored in a PostgreSQL database: + +```sql +SELECT arrive_by - INTERVAL '30 minutes' AS depart_at +FROM events +``` + +is equivalent to the Metabase `datetimeSubtract` expression: + +``` +datetimeSubtract([Arrive By], 30, "minute") +``` + +### Spreadsheets + +Assuming the [events sample data](#calculating-a-start-date) is in a spreadsheet where "Arrive By" is in column A with a datetime format, the spreadsheet function + +``` +A:A - 30/(60*24) +``` + +produces the same result as + +``` +datetimeSubtract([Arrive By], 30, "minute") +``` + +Most spreadsheets require you to use different calculations for different time units (for example, you'd need to use a different calculation to subtract "days" from a date). `datetimeSubtract` makes it easy for you to convert all of those functions to a single consistent syntax. + +### Python + +If our [events sample data](#calculating-a-start-date) is in a `pandas` dataframe column called `df`, you can import the `datetime` module and use the `timedelta` function: + +``` +df['Depart At'] = df['Arrive By'] - datetime.timedelta(minutes=30) +``` + +is equivalent to + +``` +datetimeSubtract([Arrive By], 30, "minute") +``` + +## Further reading + +- [Custom expressions documentation](../expressions) +- [Custom expressions tutorial](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) +- [Time series analysis](/learn/metabase-basics/querying-and-dashboards/time-series/start) diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/in.md b/_docs/doc-update-detection/questions/query-builder/expressions/in.md new file mode 100644 index 000000000..af65e4569 --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/in.md @@ -0,0 +1,69 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: In +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/in.md' +--- + +# In + +`in` compares values and returns true if `value1` equals `value2` (OR `value3`, etc., if specified). + +## Syntax + +``` +in(value1, value2, ...) +``` + +`value1` is the column or value to check. + +`value2, ...` is the list of columns or values to check. + +Metabase will return rows where the `value1` equals `value2` OR `value3`, etc. Matches must be exact (e.g., strings are case sensitive). + +For example, + +``` +in([Category], "Gadget", "Widget") +``` +would return rows where `[Category]` is either `Gadget` or `Widget`. + + +You can choose multiple columns. For example, let's say you wanted to find records where `[Title]` or `[Category]` fields are equal to `Gadget`. You could write: + +``` +in("Gadget", [Title], [Category]) +``` + +## Related functions + +### SQL + +`in` works like SQL's `in` function. + +So if you have the expression: `in[title], "Lightweight Wool Computer", "Aerodynamic Cotton Lamp")`, in SQL, it would be: + +```sql +title IN ('Lightweight Wool Computer', 'Aerodynamic Cotton Lamp') +``` + +But under the hood, Metabase translates this `IN` expression to a `WHERE` clause that uses the `OR` operator: + +```sql +WHERE + title = 'Lightweight Wool Computer' + OR title = 'Aerodynamic Cotton Lamp' +``` + +## Accepted data types + +| Data type | Works with `in` | +| --------- | --------------- | +| String | ✅ | +| Number | ✅ | +| Timestamp | ❌ | +| Boolean | ✅ | +| JSON | ❌ | diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/isempty.md b/_docs/doc-update-detection/questions/query-builder/expressions/isempty.md new file mode 100644 index 000000000..f69774221 --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/isempty.md @@ -0,0 +1,144 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Isempty +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/isempty.md' +--- + +# Isempty + +`isempty` checks whether a value in a **string column** is an empty string (`""`) or null. Calling `isempty` on a non-string column would cause an error. + +## Syntax + +``` +isempty(text column) +``` + +You can use `isempty` in [custom filters](../expressions#filter-expressions-and-conditionals), or as the condition for conditional aggregations [`CountIf`](../expressions/countif) and [`SumIf`](../expressions/sumif). To create a custom column using `isempty`, you must combine `isempty` with another function that accepts boolean values, like [`case`](./case). + +## How Metabase handles empty strings and null values + +In Metabase, columns with string [data types][data-types] will display blank cells for empty strings, strings of whitespace characters, _or_ `null` values (if the column is nullable in your database). +The table below shows you examples of the output of `isempty`. + +| Metabase shows | Database value | `isempty(value)` | +| -------------- | ------------------- | ---------------- | +| | `null` | `true` | +| | `""` (empty string) | `true` | +| | `" "` (whitespace) | `false` | +| kitten | `"kitten"` | `false` | + +## Creating a boolean custom column + +To create a custom column using `isempty`, you must combine `isempty` with another function. +For example, if you want to create a custom column that contains `true` when the `Feedback` column is empty or null, and `false` otherwise, you can use the [`case expression`](./case) : + +``` +case(isempty([Feedback]), true, false) +``` + +## Replacing empty strings with another value + +You can combine `isempty` with the [`case` expression](./case) to replace empty strings with something more descriptive. + +For example, you can create a new custom column that will contain `"No feedback"` when the original `[Feedback]` column is empty or null, and the feedback value when `[Feedback]` is has a non-empty value. The custom expression to do it is: + +``` +case(isempty([Feedback]), "No feedback.", [Feedback]) +``` + +| Feedback | `case(isempty([Feedback]), "No feedback.", [Feedback])` | +| ---------------------- | ------------------------------------------------------- | +| `""` | `"No feedback."` | +| `null` | `"No feedback."` | +| `"I like your style."` | `"I like your style."` | + +## Accepted data types + +| [Data type][data-types] | Works with `isempty` | +| ----------------------- | -------------------- | +| String | ✅ | +| Number | ❌ | +| Timestamp | ❌ | +| Boolean | ❌ | +| JSON | ❌ | + +## Limitations + +- To create a custom column you must combine `isempty` with another expression that accepts boolean arguments (i.e., `true` or `false`). +- `isempty` only accepts one value at a time. If you need to deal with empty strings from multiple columns, you'll need to use multiple `isempty` expressions with the [case expression](./case). + +## Related functions + +This section covers functions and formulas that can be used interchangeably with the Metabase `isempty` expression, with notes on how to choose the best option for your use case. + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +All examples below use the table from the [Replacing empty strings](#replacing-empty-strings-with-another-value) example: + +| Feedback | `case(isempty([Feedback]), "No feedback.", [Feedback])` | +| ---------------------- | ------------------------------------------------------- | +| `""` | `"No feedback."` | +| `null` | `"No feedback."` | +| `"I like your style."` | `"I like your style."` | + +### SQL + +In most cases (unless you're using a NoSQL database), questions created from the [query builder][notebook-editor-def] are converted into SQL queries that run against your database or data warehouse. + +```sql +CASE WHEN (Feedback = "" OR Feedback IS NULL) THEN "No feedback" + ELSE Feedback END +``` + +is equivalent to the Metabase `isempty` expression: + +``` +case(isempty([Feedback]), "No feedback.", [Feedback]) +``` + +### Spreadsheets + +If our sample [feedback column](#replacing-empty-strings-with-another-value) is in a spreadsheet where "Feedback" is in column A, then the formula + +``` +=IF(A2 = "", "Unknown feedback.", A2) +``` + +is equivalent to the Metabase `isempty` expression: + +``` +case(isempty([Feedback]), "No feedback.", [Feedback]) +``` + +### Python + +Assuming the sample [feedback column](#replacing-empty-strings-with-another-value) is in a dataframe column called `df["Feedback"]`: + +```python +df["Custom Column"] = np.where((df["Feedback"] == "") | (df["Feedback"].isnull()), "No feedback.", df["Feedback"]) +``` + +is equivalent to the Metabase `isempty` expression: + +``` +case(isempty([Feedback]), "No feedback.", [Feedback]) +``` + +## Further reading + +- [Custom expressions documentation][custom-expressions-doc] +- [Custom expressions tutorial][custom-expressions-learn] + +[custom-expressions-doc]: ../expressions +[custom-expressions-learn]: /learn/metabase-basics/querying-and-dashboards/questions/custom-expressions +[data-types]: /learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types +[notebook-editor-def]: /glossary/query_builder +[numpy]: https://numpy.org/doc/ +[pandas]: https://pandas.pydata.org/pandas-docs/stable/ diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/isnull.md b/_docs/doc-update-detection/questions/query-builder/expressions/isnull.md new file mode 100644 index 000000000..3d7df36fa --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/isnull.md @@ -0,0 +1,152 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Isnull +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/isnull.md' +--- + +# Isnull + +`isnull` checks if a value is a `null`, a special kind of placeholder that's used by a database when something is missing or unknown. + +## Syntax + +``` +isnull(text column) +``` + +You can use `isnull` in [custom filters](../expressions#filter-expressions-and-conditionals), or as the condition for conditional aggregations [`CountIf`](../expressions/countif) and [`SumIf`](../expressions/sumif). To create a custom column using `isnull`, you must combine `isnull` with another function that accepts boolean values, like [`case`](./case). + +## How Metabase handles nulls + +In Metabase tables, `null`s are displayed as blank cells. Additionally, for string columns, empty strings and strings containing only whitespace characters will be displayed as blank as well. + +The table below shows you examples of the output of `isnull`. + +| Metabase shows | Database value | `isnull(value)` | +| -------------- | ------------------- | --------------- | +| | `null` | `true` | +| | `""` (empty string) | `false`\* | +| | `" "` (whitespace) | `false` | +| kitten | `"kitten"` | `false` | + +\*In Oracle and Vertica databases, empty strings are treated as nulls instead. + +## Creating a boolean custom column + +To create a custom column using `isnull`, you must combine `isnull` with another function. +For example, if you want to create a custom column that contains `true` when the `Discount` column is null, and `false` otherwise, you can use the [`case expression`](./case) : + +``` +case(isnull([Discount]), true, false) +``` + +## Replacing null values with another value + +Combine `isnull` with the [`case` expression](./case) to replace missing information with something more descriptive: + +For example, you can create a new custom column that will contain `"Unknown feedback"` when the original `[Feedback]` column is null, and the actual feedback value when `[Feedback]` is has a value. The custom expression to do it is: + +``` +case(isnull([Feedback]), "Unknown feedback.", [Feedback]) +``` + +| Feedback | `case(isnull([Feedback]), "Unknown feedback.", [Feedback])` | +| ---------------------- | ----------------------------------------------------------- | +| `null` | `"Unknown feedback."` | +| `""` | `""` | +| `"I like your style."` | `"I like your style."` | + +## Accepted data types + +| [Data type][data-types] | Works with `isnull` | +| ----------------------- | ------------------- | +| String | ✅ | +| Number | ✅ | +| Timestamp | ✅ | +| Boolean | ✅ | +| JSON | ✅ | + +## Limitations + +- In Metabase, you must combine `isnull` with another expression that accepts boolean arguments (i.e., `true` or `false`). +- `isnull` only accepts one value at a time. If you need to deal with blank cells across multiple columns, see the [coalesce expression](./coalesce). +- If `isnull` doesn't seem to do anything to your blank cells, you might have empty strings. Try the [`isempty` expression](./isempty) instead. + +## Related functions + +This section covers functions and formulas that can be used interchangeably with the Metabase `isnull` expression, with notes on how to choose the best option for your use case. + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +All examples below use the table from the [Replacing null values](#replacing-null-values-with-another-value) example: + +| Feedback | `case(isnull([Feedback]), "Unknown feedback.", [Feedback])` | +| ---------------------- | ----------------------------------------------------------- | +| `null` | `"Unknown feedback."` | +| `""` | `""` | +| `"I like your style."` | `"I like your style."` | + +### SQL + +In most cases (unless you're using a NoSQL database), questions created from the [query builder][notebook-editor-def] are converted into SQL queries that run against your database or data warehouse. + +```sql +CASE WHEN Feedback IS NULL THEN "Unknown feedback", + ELSE Feedback END +``` + +is equivalent to the Metabase `isnull` expression: + +``` +case(isnull([Feedback]), "Unknown feedback.", [Feedback]) +``` + +### Spreadsheets + +Spreadsheet `#N/A`s are the equivalent of database `null`s (placeholders for "unknown" or "missing" information). + +Assuming our sample [feedback column](#replacing-null-values-with-another-value) is in a spreadsheet where "Feedback" is in column A, then the formula + +``` +=IF(ISNA(A2), "Unknown feedback.", A2) +``` + +is equivalent to the Metabase `isnull` expression: + +``` +case(isnull([Feedback]), "Unknown feedback.", [Feedback]) +``` + +### Python + +[Numpy][numpy] and [pandas][pandas] use `NaN`s or `NA`s instead of `null`s. + +Assuming our sample [feedback column](#replacing-null-values-with-another-value) is in a dataframe column called `df["Feedback"]`: + +``` +df["Custom Column"] = np.where(df["Feedback"].isnull(), "Unknown feedback.", df["Feedback"]) +``` + +is equivalent to the Metabase `isnull` expression: + +``` +case(isnull([Feedback]), "Unknown feedback.", [Feedback]) +``` + +## Further reading + +- [Custom expressions documentation][custom-expressions-doc] +- [Custom expressions tutorial][custom-expressions-learn] + +[custom-expressions-doc]: ../expressions +[custom-expressions-learn]: /learn/metabase-basics/querying-and-dashboards/questions/custom-expressions +[data-types]: /learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types +[notebook-editor-def]: /glossary/query_builder +[numpy]: https://numpy.org/doc/ +[pandas]: https://pandas.pydata.org/pandas-docs/stable/ diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/now.md b/_docs/doc-update-detection/questions/query-builder/expressions/now.md new file mode 100644 index 000000000..50082e43e --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/now.md @@ -0,0 +1,113 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Now +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/now.md' +--- + +# Now + +`now` returns the current datetime using your Metabase [report timezone](../../../configuring-metabase/localization#report-timezone). + +## Creating conditional logic using the current date or time + +Let's say you have some project data, and you want to add a status column for each task. We'll assume today's date and time is November 22, 2022, 12:00:00. + +| Task | Start | Deadline | Status | +| ------ | --------------------------- | --------------------------- | --------------- | +| Draft | November 1, 2022, 12:00:00 | November 30, 2022, 12:00:00 | In progress | +| Review | November 15, 2022, 12:00:00 | November 19, 2022, 12:00:00 | Needs extension | +| Edit | November 22, 2022, 12:00:00 | November 22, 2022, 12:00:00 | DUE RIGHT NOW! | + +To mark a task in progress, you'd use the expression: + +``` +now >= [Start] AND now < [Deadline] +``` + +To check if you need to ask for an extension: + +``` +now >= [Start] AND now >= [Deadline] +``` + +If you're looking for an adrenaline rush (and you have real-time data), you can flag the tasks that are due _right this second_: + +``` +now = [Deadline] +``` + +To set up the **Status** column that combines all three situations above, you'd wrap everything in a `case` expression: + +``` +case(now >= [Start] AND now < [Deadline], "In progress", + now >= [Start] AND now >= [Deadline], "Needs extension", + now = [Deadline], "DUE RIGHT NOW!") +``` + +## Data types + +| [Data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types) | Returned by `now` | +| ------------------------------------------------------------------------------------------------------------------------------ | ----------------- | +| String | ❌ | +| Number | ❌ | +| Timestamp | ✅ | +| Boolean | ❌ | +| JSON | ❌ | + +`now` returns a `timestamp with time zone` if time zones are supported by your database, otherwise `now` returns a `timestamp without time zone`. + +For more info about the way these data types behave in Metabase, see [Timezones](../../../configuring-metabase/timezones#data-types). + +## Limitations + +`now` might not actually be _now_ (in your local time) if you don't live in the same timezone as your Metabase [report time zone](../../../configuring-metabase/localization#report-timezone). + +If you need to compare `now` to a column in a different time zone, use [convertTimezone](./converttimezone) to shift both columns into the same time zone. For example: + +``` +convertTimezone(now, 'UTC', ) >= convertTimezone([Deadline], 'UTC', ) +``` + +## Related functions + +Different ways to do the same thing, because while you'd love to use custom expressions more, now's just not the time. + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +### SQL + +When you run a question using the [query builder](/glossary/query_builder), Metabase will convert your query builder settings (filters, summaries, etc.) into a SQL query, and run that query against your database to get your results. + +By default, `now` uses your Metabase's [report time zone](../../../configuring-metabase/localization#report-timezone). If your admin hasn't set a report time zone, `now` will use your database's time zone. + +Say you're using a Postgres database. If your Metabase report time zone is set to EST, you'll get `now` in EST: + +```sql +SELECT CURRENT_TIMESTAMP AT TIME ZONE 'EST' +``` + +If you don't have a report time zone, you'll get `now` in the Postgres database's time zone (typically UTC): + +```sql +SELECT CURRENT_TIME +``` + +### Spreadsheets + +The spreadsheet function `NOW()` gets the current date and time in your operating system's time zone (the time that's on your computer or mobile device). + +### Python + +You can use `pd.Timestamp.now()` using the `pandas` module. This will give you a `Timestamp` object with the current date and time in your operating system's time zone. + +## Further reading + +- [Custom expressions documentation](../expressions) +- [Custom expressions tutorial](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) +- [Time series analysis](/learn/metabase-basics/querying-and-dashboards/time-series/start) diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/offset.md b/_docs/doc-update-detection/questions/query-builder/expressions/offset.md new file mode 100644 index 000000000..ef090fb5f --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/offset.md @@ -0,0 +1,140 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Offset +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/offset.md' +--- + +# Offset + +> ⚠️ The `Offset` function is currently unavailable for MySQL/MariaDB, MongoDB, and Druid. + +The `Offset` function returns the value of an expression in a different row. `Offset` can only be used in the query builder's Summarize step (you cannot use `Offset` to create a custom column). + +Syntax: `Offset(expression, rowOffset)` + +The `expression` is the value to get from a different row. + +The `rowOffset` is the number relative to the current row. For example, `-1` for the previous row, or `1` for the next row. + +Example: `Offset(Sum([Total]), -1)` would get the value of `Sum([Total])` from the previous row. + +## The order of the breakouts matter + +Because `Offset` refers to other rows, the order of the breakouts matters (the breakouts are the groups in the "Group By" section in the Summarization step). Metabase will sort by the first group, then partition by any additional breakouts. For example, if you want to see the counts of orders by product category over time, and the counts by product category for the previous period, you should first group by `Created At`, then by the product category. + +## Offset doesn't account for missing data + +`Offset` can only reference the rows you _have_, which means it can produce correct but unexpected results. For example, let's say you want to compare each _day's_ count to the previous day. + +Take the following table, where the `Previous` column is created by the expression `Offset(Count, -1)`: + +| Date | Count | Previous | +| -------- | ----- | -------- | +| 1-Oct-22 | 6 | | +| 2-Oct-22 | 3 | 6 | +| 4-Oct-22 | 2 | 3 | + +The value in the `Previous` column for October 4th is `3`, which is the value of the previous row. While correct based on the data, the previous row is October _2nd_; there's no data for the previous _day_, October 3rd. If you want to use offset to compare previous _days_ (or weeks, or whatever), you need to make sure that your data includes a row for each data point you want to compare. In this case, your data would need to include a row for each day, including days where the count was zero. If you're missing dates in your data, you could join a calendar table to your data to make sure that each day has a row in your data. + +## Data types + +The `Offset` function returns whatever value is in the offset row. + +| [Data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types) | Returned by `Offset` | +| ------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| String | ✅ | +| Number | ✅ | +| Timestamp | ✅ | +| Boolean | ✅ | +| JSON | ✅ | + +## Example year-over-year (YoY) time series comparison using `Offset` + +In the Sample database, you can use `Offset` to compare the count of orders year over year (YoY). + +First, summarize by Sum of Total. Then summarize that summation again, this time using `Offset` to grab the previous row's value. + +``` +Offset(Sum([Total]), -1) +``` + +Then group the results by `Created At` by year: + +![Comparing year over year](../../images/sum-of-totals-for-previous-period.png) + +Which yields: + +![Year over year order sum of order totals](../../images/year-over-year-sum-totals.png) + +With these offsets (the Sums in the "Previous period" column), we can then create [custom columns](../editor#custom-columns) to calculate things like the difference between yearly Sums: + +``` +[Sum of total] - [Previous period] +``` + +And the percentage change year to year: + +``` +[Difference] / [Previous period] * 100 +``` + +![Difference and percentage change](../../images/diff-and-percentage.png) + +## Example rolling average using `Offset` + +You can use a custom expression with `Offset` to calculate rolling averages. + +For example, let's say you want to calculate the rolling average sum of order totals over the past three months. You could create a custom expression to calculate these rolling averages: + +``` +(Sum([Total]) + Offset(Sum([Total]), -1) + Offset(Sum([Total]), -2)) / 3 +``` + +The above expression adds up this period's total, plus the totals for the previous two periods (offset by `-1` and `-2`), and then divides by three to get the average across those periods. + +![Rolling average](../../images/rolling-average.png) + +## Related functions + +### SQL + +The `Offset` function compares with SQL's `LAG` and `LEAD` window functions. + +For example, if you're trying to create a line chart with two series to compare a) this month's order counts with b) the previous month's order counts, you'd `count` the orders for this month, then use an `offset` expression to count the previous month's orders, like so: + +``` +Offset(count, -1) +``` + +Under the hood, Metabase will translate that `Offset` expression into a `LAG` window function, like in this query: + +```sql +SELECT + "source"."CREATED_AT" AS "CREATED_AT", + COUNT(*) AS "count", + LAG(COUNT(*), 1) OVER ( + +ORDER BY + "source"."CREATED_AT" ASC + ) AS "Order count previous period" +FROM + ( + SELECT + DATE_TRUNC('month', "PUBLIC"."ORDERS"."CREATED_AT") AS "CREATED_AT" + FROM + "PUBLIC"."ORDERS" + ) AS "source" +GROUP BY + "source"."CREATED_AT" +ORDER BY + "source"."CREATED_AT" ASC +``` + +## Further reading + +- [Custom expressions documentation](../expressions) +- [Custom expressions tutorial](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/regexextract.md b/_docs/doc-update-detection/questions/query-builder/expressions/regexextract.md new file mode 100644 index 000000000..99a7eae84 --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/regexextract.md @@ -0,0 +1,148 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Regexextract +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/regexextract.md' +--- + +# Regexextract + +> ⚠️ `regexextract` is unavailable for MongoDB, SQLite, and SQL Server. For Druid, `regexextract` is only available for the Druid-JDBC driver. + +`regexextract` uses [regular expressions (regex)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) to get a specific part of your text. + +`regexextract` is ideal for text that has little to no structure, like URLs or freeform survey responses. If you're working with strings in predictable formats like SKU numbers, IDs, or other types of codes, check out the simpler [substring](../expressions/substring) expression instead. + +Use `regexextract` to create custom columns with shorter, more readable labels for things like: + +- filter dropdown menus, +- chart labels, or +- embedding parameters. + +| Syntax | Example | +| ------------------------------------------------------------- | ---------------------------------------- | +| `regexextract(text, regular_expression)` | `regexextract("regexextract", "ex(.*)")` | +| Gets a specific part of your text using a regular expression. | "extract" | + +## Searching and cleaning text + +Let's say that you have web data with a lot of different URLs, and you want to map each URL to a shorter, more readable campaign name. + +| URL | Campaign Name | +| ----------------------------------------------------- | ------------- | +| https://www.metabase.com/docs/?utm_campaign=alice | alice | +| https://www.metabase.com/learn/?utm_campaign=neo | neo | +| https://www.metabase.com/glossary/?utm_campaign=candy | candy | + +You can create a custom column **Campaign Name** with the expression: + +``` +regexextract([URL], "^[^?#]+\?utm_campaign=(.*)") +``` + +Here, the regex pattern [`^[^?#]+\?` matches all valid URL strings](https://www.oreilly.com/library/view/regular-expressions-cookbook/9780596802837/ch07s13.html). You can replace `utm_campaign=` with whatever query parameter you like. At the end of the regex pattern, the [capturing group](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Backreferences) `(.*)` gets all of the characters that appear after the query parameter `utm_campaign=`. + +Now, you can use **Campaign Name** in places where you need clean labels, such as [filter dropdown menus](../../../dashboards/filters), [charts](../../visualizations/visualizing-results), and [embedding parameters](../../../embedding/static-embedding-parameters). + +## Accepted data types + +| [Data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types) | Works with `regexextract` | +| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | +| String | ✅ | +| Number | ❌ | +| Timestamp | ❌ | +| Boolean | ❌ | +| JSON | ❌ | + +## Limitations + +`regexextract` is unavailable for MongoDB, SQLite, and SQL Server. For Druid, `regexextract` is only available for the Druid-JDBC driver. + +Regex can be a dark art. You have been warned. + +## Related functions + +This section covers functions and formulas that work the same way as the Metabase `regexextract` expression, with notes on how to choose the best option for your use case. + +**[Metabase expressions](../expressions-list)** + +- [substring](#substring) + +**Other tools** + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +### Substring + +Use [substring](../expressions/substring) when you want to search text that has a consistent format (the same number of characters, and the same relative order of those characters). + +For example, you wouldn't be able to use `substring` to get the query parameter from the [URL sample data](#searching-and-cleaning-text), because the URL paths and the parameter names both have variable lengths. + +But if you wanted to pull out everything after `https://www.` and before `.com`, you could do that with either: + +``` +substring([URL], 13, 8) +``` + +or + +``` +regexextract([URL], "^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/.\n]+)") +``` + +### SQL + +When you run a question using the [notebook editor](/glossary/notebook_editor), Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results. + +If our [sample data](#searching-and-cleaning-text) is stored in a PostgreSQL database: + +```sql +SELECT + url, + SUBSTRING(url, '^[^?#]+\?utm_campaign=(.*)') AS campaign_name +FROM follow_the_white_rabbit +``` + +is equivalent to the Metabase `regexextract` expression: + +``` +regexextract([URL], "^[^?#]+\?utm_campaign=(.*)") +``` + +### Spreadsheets + +If our [sample data](#searching-and-cleaning-text) is in a spreadsheet where "URL" is in column A, the spreadsheet function + +``` +regexextract(A2, "^[^?#]+\?utm_campaign=(.*)") +``` + +uses pretty much the same syntax as the Metabase expression: + +``` +regexextract([URL], "^[^?#]+\?utm_campaign=(.*)") +``` + +### Python + +Assuming the [sample data](#searching-and-cleaning-text) is in a dataframe column called `df`, + +``` +df['Campaign Name'] = df['URL'].str.extract(r'^[^?#]+\?utm_campaign=(.*)') +``` + +does the same thing as the Metabase `regexextract` expression: + +``` +regexextract([URL], "^[^?#]+\?utm_campaign=(.*)") +``` + +## Further reading + +- [Custom expressions documentation](../expressions) +- [Custom expressions tutorial](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/substring.md b/_docs/doc-update-detection/questions/query-builder/expressions/substring.md new file mode 100644 index 000000000..e3a45ff1f --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/substring.md @@ -0,0 +1,158 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Substring +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/substring.md' +--- + +# Substring + +`substring` extracts part of some text. This function is useful for cleaning up text (or any value with a [string data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types)) that has a consistent format. + +For example, `substring` should work well on strings like SKU numbers, ISO codes, and standardized email addresses. + +| Syntax | Example | +| ------------------------------------------------------------------------------------------------ | -------------------------------------- | +| `substring(text, position, length)` | `substring("user_id@email.com", 1, 7)` | +| Extracts part of the text given a starting point (position) and a length (number of characters). | "user_id" | + +## Parameters + +- The first character in your string is at position 1. +- The length of your substring should always be a positive number. + +## Getting a substring from the left + +| Mission ID | Agent | +| ----------- | ----- | +| 19951113006 | 006 | +| 20061114007 | 007 | +| 19640917008 | 008 | + +**Agent** is a custom column with the expression: + +``` +substring([Mission ID], 9, 3) +``` + +## Getting a substring from the right + +Instead of using a number for the position, you'll use the formula + +``` +1 + length([column]) - position_from_right +``` + +where `position_from_right` is the number of characters you want to count from right to left. + +| Mission ID | Agent | +| ----------- | ----- | +| 19951113006 | 006 | +| 20061114007 | 007 | +| 19640917008 | 008 | + +Here, **Agent** is a custom column with the expression: + +``` +substring([Mission ID], (1 + length([Mission ID]) - 3), 3) +``` + +## Accepted data types + +| [Data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types) | Works with `substring` | +| ------------------------------------------------------------------------------------------------------------------------------ | ---------------------- | +| String | ✅ | +| Number | ❌ | +| Timestamp | ❌ | +| Boolean | ❌ | +| JSON | ❌ | + +## Limitations + +`substring` extracts text by counting a fixed number of characters. If you need to extract text based on some more complicated logic, try [`regexextract`](../expressions-list#regexextract). + +And if you only need to clean up extra whitespace around your text, you can use the [`trim`](../expressions-list#trim), [`ltrim`](../expressions-list#ltrim), or [`rtrim`](../expressions-list#rtrim) expressions instead. + +## Related functions + +This section covers functions and formulas that work the same way as the Metabase `substring` expression, with notes on how to choose the best option for your use case. + +**[Metabase expressions](../expressions-list)** + +- [regexextract](#regexextract) + +**Other tools** + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +### Regexextract + +Use [regexextract](./regexextract) if you need to extract text based on more specific rules. For example, you could get the agent ID with a regex pattern that finds the last occurrence of "00" (and everything after it): + +``` +regexextract([Mission ID], ".+(00.+)$") +``` + +should return the same result as + +``` +substring([Mission ID], 9, 3) +``` + +### SQL + +When you run a question using the [notebook editor](/glossary/notebook_editor), Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results. + +If our [sample data](#getting-a-substring-from-the-left) is stored in a PostgreSQL database: + +```sql +SELECT + mission_id, + SUBSTRING(mission_id, 9, 3) AS agent +FROM + this_message_will_self_destruct; +``` + +is equivalent to the Metabase `substring` expression: + +``` +substring([Mission ID], 9, 3) +``` + +### Spreadsheets + +If our [sample data](#getting-a-substring-from-the-left) is in a spreadsheet where "Mission ID" is in column A, + +``` +=mid(A2,9,3) +``` + +is the same as the Metabase `substring` expression: + +``` +substring([Mission ID], 9, 3) +``` + +### Python + +Assuming the [sample data](#getting-a-substring-from-the-left) is in a dataframe column called `df`, + +``` +df['Agent'] = df['Mission ID'].str.slice(8, 11) +``` + +does the same thing as the Metabase `substring` expression: + +``` +substring([Mission ID], 9, 3) +``` + +## Further reading + +- [Custom expressions documentation](../expressions) +- [Custom expressions tutorial](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/sumif.md b/_docs/doc-update-detection/questions/query-builder/expressions/sumif.md new file mode 100644 index 000000000..40cafa9cb --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/sumif.md @@ -0,0 +1,283 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: SumIf +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/sumif.md' +--- + +# SumIf + +`SumIf` adds up the values in a column based on a condition. + +Syntax: `SumIf(column, condition)`. + +Example: in the table below, `SumIf([Payment], [Plan] = "Basic")` would return 200. + +| Payment | Plan | +| ------- | -------- | +| 100 | Basic | +| 100 | Basic | +| 200 | Business | +| 200 | Business | +| 400 | Premium | + +> [Aggregation formulas](../expressions-list#aggregations) like `sumif` should be added to the query builder's [**Summarize** menu](../../query-builder/summarizing-and-grouping) > **Custom Expression** (scroll down in the menu if needed). + +## Parameters + +- `column` can be the name of a numeric column, or a [function](../expressions-list#functions) that returns a numeric column. +- `condition` is a [function](../expressions-list#functions) or [conditional statement](../expressions#conditional-operators) that returns a boolean value (`true` or `false`), like the conditional statement `[Payment] > 100`. + +## Multiple conditions + +We'll use the following sample data to show you `SumIf` with [required](#required-conditions), [optional](#optional-conditions), and [mixed](#some-required-and-some-optional-conditions) conditions. + +| Payment | Plan | Date Received | +| ------- | -------- | ---------------- | +| 100 | Basic | October 1, 2020 | +| 100 | Basic | October 1, 2020 | +| 200 | Business | October 1, 2020 | +| 200 | Business | November 1, 2020 | +| 400 | Premium | November 1, 2020 | + +### Required conditions + +To sum a column based on multiple required conditions, combine the conditions using the `AND` operator: + +``` +SumIf([Payment], ([Plan] = "Basic" AND month([Date Received]) = 10)) +``` + +This expression would return 200 on the sample data above: the sum of all of the payments received for Basic Plans in October. + +### Optional conditions + +To sum a column with multiple optional conditions, combine the conditions using the `OR` operator: + +``` +SumIf([Payment], ([Plan] = "Basic" OR [Plan] = "Business")) +``` + +Returns 600 on the sample data. + +### Some required and some optional conditions + +To combine required and optional conditions, group the conditions using parentheses: + +``` +SumIf([Payment], ([Plan] = "Basic" OR [Plan] = "Business") AND month([Date Received]) = 10) +``` + +Returns 400 on the sample data. + +> Tip: make it a habit to put parentheses around your `AND` and `OR` groups to avoid making required conditions optional (or vice versa). + +## Conditional subtotals by group + +To get a conditional subtotal for a category or group, such as the total payments per plan, you'll: + +1. Write a `sumif` formula with your conditions. +2. Add a [**Group by**](../../query-builder/summarizing-and-grouping) column in the query builder. + +| Payment | Plan | Date Received | +| ------- | -------- | ---------------- | +| 100 | Basic | October 1, 2020 | +| 100 | Basic | October 1, 2020 | +| 200 | Business | October 1, 2020 | +| 200 | Business | November 1, 2020 | +| 400 | Premium | November 1, 2020 | + +To sum payments for the Business and Premium plans: + +``` +SumIf([Payment], [Plan] = "Business" OR [Plan] = "Premium") +``` + +Or, sum payments for all plans that aren't "Basic": + +``` +SumIf([Payment], [Plan] != "Basic") +``` + +> The "not equal" operator `!=` should be written as !=. + +To view those payments by month, set the **Group by** column to "Date Received: Month". + +| Date Received: Month | Total Payments for Business and Premium Plans | +| -------------------- | --------------------------------------------- | +| October | 200 | +| November | 600 | + +> Tip: when sharing your work with other people, it's helpful to use the `OR` filter, even though the `!=` filter is shorter. The inclusive `OR` filter makes it easier to understand which categories (e.g., plans) are included in the sum. + +## Accepted data types + +| [Data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview#examples-of-data-types) | Works with `SumIf` | +| ------------------------------------------------------------------------------------------------------------------------------ | ------------------ | +| String | ❌ | +| Number | ✅ | +| Timestamp | ❌ | +| Boolean | ✅ | +| JSON | ❌ | + +See [parameters](#parameters). + +## Related functions + +Different ways to do the same thing, because CSV files still make up 40% of the world's data. + +**Metabase** + +- [case](#case) +- [CumulativeSum](#cumulativesum) + +**Other tools** + +- [SQL](#sql) +- [Spreadsheets](#spreadsheets) +- [Python](#python) + +### case + +You can combine [`Sum`](../expressions-list#sum) and [`case`](./case): + +``` +Sum(case([Plan] = "Basic", [Payment])) +``` + +to do the same thing as `SumIf`: + +``` +SumIf([Payment], [Plan] = "Basic") +``` + +The `case` version lets you sum a different column when the condition isn't met. For example, you could create a column called "Revenue" that: + +- sums the "Payments" column when "Plan = Basic", and +- sums the "Contract" column otherwise. + +``` +sum(case([Plan] = "Basic", [Payment], [Contract])) +``` + +### CumulativeSum + +`SumIf` doesn't do running totals. You'll need to combine the [CumulativeSum](../expressions-list#cumulativesum) aggregation with the [`case`](./case) formula. + +For example, to get the running total of payments for the Business and Premium plans by month (using our [payment sample data](#conditional-subtotals-by-group)): + +| Date Received: Month | Total Payments for Business and Premium Plans | +| -------------------- | --------------------------------------------- | +| October | 200 | +| November | 800 | + +Create an aggregation from **Summarize** > **Custom expression**: + +``` +CumulativeSum(case(([Plan] = "Basic" OR [Plan] = "Premium"), [Payment], 0)) +``` + +Don't forget to set the **Group by** column to "Date Received: Month". + +### SQL + +When you run a question using the [query builder](/glossary/query_builder), Metabase will convert your query builder settings (filters, summaries, etc.) into a SQL query, and run that query against your database to get your results. + +If our [payment sample data](#sumif) is stored in a PostgreSQL database, the SQL query: + +```sql +SELECT + SUM(CASE WHEN plan = "Basic" THEN payment ELSE 0 END) AS total_payments_basic +FROM invoices +``` + +is equivalent to the Metabase expression: + +``` +SumIf([Payment], [Plan] = "Basic") +``` + +To add [multiple conditions with a grouping column](#conditional-subtotals-by-group), use the SQL query: + +```sql +SELECT + DATE_TRUNC("month", date_received) AS date_received_month, + SUM(CASE WHEN plan = "Business" THEN payment ELSE 0 END) AS total_payments_business_or_premium +FROM invoices +GROUP BY + DATE_TRUNC("month", date_received) +``` + +The `SELECT` part of the SQl query matches the Metabase `SumIf` expression: + +``` +SumIf([Payment], [Plan] = "Business" OR [Plan] = "Premium") +``` + +The `GROUP BY` part of the SQL query maps to a Metabase [**Group by**](../../query-builder/summarizing-and-grouping) column set to "Date Received: Month". + +### Spreadsheets + +If our [payment sample data](#sumif) is in a spreadsheet where "Payment" is in column A and "Date Received" is in column B, the spreadsheet formula: + +``` +=SUMIF(B:B, "Basic", A:A) +``` + +produces the same result as the Metabase expression: + +``` +SumIf([Payment], [Plan] = "Basic") +``` + +To add additional conditions, you'll need to switch to a spreadsheet **array formula**. + +### Python + +If our [payment sample data](#sumif) is in a `pandas` dataframe column called `df`, the Python code: + +```python +df.loc[df['Plan'] == "Basic", 'Payment'].sum() +``` + +is equivalent to the Metabase expression: + +``` +SumIf([Payment], [Plan] = "Basic") +``` + +To add [multiple conditions with a grouping column](#conditional-subtotals-by-group): + +```python +import datetime as dt + +## Optional: convert the column to a datetime object + + df['Date Received'] = pd.to_datetime(df['Date Received']) + +## Extract the month and year + + df['Date Received: Month'] = df['Date Received'].dt.to_period('M') + +## Add your conditions + + df_filtered = df[(df['Plan'] == 'Business') | (df['Plan'] == 'Premium')] + +## Sum and group by + + df_filtered.groupby('Date Received: Month')['Payment'].sum() +``` + +These steps will produce the same result as the Metabase `SumIf` expression (with the [**Group by**](../../query-builder/summarizing-and-grouping) column set to "Date Received: Month"). + +``` +SumIf([Payment], [Plan] = "Business" OR [Plan] = "Premium") +``` + +## Further reading + +- [Custom expressions documentation](../expressions) +- [Custom expressions tutorial](/learn/metabase-basics/querying-and-dashboards/questions/custom-expressions) diff --git a/_docs/doc-update-detection/questions/query-builder/expressions/week.md b/_docs/doc-update-detection/questions/query-builder/expressions/week.md new file mode 100644 index 000000000..19171d82a --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/expressions/week.md @@ -0,0 +1,101 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Week of year' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/expressions/week.md' +description: 'In Metabase, you can group by week of year in the query builder, or extract the week of year from a date column using a custom expression. Metabase supports multiple algorithms for determining the first week of the year.' +--- + +# Week of year + +Weeks of the year are numbered from 1 to 52, 53, or 54 (depending on how the first week of the year is determined). Metabase supports multiple algorithms for determining the first week of the year. + +In the query builder, you can group summaries by week of year, or extract the week of year from a date column using a custom expression. + +Grouping summaries by Week of year is useful when making period-over-period comparisons - for example, when comparing a metric from the first week this year to the metric from the first week in the previous year. + +## Summarize by Week of year in the query builder + +You can choose to group a metric by week of year in the query builder. + +1. In the Summarize section, click on **Pick a column to group by** and select a date field: +2. Click on the dropdown with date granularity (for example, "by month") to the right of the field name; +3. In the popup with date granularity options, click **More...** to see additional options, and select **Week of year**. + +The result will be summarized by week number (as opposed to week _dates_, like when you select "by week" option): + +![Summarize by week of year](../../images/summarize-by-week-of-year.png) + +## How Metabase numbers weeks of the year + +By default, when you group by Week of year in the query builder, Metabase will find the first Sunday of the year and call that week “week 1”. Any day before the first Sunday is considered to be part of the last week of the previous year (week 52 or 53). + +### Using a different first week of the year + +Even if your instance has a different first day of the week set in [localization settings](../../../configuring-metabase/localization), the query builder's default week of year grouping will _always_ use Sunday as the start of the week. + +The way to use your instance's localization settings is to use the `week` function in a custom expression with the `"Instance"` mode, like so: `week([Created At], "Instance")` (see below). + +The `week` custom expression provides three alternative algorithms for computing first week of the year. To use an alternative algorithm for summarizing, you can create a custom column that extracts the week number from a date column using the `week` expression, then group by that custom column. + +## `week` custom expression + +The `week` custom expression extracts the week of the year as an integer. + +Syntax: + +``` +week(column, mode) +``` + +Examples: + +``` +week([Created At]) +week([Created At], "US") +week([Created At], "Instance") +``` + +Where: + +- `column` is the date column you want to extract the week number from. +- `mode` is optional and specifies the algorithm to use to determine the first week of the year. It can be one of the following: + - `"ISO"` (default): the first week of the year is the week containing the first Thursday of the year. Weeks start on Monday. This is the ISO 8601 standard. + - `"US"`: The first week of the year starts on January 1. Weeks start on Sundays. In most years, the first week will be a partial week. + - `"Instance"`: The first week of the year starts on January 1. Weeks start on the day of the week specified in [localization settings](../../../configuring-metabase/localization). In most years, the first week will be a partial week. + +Note that none of the three currently available modes match the first week algorithm used in summarizing by week of the year in the query builder. + +### Comparing how different algorithms calculate the first and last weeks + +- In the query builder when using **Group by Week of year**: + + ![How the week numbers are calculated for Group by Week of year](../../images/group-by-week-of-year.png) + +- `week(column)` or `week(column, "ISO")`: + + ![How the week numbers are calculated by ISO](../../images/week-iso.png) + +- `week(column, "US")`: + + ![How the week numbers are calculated by US method](../../images/week-us.png) + +- `week(column, "Instance")` if the instance's first day of the week is Monday: + + ![How the week numbers are calculated by Instance method](../../images/week-instance.png) + +## SQL + +Different SQL databases have different approaches and functions for extracting week of the year. Some engines offer multiple functions for extracting week of the year and multiple algorithms for computing week of year using SQL. Refer to the documentation for your database. + +Here's an incomplete list of example functions: + +| Database | Example | First week algorithm | +| -------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| Postgres | `EXTRACT(WEEK FROM TIMESTAMP created_at)` | ISO algorithm | +| MySQL | `WEEKOFYEAR("2017-06-15")` | The first day of the week is Monday and the first week of the year has more than 3 days. Alternative functions exist. | +| BigQuery | `EXTRACT(WEEK FROM DATE ticreated_at)` | Weeks numbered from 0. Dates prior to the first Sunday of the year are in week 0. Alternative functions exist. | +| Redshift | `DATE_PART(week, TIMESTAMP created_at)` | ISO algorithm | diff --git a/_docs/doc-update-detection/questions/query-builder/filters.md b/_docs/doc-update-detection/questions/query-builder/filters.md new file mode 100644 index 000000000..2025460d4 --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/filters.md @@ -0,0 +1,62 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Filtering +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/filters.md' +--- + +# Filtering + +Filtering just means narrowing things down based on certain criteria. You're probably already familiar with filtering when looking for something online, like when shopping. Maybe you only want to see olive-colored pants, or books where the author's last name is "Borges," or pictures of people wearing olive-colored pants reading Jorge Luis Borges. + +![Filtering](../images/filter-step.png) + +When you add a filter step, you can select one or more columns to filter on. Depending on the [data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview) of the column you pick, you'll get different [filter types](#filter-types), like a calendar for date columns. + +You can add subsequent filter steps after each summarize step. This lets you do things like summarize by the count of rows per month, and then add a filter on the `count` column to only include rows where the count is greater than 100. (This is basically like a SQL `HAVING` clause.) + +Once you're happy with your filter, click **Add filter**, and visualize your results. Your data will be updated with the filter applied. + +If you want to edit your filter, just click the little purple filter at the top of the screen. If you click on the X, you'll remove your filter. You can add as many filters as you need. + +## Filter types + +Depending on the data type of the column, Metabase will present different filtering options. + +- **Numeric columns** let you add filters to only include rows in your table where this number is between two specific values, or is greater or less than a specific value, or is exactly equal to something. +- **Text or category columns** let you specify that you only want to include data where this column is or isn't a specific option, whether it contains, starts with, or ends with a substring, or whether the row is empty or not. +- **Date columns** give you a lot of options to filter by specific date ranges, relative date ranges, and more. +- **Structured data columns**, typically JSON or XML, can only be filtered by "Is empty" or "Not empty". Some databases, however, support [JSON unfolding](../../data-modeling/json-unfolding), which allows you to split up JSON data into separate columns, which you can then filter on. +- **Latitude and longitude columns** will have the same options as numeric columns, but also a special "Inside" filter type that will let you filter on both latitude and longitude simultaneously. + +## Filter multiple columns + +When viewing a table or chart, clicking on the **Filter** will bring up the filter modal. + +![Bulk filter modal](../images/bulk-filter-modal.png) + +Here you can add multiple filters to your question in one go (which can save you a lot of loading time). Filter options will differ depending on the [field type](../../data-modeling/field-types). Any tables linked by foreign keys will be displayed in the left tab of the modal. You can also filter your summaries. + +When you're done adding filters, hit **Apply filters** to rerun the query and update its results. To remove all the filters you've applied, click on **Clear all filters** in the bottom left of the filter modal. Any filters you apply here will show up in the editor, and vice versa. + +## Filtering by date + +One important thing to understand when filtering on a date column is the difference between specific and relative dates: + +- **Specific dates** are things like November 1, 2010, or June 3 – July 12, 2017; they always refer to the same date(s). +- **Relative dates** are things like "the previous 30 days," or "the current week;" as time passes, the dates these options refer to _change_. Relative dates are a useful way to set up a filter on a question so that it stays up-to-date by showing you, for example, how many people visited your website in the last 7 days. You can also click on the **...** to specify a **Starting from** option, which lets you offset the relative date range. For example, you could set the range as the "Previous 7 days, starting from 2 days ago". + +## Filter with custom expressions + +![Filter expression](../images/filter-expression.png) + +If you have a more complex filter you're trying to express, you can pick [Custom Expression](./expressions) from the add filter menu to create a filter expression. You can use comparison operators like greater than, `>`, or less than ,`<`, as well as spreadsheet-like functions. For example, `[Subtotal] > 100 OR median([Age]) < 40`. + +Learn more about writing [expressions](./expressions) or skip right to the [list of expressions](./expressions-list). + +## Filtering by a segment + +If your Metabase administrators have created special named filters for the table you're viewing, they’ll appear at the top of the filter dropdown in purple text with a star next to them. These are called [**Segments**](../../data-modeling/segments), and they're shortcuts to a combination of filters that are commonly used in your organization. They might be called things like “Active Users,” or “Most Popular Products.” diff --git a/_docs/doc-update-detection/questions/query-builder/join.md b/_docs/doc-update-detection/questions/query-builder/join.md new file mode 100644 index 000000000..a5fd0afc8 --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/join.md @@ -0,0 +1,67 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Joining data' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/join.md' +redirect_from: + - /docs/doc-update-detection/users-guide/join +--- + +# Joining data + +![Joining](../images/join-step.png) + +You can [join data][join] to combine your current data with another table, or even with a saved question. + +After you click on the Join Data button to add a join step, you'll need to pick the data (from the same database) that you want to join. You can only pick tables and saved questions that are from the same database as your starting data. + +![Picking the data to join](../images/join-pick-data.png) + +Next, you'll need to pick the columns you want to join on. This means you pick a column from the first table, and a column from the second table, and the join will stitch rows together where the value from the first column is equal to the value in the second column. A very common example is to join on an ID column in each table, so if you happened to pick a table to join on where there is a foreign key relationship between the tables, Metabase will automatically pick those corresponding ID columns for you. At the end of your join step, there's a `Columns` button you can click to choose which columns you want to include from the joined data. + +By default, Metabase will do a left outer join, but you can click on the Venn diagram icon to select a different type of join. Not all databases support all types of joins, so Metabase will only display the options supported by the database you're using. + +Here are the basic types of joins: + +- **Left outer join:** select all records from Table A, along with records from Table B that meet the join condition, if any. +- **Right outer join:** select all records from Table B, along with records from Table A that meet the join condition, if any. +- **Inner join:** only select the records from Table A and B where the join condition is met. +- **Full outer join:** select all records from both tables, whether or not the join condition is met. + +**A left outer join example:** If Table A is Orders and Table B is Customers, and assuming you do a join where the `customer_id` column in Orders is equal to the `ID` column in Customers, when you do a left outer join your results will be a full list of all your orders, and each order row will also display the columns of the customer who placed that order. Since a single customer can place many orders, a given customer's information might be repeated many times for different order rows. If there isn't a corresponding customer for a given order, the order's information will be shown, but the customer columns will just be blank for that row. + +## Multiple stages of joins + +In many cases you might have tables A, B, and C, where A and B have a connection, and B and C have a connection, but A and C don't. If you want to join A to B to C, all you have to do is add multiple join steps. Click on Join Data, join table A to table B, then click the Join Data step below that completed join block to add a second join step, and join the results of your last join to table C. + +![An A to B to C join](../images/join-a-b-c.png) + +## Joining on multiple conditions + +Your joins can also include multiple conditions to refine your results. Metabase will combine multiple conditions using the `AND` operator. + +![Joining tables on multiple columns](../images/joining-on-multiple-columns.png) + +## Joining with different operators + +You can join tables on comparison conditions like: + +- `=` (equals) +- `≠` (not equals) +- `>` (greater than) +- `≥` (greater than or equal to) +- `<` (less than) +- `≤` (less than or equal to) + +![Join operators](../images/join-operator.png) + +## Further reading + +- [Joins in Metabase][join] +- [Type of joins][join-types] + +[join]: /learn/metabase-basics/querying-and-dashboards/questions/joins-in-metabase +[join-types]: /learn/grow-your-data-skills/learn-sql/working-with-sql/sql-join-types diff --git a/_docs/doc-update-detection/questions/query-builder/summarizing-and-grouping.md b/_docs/doc-update-detection/questions/query-builder/summarizing-and-grouping.md new file mode 100644 index 000000000..e663471e6 --- /dev/null +++ b/_docs/doc-update-detection/questions/query-builder/summarizing-and-grouping.md @@ -0,0 +1,73 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Summarizing and grouping' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/query-builder/summarizing-and-grouping.md' +--- + +# Summarizing and grouping + +![Summarizing](../images/summarize-step.png) + +When we have a question like "how many people downloaded our app each day last week?", we're asking for a **summary** of the data. A summary is usually made up of two parts: one or more _numbers_ we care about (called a "metric" in data-speak), and how we want to see that number _grouped_ or _broken out_. To answer that example question of "How many people downloaded our app each day last week?" + +- The metric would be the count of people who downloaded the app (the count of rows). +- We want that metric to be grouped by "each day." +- And we want to filter the rows for "last week." + +There are two common ways you'll tend to summarize your data: + +- Counting the number of rows in your table +- Getting the sum or average of a numeric column + +And a lot of the time, you'll then **group** that metric by: + +- Time +- Place +- Category + +## Summary metrics + +Adding a summarize step lets you choose how to aggregate the data from the previous step. You can pick one or more metrics, and optionally group those metrics by one or more dimensions (columns). When picking your metrics you can choose from basic functions like `sum`, `average`, and `count`; or you can pick a common metric defined by an admin; or you can create a [custom expression](./expressions) by writing a formula. + +Common metrics include: + +- **Count of rows:** the total of number of rows in the table, after any filters have been applied. If you're looking at your `Orders` table and want to know how many orders were placed with a price greater than \$40, you’d filter by “Price greater than 40,” and then select `Count of rows`, because you want Metabase to count how many orders matched your filter. +- **Sum of …:** the sum of all the values in a specific column. +- **Average of …:** the average of all the values in a single column. +- **Number of distinct values of…:** the number of unique values in all the cells of a single column. This is useful when trying to find out things like how many different _types_ of products were sold last month (not how many were sold in total). +- **Cumulative sum of…:** This gives you a running total for a specific column. In order for this metric to be useful you'll need to group it by a date column to see it across time. +- **Cumulative count of rows:** This gives you a running total of the number of rows in the table over time. Just like `Cumulative sum of…`, you'll need to group this by a date column in order for it to be useful. +- **Standard deviation of …:** A number which expresses how much the values of a column vary, plus or minus, from the average value of that column. +- **Minimum of …:** The minimum value present in the selected field. +- **Maximum of …:** The maximum value present in the selected field. + +If you summarize and add a grouping you can then summarize _again_. You can also add steps to filter and/or join in between. For example, your first summarization step could be to get the count of orders per month, and you could then add a second summarization step to get the average monthly order total by selecting the `Average of…` your `count` column. + +![Multiple summarize steps](../images/multiple-summarize-steps.png) + +You can also add metrics and groupings on the results page in a sidebar: the top of the sidebar where you pick the number ("metric") you want to see, and the part below is where you pick how to group that number (or how to "break it out"). + +If your admins have created any named [metrics](../../data-modeling/metrics) that are specific to your company or organization, they will be in this dropdown under the **Common Metrics** section. These might be things like your company’s official way of calculating revenue. + +## Grouping your metrics + +Depending on the grouping column you select, Metabase will show you what it thinks is the best default visualization or chart for this summary. So if you select a date column, you'll see a line chart like this (you can click the green **Summarize** button to view the summarize sidebar). + +![Grouping by a date column](../images/summarize-timeseries.png) + +When you click on a different grouping column than the one you currently have selected, the grouping will switch to use that column instead. But if you want to _add_ an additional grouping, just click the plus (+) icon on the right side of the column. To remove a grouping, click on the X icon. + +![Multiple groupings](../images/summarize-timeseries-breakout.png) + +Some grouping columns will give you the option of choosing how big or small to make the groupings: + +- For datetime columns, you can click on the words `by month` to change the grouping to day, week, hour, quarter, year, etc. You'll also be able to add multiple breakouts by the same datetime column with different time granularities (for example, group by week and day of the week). For information on grouping by week of year, see [Week of year](./expressions/week). +- For numeric columns like age, Metabase will automatically "bin" the results, so you'll see your metric grouped in age brackets, like 0–10, 11–20, 21–30, etc. Just like with dates, you can click on the current binning option to change it to a specific number of bins. Currently, you can't choose your own ranges for bins. + + ![Multiple groupings](../images/histogram-bins.png) + + If you select a fixed number of bins, Metabase will break the range of the data into that number of equal size intervals. Some intervals might end up having no data, and Metabase will not display them. diff --git a/_docs/doc-update-detection/questions/start.md b/_docs/doc-update-detection/questions/start.md new file mode 100644 index 000000000..fc7aaf2f5 --- /dev/null +++ b/_docs/doc-update-detection/questions/start.md @@ -0,0 +1,71 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: Questions +title: 'Questions overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/start.md' +--- + +# Questions overview + +Questions are queries plus their visualization. You can ask questions using Metabase's graphical query builder, or create a native/SQL query. + +## [Question introduction](./introduction) + +Questions are the basic building blocks of Metabase. + +## Query builder + +### [The query editor](./query-builder/editor) + +An introduction to Metabase's graphical query builder. + +### [Custom expressions](./query-builder/expressions) + +Custom expressions, like spreadsheet formulas, are tools you can use in the graphical query builder to ask more complicated questions. + +### [List of expressions](./query-builder/expressions-list) + +A list of the aggregations and functions available in the graphical query builder. + +### [Joining data](./query-builder/join) + +You can join data to combine your current data with another table, or even with a saved question. + +## Native query editor + +Also known as the SQL editor (we say native because you can also query databases that don't use SQL, like MongoDB). + +### [Introduction to the native query editor](./native-editor/writing-sql) + +Write native code (like SQL) to query your data source. + +### [SQL templates](./native-editor/sql-parameters) + +Pass parameters into variables in your SQL templates. + +### [Snippets](./native-editor/snippets) + +Reuse and share bits of SQL. + +## Sharing results + +There are many different ways to share the results of questions. To share the results of a dashboard, see [Dashboard subscriptions](../dashboards/subscriptions). + +### [Visualizing results](./visualizations/visualizing-results) + +Choose from a variety of visualization types. + +### [Alerts](./alerts) + +Get results via email or Slack, either on a schedule, or only when something interesting happens. + +### [Exporting](./exporting-results) + +The different ways you can export the results of questions and dashboards. + +### [Tooltips](./visualizations/tooltips) + +Customize tooltips on bar, line, and area charts. diff --git a/_docs/doc-update-detection/questions/visualizations/combo-chart.md b/_docs/doc-update-detection/questions/visualizations/combo-chart.md new file mode 100644 index 000000000..ab84ed259 --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/combo-chart.md @@ -0,0 +1,27 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Combo charts' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/combo-chart.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/combo-chart +--- + +# Combo charts + +Combo charts let you combine bars and lines (or areas) on the same chart. + +![Line + bar](../images/combo-chart.png) + +Metabase will pick one of your series to display as a line, and another to display as a bar by default. Open up the visualization settings to change which series are lines, bars, or areas, as well as to change per-series settings like colors. + +To use a Combo chart you'll either need to have two or more metrics selected in the Summarize By section of your question, with one or two grouping columns, like this: + +![Data for Line + Bar chart](../images/combo-chart-data-1.png) + +Or you'll need a question with a single metric and two grouping columns, like this: + +![Data for Line + Bar chart](../images/combo-chart-data-2.png) diff --git a/_docs/doc-update-detection/questions/visualizations/detail.md b/_docs/doc-update-detection/questions/visualizations/detail.md new file mode 100644 index 000000000..722f7a49b --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/detail.md @@ -0,0 +1,19 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Detail +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/detail.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/detail +--- + +# Detail + +The **Detail** visualization shows a single result record (row) in an easy-to-read, two-column display. + +![Detail of a record in the account table](../images/detail.png) + +You can cycle through records using the arrow buttons. diff --git a/_docs/doc-update-detection/questions/visualizations/funnel.md b/_docs/doc-update-detection/questions/visualizations/funnel.md new file mode 100644 index 000000000..fe0853f5a --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/funnel.md @@ -0,0 +1,93 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Funnel charts' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/funnel.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/funnel + - /learn/visualization/funnel + - /docs/doc-update-detection/questions/visualizations/funnel + - /learn/metabase-basics/querying-and-dashboards/visualization/funnel +description: 'Funnel charts visualize how a value is broken out by a series of steps, and the percent change between steps. To build a funnel chart in Metabase, you need a table with the name and value for each step.' +--- + +# Funnel charts + +Funnel charts visualize how a value is broken out by a series of steps, and the percent change between steps. + +![Funnel](../images/funnel.png) + +Funnels are commonly used in e-commerce or sales to visualize how many customers are present within each step of a checkout flow or sales cycle. Funnels only make sense if the steps are sequential, with the metric dropping from one step to the next. + +## Data shape for a funnel chart + +To create a funnel in Metabase, you'll need to have a table with at least two columns: one column that contains the funnel's steps, and another column contains the metric you're interested in, like the number of customers at this step. + +Here's the data shape used to create the chart above: + +| Stage | Opportunities | +| ------------- | ------------- | +| Leads | 3901 | +| Qualification | 3714 | +| Prospecting | 3231 | +| Proposal | 2972 | +| Negotiation | 1588 | +| Closed | 737 | + +If you have more columns in your query results, you can select which columns should be used for the funnel steps and the metric in the [data settings](#funnel-chart-settings). + +By default, Metabase will present steps in the same order as they appear in the query result, but you can reorder or hide the steps in the [data settings](#funnel-chart-settings). + +## Build a query for a funnel chart + +To create a query with a result that has the shape required for a funnel chart, you'll probably need to summarize your data. + +If your (original, unaggregated) data already contains a field with the the step for every data point, you can build a simple query with a breakout by steps: + +![A query in the query builder used to build a funnel chart](../images/build-a-funnel-query.png) + +If data for the different steps of the funnel comes from different tables, or if you need to use different filters or aggregation rules for each step, you can create separate questions for each step, and then combine them with a SQL query. + +For example: you could create three separate [query builder](../query-builder/editor) questions, each returning the counts for `Leads`, `Qualification`, and `Proposal` stage. Then you'd write a [SQL query](../native-editor/writing-sql) that [references those questions](../native-editor/referencing-saved-questions-in-queries) and uses `UNION` to return results in the right shape to build a funnel chart. + +```sql +-- example of a query that retrieves results of questions and combines them with UNION + +SELECT 'Leads' as step, * from {{#120-leads}} +UNION +SELECT 'Qualified' as step, * from {{#121-qualified}} +UNION +SELECT 'Prospects' as step, * from {{#122-prospects}} + +``` + +![Data for the funnel coming from a SQL union](../images/funnel-as-sql.png) + +## How to read a funnel chart + +Funnel charts show the value of the metric for each step, and how the metric compares to the value at the _first_ step. The first step's metric is displayed to the left of the chart. + +![Funnel chart with a tooltip](../images/read-a-funnel.png) + +So for example,"76.19\%, 2,972" under a step means that the value of the metric at this step is 2,972, which is 76.19\% of the value of the _first_ step (equal to 3,901). + +To see percentage comparison with the _previous_ step (instead of the first), hover over the step and read the tooltip. + +## Funnel chart settings + +To open chart settings, click on the **Gear** icon in the bottom left. + +![Funnel chart settings](../images/funnel-settings.png) + +If you have more than two columns in your query results, you can select which columns should be used for the funnel steps and the measure in the **Data** tab. + +You can reorder funnel steps by dragging and dropping, or hide a step by clicking on the **Eye** icon on the step card. + +To edit the formatting of the metric, click on **Three dots** next to the metric. The formatting will only apply to the _metric itself_, but _not_ to the percentage values that compare each step's metric to the first step (which currently you can't format). + +## Limitations and alternatives + +Currently, you can't change the color or orientation of the funnel, or add breakouts. Consider using a [bar or row chart](./line-bar-and-area-charts) for more flexible visualization options. diff --git a/_docs/doc-update-detection/questions/visualizations/gauge.md b/_docs/doc-update-detection/questions/visualizations/gauge.md new file mode 100644 index 000000000..a90726388 --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/gauge.md @@ -0,0 +1,68 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Gauge chart' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/gauge.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/gauge +--- + +# Gauge chart + +Ah, **gauges**: you either love 'em or you hate 'em. …Or you feel "meh" about them, I guess. Whatever the case, gauges allow you to show a single number in the context of a set of colored ranges that you can specify. + +![Gauge](../images/gauge.png) + +## When to use a gauge chart + +A gauge chart is useful when you want to show progress or status across different categories. +They're helpful for performance metrics, risk assessments, or any metric that has distinct thresholds. + +## How to create a gauge chart + +To build a gauge chart, you'll need: + +- A query that returns a single number: + + | Sum of Quantity | + | --------------- | + | 4910 | + + You can also use a query that returns several metrics in a single row: + + | Sum of Quantity | Average Quantity | Max Quantity | + | --------------- | ---------------- | ------------ | + | 4910 | 17.32 | 173 | + + In this case, the gauge chart will use the metric in the first column ("Sum of quantity"). To change the metric, go to the editor and drag the metric you want to the first position in the Summarize block. + +- One or more ranges for the metric, for example "Low", "Medium", "High". Currently, Metabase only supports defining static ranges (you can't set range boundaries based on another query). + +![Gauge chart](../images/gauge-labeled.png) + +## Gauge chart settings + +You can set the ranges, their colors, and optional labels in chart settings. + +To open the chart setting, click on the **Visualization** icon at the bottom left of the screen. + +Format options will apply to both the result of the query and the range boundaries: + +![Gauge format options](../images/gauge-format.png) + +In particular, the gauge chart will apply the "Multiply by a number" option to the range boundaries. So if you want to show a range from 2000 to 4000 on the chart, you can set "Multiply by a number: 1000", then set the underlying range to be from 2 to 4. + +Selecting “Style: Percent” in format options will only change how Metabase formats the results. For example, `17` will be formatted as `1700%`. If you instead want to display the query result as a percentage of the _total_ range of the chart, you’ll need to calculate that percentage in your query. Another example: to display the count of orders as a percentage of 20, use custom expressions to return “Count of orders divided by 20”, and format the result as a percentage. + +## Limitations and alternatives + +- If you want to show progress of a metric within a single range, consider using the [progress bar](./progress-bar) instead. + +- Metabase doesn't support setting alerts for when a metric moves from one region of the gauge chart to another. Consider using a [progress bar](./progress-bar) to create an alert when your metric reaches a certain value. + +- Gauge charts don't support breakouts. Depending on your use case, consider using a [bar chart with a goal line](./line-bar-and-area-charts#goal-lines). + +- Gauge chart ranges can't be set based on results of another query. diff --git a/_docs/doc-update-detection/questions/visualizations/line-bar-and-area-charts.md b/_docs/doc-update-detection/questions/visualizations/line-bar-and-area-charts.md new file mode 100644 index 000000000..dcebd5c80 --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/line-bar-and-area-charts.md @@ -0,0 +1,175 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Line charts, bar charts, and area charts' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/line-bar-and-area-charts.md' +redirect_from: + - /docs/doc-update-detection/questions/visualizations/line-bar-and-area-charts +--- + +# Line charts, bar charts, and area charts + +They're pretty useful. + +## Line charts + +**Line charts** are best for displaying the trend of a number over time, especially when you have lots of x-axis values. For more, check out our [Guide to line charts](/learn/metabase-basics/querying-and-dashboards/visualization/line-charts) and [Time series analysis](/learn/metabase-basics/querying-and-dashboards/time-series) tutorials. + +![Trend lines](../images/goal-line.png) + +## Bar charts + +![Bar chart](../images/bar.png) + +If you're trying to group a number by a column that has a lot of possible values, like a Vendor or Product Title field, try visualizing it as a **row chart**. Metabase will show you the bars in descending order of size, with a final bar at the bottom for items that didn't fit. + +![Row chart](../images/row.png) + +If you have a bar chart like Count of Users by Age, where the x-axis is a number, you'll get a special kind of chart called a **[histogram](/learn/metabase-basics/querying-and-dashboards/visualization/histograms)**, where each bar represents a range of values (called a "bin"). Note that Metabase will automatically bin your results any time you use a number as a grouping, even if you aren't viewing a bar chart. Questions that use latitude and longitude will also get binned automatically. + +## Combo line and bar charts + +See [Combo charts](./combo-chart). + +## Histograms + +![Histogram](../images/histogram.png) + +By default, Metabase will automatically choose a good way to bin your results. But you can change how many bins your result has, or turn the binning off entirely, by clicking on the area to the right of the column you're grouping by: + +![Binning options](../images/histogram-bins.png) + +## Area charts + +**Area charts** are useful when comparing the proportions of two metrics over time. Both bar and area charts can be stacked. + +![Stacked area chart](../images/area.png) + +## Settings for line, bar, and area charts + +These three charting types have very similar options, which are broken up into the following tabs. You can access these chart settings by clicking the **gear** icon in the lower left of the chart. + +- [Data settings](#data-settings) +- [Display settings](#display-settings) +- [Axes settings](#axes-settings) + +## Data settings + +Here you can configure settings for the how the data is displayed. + +For each series on the chart, you can: + +- Whether to show or hide the series. +- Determine how to display the series: as a line, bar, or area chart. +- Determine the order Metabase displays the series in the chart's legend. + +### Line chart and Area chart options + +![Line chart options](../images/line-options.png) + +- Line color +- Line shape +- Line style +- Line size: Small, Medium, or Large +- Whether to show docs on the lines (the dots represent the actual data points plotted on the chart) +- Whether to show values for the series. This option is only available if you've toggled on [Show value on data points](#values-on-data-points). +- How to replace missing values: Zero, Nothing (just a break in the line), or Linear interpolated + +You can also rearrange series (which determines their order in the chart's legend). + +### Bar chart options + +For bar charts, you can configure: + +- Bar color +- Y-axis position (which side of the chart to display the y-axis labels) + +## Display settings + +Here you set things like: + +- [Goal line](#goal-lines) +- [Stack a bar chart](#stacked-bar-chart) +- [Whether to show values on data points](#values-on-data-points) + +### Goal lines + +![Goal line on chart](../images/goal-line.png) + +Goal lines can be used in conjunction with [alerts](../alerts) to send an email or a Slack message when your metric cross this line. + +### Trend lines + +**Trend lines** are another useful option for line, area, bar, and scatter charts. If you have a question where you're grouping by a time field, open up the visualization settings and turn the **Show trend line** toggle on to display a trend line. Metabase will choose the best type of line to fit to the trend of your series. Trend lines will even work if you have multiple metrics selected in your summary. But trend lines won't work if you have any groupings beyond the one time field. + +![Trend lines](../images/trend-lines.png) + +### Stacked bar chart + +If you have multiple series, you can stack them on bar chart. + +![Stacked bar chart](../images/stacked-bar-chart.png) + +As well as stack them as a percentage: + +![Stacked bar chart 100%](../images/stacked-100.png) + +### Values on data points + +You can show some values (Metabase will pick some values to make the chart more legible), all values, or no values. + +If you toggle on values on data points, you can toggle values for individual series on the [Data](#data-settings) tab of the chart's settings. For example, if you have four series, and only want to display values for one of the series. + +### Autoformatting + +For displaying numbers on the chart, Metabase can truncate the numbers to make the chart more legible. For example, Metabase will truncate 42,000 to 42K. + +## Axes settings + +Here you'll find additional settings for configuring your x and y axes (as in axis, not battle axe). + +### X-axis + +- Show label (the label for the axis). +- Rename the axis +- Show line and marks +- Scale: Timeseries or Ordinal. + +### Y-axis + +- Show label (the label for the axis). +- Rename the axis +- Split y-axis when necessary +- Auto y-axis range. When not toggled on, you can set the y-axis range (it's min and max values). +- Scale: Linear, power, or log. +- Show lines and marks +- Unpin from zero. Allows you to "Zoom in" on charts with values well above zero. Here's an example (note the y-axis starts at 20,000): + ![y-axis unpinned from zero](../images/unpinned-from-zero-y-axis.png) + +## Chart legend + +For charts with multiple series or breakouts, chart legend displays the label and color of each series. + +![Legend](../images/legend.png) + +You can change the color and label for each series and reorder them in [data settings](#data-settings). + +You can use the legend to: + +- Highlight a series, by hovering over the name of the series in the legend. +- Hide the series, by clicking on the color circle for the series. + +To permanently hide the series from the chart, use the [data settings](#data-settings). + +- Drill down to individual records for aggregated series, by clicking on the series name. + +Currently, you can't hide the legend or change its position on the chart. + +## Further reading + +- [Guide to line charts](/learn/metabase-basics/querying-and-dashboards/visualization/line-charts) +- [Master the bar chart](/learn/metabase-basics/querying-and-dashboards/visualization/bar-charts) +- [Visualize your data as a histogram](/learn/metabase-basics/querying-and-dashboards/visualization/histograms) diff --git a/_docs/doc-update-detection/questions/visualizations/map.md b/_docs/doc-update-detection/questions/visualizations/map.md new file mode 100644 index 000000000..8b8deb43e --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/map.md @@ -0,0 +1,208 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Maps +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/map.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/maps + - /learn/basics/visualizing-data/maps + - /learn/visualization/maps + - /learn/metabase-basics/querying-and-dashboards/visualization/maps +description: 'Maps in Metabase allow you to visualize geographical data either using coordinates or by region. Metabase gives you three types of maps : pin map for unaggregated data, grid map for histograms, and region map for distributions by regions like countries or states. You can also create custom maps.' +--- + +# Maps + +Metabase has three types of map visualization: + +- [**Pin map**](#pin-map) for putting individual data points on a map using longitude and latitude coordinates; +- [**Grid map**](#grid-map) for distributing a large number of points over a specified area. +- [**Region map**](#region-maps) for data broken out by regions, like countries or states. Metabase comes with two built-in maps, but you can upload your own custom regions. + +When you select the **Map** visualization setting, Metabase will automatically try and pick the best kind of map to use based on the table or result set, as long as the columns with the geographical data have the [right metadata](../../data-modeling/metadata-editing). + +![Map types](../images/map-types.png) + +{% include youtube.html id='EewOLxHht1s' %} + +## Pin map + +Pin maps display pins for individual data points on the map. They work best for displaying unaggregated geographical data. + +### Pin map data shape + +To build a pin map, you need a query that returns a result that has latitude and longitude columns. Metabase will put one pin on the map for each row in your table, based on the latitude and longitude fields. Other data in the rows will be shown in the tooltip, and won't otherwise affect the placement or shape of pins. + +![Pin map data shape](../images/pin-data-shape.png) +![Pin map with a tooltip](../images/pin-map-with-tooltip.png) + +Note that the tooltips will only be displayed when the map is sufficiently zoomed in using [**Draw box to filter**](#draw-box-to-filter). + +### Create a pin map + +To create a pin map: + +1. Build a query with latitude and longitude columns for each data point (either in the query builder or using SQL); +2. Select **Visualization**, and pick **Map**; +3. If your query results have columns whose field type is set to latitude/longitude in [table metadata](../../data-modeling/metadata-editing#field-type), Metabase should build a pin map automatically. + + Otherwise, click on the **Gear** icon to go to visualization settings, choose **Map type: Pin map**, and pick columns that contain latitude and longitude coordinates. + +### Pin maps display 2000 pins by default + +By default, pin maps will display 2000 pins even if there are more rows in your query results (this limit is the same for every chart displaying unaggregated data in Metabase). You can use the environment variable [`MB_UNAGGREGATED_QUERY_ROW_LIMIT`](../../configuring-metabase/environment-variables#mb_unaggregated_query_row_limit) to increase the number of data points rendered on charts based on unaggregated queries, but keep in mind that this setting will affect all charts—not just the pin maps—and it might significantly slow down your Metabase and your browser. + +If you need to display a large number of geographical data points, consider using a grid map to display the distribution instead. + +## Grid map + +Grid map is an aggregated version of the pin map — like a heatmap for the distribution of pins. Grid map breaks the the map into a grid based on latitude/longitude, and then colors each grid cell based on how many data points fall in it. + +![Grid map](../images/grid-map.png) + +### Grid map data shape + +To create a grid map, you need to have a query returning a metric summarized by binned latitude/longitude coordinates. + +![Example of data for grid map](../images/latlong-binned-result.png) + +If you're writing a query in the query builder, you can choose how to bin latitude/longitude in the **Group by** block. If you're writing a query in SQL, you'll need to add binning logic yourself. + +![Binned latitude and longitude in the query builder](../images/bin-by-latlong.png) + +### Create a grid map + +To create a grid map: + +1. Build a query with summary by binned latitude and longitude columns (either in the query builder or using SQL); +2. Select **Visualization**, and pick **Map**; +3. If your query results have columns whose field type is set to latitude/longitude in [table metadata](../../data-modeling/metadata-editing#field-type), Metabase should build a grid map automatically. + + Otherwise, click on the **Gear** icon to go to visualization settings, choose **Map type: grid map**, and pick columns that contain latitude and longitude coordinates. + +4. If your query contains several metrics, you can pick the one you want to display in visualization settings. + +## Region maps + +Region maps display a distribution of aggregated data broken out by regions, like count of users by country. + +Metabase comes with two built-in regions: [world map](#world-map) with countries, and the [Unites States map](#united-states-map) with states. Admins can [add custom regions](#custom-regions) in Admin setting. + +![Three types of region maps](../images/region-maps.png) + +You can disable the default regions by setting the environment variable [`MB_DEFAULT_MAPS_ENABLED`](../../configuring-metabase/environment-variables#mb_default_maps_enabled). + +### Region map data shape + +To build a region map, you need a query (either a question built with the query builder, or a native query) with at least two columns: the column with the region name and the column with the metric that you want to display by region. + +![Region map query example](../images/region-map-query.png) + +The region name in the query results must be an exact case-sensitive match to the region name: two-letter country code for world maps, two-letter state code or state name for the United States map, or the [region identifier](../../configuring-metabase/custom-maps) in the custom region. + +To build a region map, you must have a column with a region name in your query results, even if your query results also have latitude/longitude coordinates. Metabase can't infer regions from latitude/longitude coordinates, and doesn't check whether the coordinates of a datapoint are consistent with the region for that data point. + +### Create a region map + +To create a region map: + +1. Build a query with summary by region name (either in the query builder or using SQL). +2. Select **Visualization**, and pick **Map**; +3. Choose **Map type: region**; +4. Pick the region map: world map (built-in), United States (built-in), or +5. Pick the column with the region name in **Region field** +6. If your query contains several metrics, you can pick the one you want to display in **Metric field**. + +You can change the base color used for the region map, but you can't currently use custom color gradients (for example, red to green), or change how Metabase bins the metric. + +### World Map + +To visualize your results in the format of a map of the world broken out by country, your result must contain a column with [two-letter ISO country codes](/glossary/country_code), like "US" or "BR", for example: + +| Country code | Metric | +| ------------ | ------ | +| US | 36 | +| BR | 25 | +| IN | 62 | +| RO | 78 | + +The country codes in the query results must match the two-letter codes exactly: if the country codes are lowercase or contain extra spaces, Metabase won't recognize them. + +If your query result has columns with [semantic type](../../data-modeling/metadata-editing#field-type) "Country", Metabase should build a world map automatically. Otherwise, you can choose which columns to use as the country name in the **Region field** visualization setting. + +You can connect the country column in the world region map to a "Location" type dashboard filter. + +### United States map + +Creating a map of the United States from your data requires your results to contain a column that contains names of states or two-letter state codes, for example "NM" or "New Mexico", for example: + +| State | Metric | +| ---------- | ------ | +| California | 45 | +| New York | 56 | +| Texas | 34 | +| Illinois | 67 | + +If your query result has columns with [semantic type](../../data-modeling/metadata-editing#field-type) "State", Metabase should build a US map automatically. Otherwise, you can choose which columns to use as the country name in the visualization settings. + +You can connect the state column in the US region map to a "Location" type dashboard filter. + +### Custom regions + +Admins can add more regions - like Brazil states or NYC neighborhoods - by [adding custom GeoJSON maps](../../configuring-metabase/custom-maps) in **Admin settings**. Once custom maps have been added, you'll be able to select them when building a region map in map settings. + +![Select a custom region](../images/select-region-map.png) + +Your query results must contain a column with values that match the _region identifier_ property in the custom map setting (not the region display name). + +If you want to connect the region column in a custom region map to a dashboard filter, you'll need to use a "Text or Category" - not "Location" - dashboard filter type. + +## Working with maps + +### Drill-through + +- **Pin map**: If the pin is linked to other tables, or there's too much information to fit in the tooltip, clicking on the pin will take you to a details page that displays a list of fields, as well as a list of connected tables. +- **Grid map**: If you click on a grid cell, you'll get an option to zoom in further into a cell. +- **World region map and US states region maps**: If your unaggregated data also contains latitude/longitude coordinates for each data point (in addition to the region name), then you'll get an option to zoom into a specific region, which will create a grid map of data points in that region binned by latitude/longitude. This only applies to the built-in region maps, not custom region maps. + +### Save as default view + +On pin and grid maps, the map resets to the default view every time the page is refreshed. To control what is displayed when someone opens a map (e.g. center around a specific point, with a specific level of zoom), adjusted your map orientation. This will be the new default view that the map returns to after a page refresh. + +### Draw box to filter + +On pin and grid maps, filter boxes allow you to zoom in or filter data by a specific area. + +You can click **Draw box to filter** and mouse over the map. To outline a section of the map, hold your mouse down and drag across the map to create a transparent blue box. Once you've outlined your target area, release your mouse, and your map will update to filter for data in the selected area. If you've set a default view, the view will remain stationary. If no default view is set, the view will zoom in on the selected area. + +Drawing a box will add filters to your query. + +## Customizing map tiles + +Admins can customize the background tiles that are used for pin and grid maps, see [Changing the Map tile server](../../configuring-metabase/custom-maps#map-tile-server). + +![Default and satellite tiles](../images/map-tiles.png) + +Currently, Metabase uses a single tile server per instance. You can't specify different tiles for different maps. + +## Limitations + +- Currently, you can't customize the following visualization settings on maps: + + - The color or pins on a pin map; + - The color of bins on the grid map; + - The number of size of bins for region maps. + +- You can't combine different types of maps. For example, you can't put pins on a region map. +- You need to use category (not location) dashboard filter types when connecting custom region maps to dashboard filters. +- You can't specify different background tiles for different maps. + + +## When NOT to use a map to visualize geographic data + +If the relative locations of regions on the map aren't the main focus of your visualization, consider using a bar or row chart instead. For example, sales by state are often better represented as a row or bar chart rather than a region map. + +![Bar chart as alternative to map](../images/map-alternative.png) diff --git a/_docs/doc-update-detection/questions/visualizations/numbers.md b/_docs/doc-update-detection/questions/visualizations/numbers.md new file mode 100644 index 000000000..8b1f3d64f --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/numbers.md @@ -0,0 +1,21 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Numbers +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/numbers.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/numbers +--- + +# Numbers + +The **Numbers** option is for displaying a single number, nice and big. The options for numbers include: + +![Number](../images/number.png) + +- **Adding character prefixes or suffixes** to it (so you can do things like put a currency symbol in front or a percent at the end), +- **Setting the number of decimal places** you want to include, and +- **Multiplying your result by a number** (like if you want to multiply a decimal by 100 to make it look like a percent). If you want to _divide_ by a number, then just multiply it by a decimal (e.g, if your result is `100`, but you want it to display as `1`, simply multiply it by 0.01). diff --git a/_docs/doc-update-detection/questions/visualizations/pie-or-donut-chart.md b/_docs/doc-update-detection/questions/visualizations/pie-or-donut-chart.md new file mode 100644 index 000000000..2cdc0ad33 --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/pie-or-donut-chart.md @@ -0,0 +1,109 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Pie and sunburst charts' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/pie-or-donut-chart.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/pie-or-donut-chart +--- + +# Pie and sunburst charts + +A **pie chart** can be used when breaking out a metric by a single dimension. In Metabase, pies are donuts. A **sunburst chart** is a multi-dimensional pie chart with multiple breakouts. + +![Pie and sunburst charts](../images/pie-sunburst-demo.png) + +## When to use a pie or sunburst chart + +Pie charts can be used to visualize a metric as part of a whole. Sunburst charts can be used to visualize hierarchical or nested data, or display multiple levels of categorization. + +Pie and sunburst charts work best when when the number of possible breakout values is small, like accounts by plan. These charts should only be used to visualize metrics that add up to 100% (like count or sum of total). + +Pie charts should be used to communicate a general sense of the relative sizes of breakouts. If precise comparison is important so people can see the exact differences between values, or you have more than a few breakouts (like customers per country), it's usually better to use a bar or row chart. + +## How to create a pie or sunburst chart + +Pie and sunburst charts display a single metric across one or more breakouts. Both pie/donut charts and sunburst charts are available in the "Pie chart" option in the visualization sidebar. + +For a simple pie chart, you'll need a query with a single breakout and metric, for example: + +| Type | Sum of Quantity | +| ---- | --------------- | +| Cat | 23 | +| Bird | 14 | +| Dog | 35 | + +If your query has multiple metrics, you'll be able to choose the metric for the chart in [chart settings](#pie-and-sunburst-chart-settings). + +![Plain pie](../images/plain-pie.png) + +For a sunburst (multi-dimensional pie) chart, you'll need a query with up to three breakouts and a numerical metric. Here's an example of a query result with two breakouts, `Type` and `Subtype`: + +| Type | Subtype | Sum of Quantity | +| ---- | ------- | --------------- | +| Cat | Siamese | 4 | +| Cat | Persian | 12 | +| Cat | Bengal | 7 | +| Bird | Crow | 5 | +| Bird | Parrot | 9 | +| Dog | Corgi | 10 | +| Dog | Poodle | 13 | +| Dog | Bulldog | 7 | +| Dog | Husky | 5 | + +You can choose which breakouts to assign to the inner, middle, or outer rings of the sunburst chart in [chart "Data" settings](#data-settings). If your query has multiple metrics, you'll also be able to choose which metric to display. Here's the sunburst chart for the example table above: + +![Sunburst with two levels](../images/sunburst-two-levels.png) + +You don't need to include the percentages in your query. Metabase will automatically compute the percentage of the total for each value of the metric (for example, Metabase will compute that 23 Cats make up 31.9% of all pets). + +## Pie and sunburst chart settings + +To open the chart options, click on the gear icon at the bottom left of the screen. This will open a settings sidebar with **Data** and **Display** tabs. + +### Data settings + +You can rename, reorder, or remove slices from the inner ring of a sunburst or pie chart. To reorder the pie slices, drag the cards with the slice names. To rename the slices, click on three dots next to the series name and enter a new name. + +To change the color of the pie slices, click on the color circle next to the slice's name. In sunburst charts, you can only change the color of the slices in the _inner_ ring (the slices in the outer rings inherit the colors of their parent slices). + +If your query has multiple metrics (columns), you can pick the column that should be depicted on the chart in the **Measure** dropdown. + +To format the total displayed in the middle of the chart, click on the three dots next to the metric name in the **Measure** setting. The measure format options — including the "number of decimal places" option — will only apply to the total, and not to the percentage values or labels. To configure the display of the percentage values and labels, go to the [display settings](#display-settings) tab. + +![format sunburst](../images/sunburst-metric-options.png) + +### Display settings + +You can configure whether to show: + +- The legend next to the chart. +- The total in the center of the chart. The format of the total can be changed in the [data settings](#data-settings). +- The labels for the pie slices. The labels for the inner ring slices can be changed in the [data settings](#data-settings). + + For sunburst charts with multiple breakouts, only the inner ring breakout will be displayed in the legend. By default, "Show labels" will be turned on. If you turn off "Show labels", the only way to distinguish slices on a sunburst chart will be to hover over them. + +- The percentage values for the slices. If you choose to display percentages **In the legend**, but then toggle off **Show legend**, the percentage values won't show up on the chart. + + You can always see percentage values for any slice by hovering over the slice. + +To change the number of decimal places in the percentage values, use the **Number of decimal places** setting in the **Display** tab. If you want to change the number of decimal places for the total in the center of the chart, go to [data settings](#data-settings). + +![Settings showcase](../images/sunburst-settings-showcase.png) + +To make the chart more legible, you can group slices smaller than a certain percentage into one slice by adjusting **Minimum slice percentage**. You'll be able to see the categories and values in the **Other** slice by hovering over it: + +![Other slice](../images/pie-other-slice.png) + +Currently, you can't change the color or label of the **Other** slice. + +## Limitations and alternatives + +Consider using a bar or row chart (or a [stacked bar chart](line-bar-and-area-charts#stacked-bar-chart)) or a [pivot table](pivot-table) instead of a pie or sunburst chart in the following cases: + +- Your data has more than three breakouts +- Your metrics don't add up to 100% (for example, average rating - prefer a gauge chart in that case) +- You have a lot of categories in each breakout diff --git a/_docs/doc-update-detection/questions/visualizations/pivot-table.md b/_docs/doc-update-detection/questions/visualizations/pivot-table.md new file mode 100644 index 000000000..2f5ccf16f --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/pivot-table.md @@ -0,0 +1,46 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Pivot tables' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/pivot-table.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/pivot-table +--- + +# Pivot tables + +Pivot tables allow you swap rows and columns, group data, and include subtotals in your table. You can group one or more metrics by one or more dimensions. + +Pivot tables are not currently available for the following databases in Metabase: + +- Druid +- MongoDB + +Pivot tables work for simple and custom questions with summarized data for all other [officially supported databases](../../databases/connecting). They don't work for questions that lack aggregate data, and they don't work for questions written in SQL, as Metabase would need to modify your SQL code in order to calculate subtotals. If you really need to use SQL, the workaround here is to create your question in two steps: first do all the complex things you need to do in SQL, save the results as a question, then use that saved SQL question as the starting point for a new GUI question which summarizes that data. + +In the settings for the Pivot Table visualization, you can assign fields to one of three "buckets": + +- Fields to use for the table **rows** +- Fields to use for the table **columns** +- Fields to use for the table **values** + +Let's say we ask the following question in the notebook editor: + +![Pivot table notebook](../images/pivot-table-notebook.png) + +From the `Orders` table, we've summarized by the count of orders and the average order total, and grouped by `User → State`, `Product → Category`, and `Created At` binned by year. Here's our question visualized as a pivot table: + +![Pivot table options](../images/pivot-table-options.png) + +We've assigned the fields `User → State` and `Created At` to table rows, and assigned the `Product -> Category` field to generate our columns: Doohickey, Gadget, and so on. We can drag and drop dimensions between the row and column buckets, and add aggregations to the table values bucket. For example, if we assign a field to the columns bucket, Metabase will pivot that field and render each unique value of that field as a column heading. + +You can put multiple fields in the "rows" and "columns" buckets, but note that the order of the fields changes how Metabase displays the table: each additional field will nest within the previous field. + +Where it makes sense, Metabase will automatically include subtotals for grouped rows. For example, as in the image above, because we've grouped our rows first by `State`, then by `Created At`, Metabase will list each year for each `State`, and aggregate the metric(s) for that subgroup. For orders placed in Wisconsin, Metabase would sum the count of orders for each category, and find the average annual order total in each product category in Wisconsin. + +To collapse a group on a pivot table, you can click on the minus (–) button next to the group's heading (or the plus (+) button to expand it). When you save a pivot table, Metabase will remember which groups were expanded and which were collapsed. + +For more, check out [How to create a pivot table to summarize your data](/learn/metabase-basics/querying-and-dashboards/visualization/how-to-create-pivot-tables). diff --git a/_docs/doc-update-detection/questions/visualizations/progress-bar.md b/_docs/doc-update-detection/questions/visualizations/progress-bar.md new file mode 100644 index 000000000..394e6a09c --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/progress-bar.md @@ -0,0 +1,65 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Progress bars' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/progress-bar.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/progress-bar +--- + +# Progress bars + +**Progress bars** are for comparing a single number to a goal value that you set. + +![Progress bar](../images/progress.png) + +## When to use a progress bar + +Progress bars are useful when you want to show the movement of a metric toward a goal, like assessing performance of a KPI, or tracking the percentage of of completion on a project. + +Progress bars give you an option to set up an alert whenever the result of a question reaches the goal set in the progress bar settings. See [Progress bar alerts](../alerts#progress-bar-alerts). + +## How to create a progress bar + +To create a progress bar you'll need: + +- A query that returns a single number, like "Sum of order quantity". Progress bar doesn't work with breakouts. + + You can also use a query that returns several metrics in a single row: + + | Sum of Quantity | Average Quantity | Max Quantity | + | --------------- | ---------------- | ------------ | + | 4910 | 17.32 | 173 | + +In this case, the progress bar chart will use the metric in the first column ("Sum of quantity"). To change the metric, go to the editor and drag the metric you want to the first position in the Summarize block. + +- A goal value. The goal value should be a positive number. Currently, Metabase only supports setting a static goal (you can't set a goal based on another query). + + The goal is set in the [chart options](#progress-bar-options). + +![Progress bar KPI](../images/progress-bar-elements.png) + +## Progress bar options + +To open the chart options, click on the gear icon at the bottom left of the screen. + +Format options will apply to both the result of the query and the goal value: + +![Progress bar with format applied](../images/progress-with-format.png) + +Selecting "**Style**: Percent" in format options will only change how the result of the query is formatted: for example, `17` will be formatted as `1700%`. If you instead want to display the query result as a percentage of the goal, you'll need to calculate that percentage in your query. For example, to display the count of orders as a percentage of the goal of `20`, use [custom expressions](../query-builder/expressions) to return "Count of orders divided by 20", and format the result as a percentage. + +## Limitations and alternatives + +- Progress bars assume that your objective is to _increase_ a metric. If the objective is to decrease or reduce a metric, consider using the [gauge chart](gauge). + +- Progress bars don't support breakouts. If you'd like to display progress of a metric towards a goal across a breakout, consider using a [bar or line chart with a goal line](line-bar-and-area-charts#goal-lines). + +## Further reading + +- [Gauge charts](./gauge) +- [Goal lines on bar and line charts](./line-bar-and-area-charts#goal-lines) +- Tutorial: [Which chart should I use?](/learn/metabase-basics/querying-and-dashboards/visualization/chart-guide) diff --git a/_docs/doc-update-detection/questions/visualizations/sankey.md b/_docs/doc-update-detection/questions/visualizations/sankey.md new file mode 100644 index 000000000..4a50f14fd --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/sankey.md @@ -0,0 +1,93 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Sankey charts' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/sankey.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/sankey +--- + +# Sankey charts + +Sankey charts show how data flows through multi-dimensional steps. They're useful for showing which elements, called nodes, contribute to the overall flow. + +![Left-aligned sankey chart](../images/sankey-left-aligned.png) + +## Sankey data shape + +To create a Sankey chart, you'll need at least three columns in your results: + +- **Source column**: specifies a node in the Sannkey flow. +- **Target column**: specifies a receiving node. +- **Count column**: value that determines the thickness of the target node. + +If you had raw page views where each row had a source page (like the title of a referrer page) and a target page (like the title for the current page view), you could summarize by count and group by the source, then the target. + +![Sankey summarize count and group by source and target](../images/sankey-summarize-count-source-target.png) + +Here's the data shape used to create the chart above. + +| Source page | Target page | Total Visitors | +| ------------ | ------------ | -------------- | +| Entry | Homepage | 584 | +| Homepage | Product Page | 2,700 | +| Product Page | Add to Cart | 572 | +| Add to Cart | Checkout | 2,490 | +| Checkout | Purchase | 1,756 | +| Homepage | Search | 2,427 | +| Search | Product Page | 2,027 | +| Product Page | Add to Cart | 2,203 | +| Add to Cart | Checkout | 1,475 | +| Search | Product Page | 1,563 | +| Checkout | Purchase | 1,041 | +| Homepage | Exit | 810 | +| Product Page | Checkout | 815 | +| Checkout | Purchase | 2,217 | +| Homepage | Exit | 1,020 | + +See [data options](#sankey-data-options). + +### Circular dependencies won't work + +If some of your sources point to targets that point back to the same sources, Metabase won't be able to create a Sankey chart. + +## Sankey data options + +To select which columns Metabase should use as the source, target, and values for the Sankey chart, click on the **settings** icon in the bottom right to view the **Data** tab. + +![Sankey data options](../images/sankey-data-options.png) + +Your data can include more than three columns, but each row must include the required three columns: source, target, and a value to scale the size of the target node. + +## Sankey display options + +You can change a charts alignment, edge labels, and edge colors. + +### Alignment + +You can select left, right, or justified alignment for the Sankey chart. Alignment determines how the chart should display the end nodes (a.k.a. leaf nodes or terminal nodes). + +The chart in the section above is left-aligned. The end nodes, `Exit` and `Purchase`, are aligned to the left. + +For right alignment, the end nodes, `Exit` and `Purchase`, move to the chart's right: + +![Right-aligned sankey chart](../images/sankey-right-aligned.png) + +In this case, justified alignment looks the same, as the end nodes move to take up the whole chart. + +### Edge labels + +Whether an edge (a.k.a. link or arrow) displays its value. Options for displaying labels include auto, compact, or full formatting. + +### Edge color + +![Sankey gray edges](../images/sankey-gray-edges.png) + +Options for edge colors include: + +- **Gray**: All edges are gray. Nodes retain their color. +- **Source**: The source node determines the edge colors. The source node is the node to the left of an edge. +- **Target**: The target node determines the edge colors. The target node is the node to the right of an edge. diff --git a/_docs/doc-update-detection/questions/visualizations/scatterplot-or-bubble-chart.md b/_docs/doc-update-detection/questions/visualizations/scatterplot-or-bubble-chart.md new file mode 100644 index 000000000..de8d82340 --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/scatterplot-or-bubble-chart.md @@ -0,0 +1,21 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Scatterplots and bubble charts' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/scatterplot-or-bubble-chart.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/scatterplot-or-bubble-chart +--- + +# Scatterplots and bubble charts + +**Scatterplots** are useful for visualizing the correlation between two variables, like comparing the age of your users vs. how many dollars they've spent on your products. To use a scatterplot, you'll need to ask a question that results in two numeric columns, like `Count of Orders grouped by Customer Age`. Alternatively, you can use a table and select the two numeric fields you want to use in the chart options. + +If you have a third numeric field, you can also create a **bubble chart**. Select the Scatter visualization, then open up the chart settings and select a field in the **bubble size** dropdown. This field will be used to determine the size of each bubble on your chart. For example, you could use a field that contains the total dollar amount for each x-y pair — i.e. larger bubbles for larger total dollar amounts spent on orders. + +Scatterplots and bubble charts also have similar chart options as line, bar, and area charts, including the option to display trend or goal lines. + +![Scatter](../images/scatter.png) diff --git a/_docs/doc-update-detection/questions/visualizations/table.md b/_docs/doc-update-detection/questions/visualizations/table.md new file mode 100644 index 000000000..9c8817663 --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/table.md @@ -0,0 +1,286 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Tables +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/table.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/table +--- + +# Tables + +The **Table** option is good for looking at tabular data (duh), or for lists of things like users or orders. The visualization options for tables allow you to add, hide, or rearrange fields in the table you're looking at, as well as modify their formatting. Check out [Everything you can do with the table visualization](/learn/metabase-basics/querying-and-dashboards/visualization/table). + +## Rearranging, adding, and removing columns + +Open up the settings for your table visualization and you'll see the Columns tab, which displays all the columns currently being shown in the table. To hide a column, click the eye icon. + +To manage these columns, including columns from linked tables, just click **add or remove columns**. Check the boxes next to the columns you want to show in the **visible section**, or uncheck to hide them. + +When viewing tables, you can click on the **gear** icon in the bottom left to bring up the columns picker. Click **Add or remove columns** to search for and pick columns, including columns from related tables. + +![Adding or removing columns](../images/column-selection.png) + +Admins (and people in groups with access to table metadata) can hide columns across your entire Metabase by marking them as hidden in the [table metadata settings](../../data-modeling/metadata-editing#column-visibility). + +> **Hiding columns should _not_ be used to secure sensitive information**. Hiding columns in table visualization settings only affects the visibility of the columns _in the visualization_, not in the query results. Even people with view-only permissions to the question will be able to change the visualization settings and unhide columns. To exclude a column from the results of a specific query, uncheck the column in the "Data" block of the query builder. + +To rearrange the order of the columns, simply click and drag any of the columns in the sidebar. You can also click on a column's heading in the table and drag the column to another position in the table. + +## Add row numbers to a table + +To number the rows of a table, click on the **gear** icon in bottom left to bring up the table formatting sidebar. In the **Columns** tab, and toggle on **Show row index**. Metabase will add a column to the left of the table displaying a number for each row. + +![Add row numbers to a table](../images/show-row-index.png) + +## Resize columns + +To change the width of a column, you can click and drag the edges of the column's header. + +## Column heading options for filtering and summarizing + +Click on a column heading and Metabase will present quick options for filtering and summarizing the data. The options for the column depend on the column's data type (ID, Text, Number, Date). + +### Filter by this column + +You can enter a value and filter the column value: + +Text filters: + +- Is / Is not +- Contains / Does not contain +- Starts with / Ends with +- Is empty / Not empty + +Number filters: + +- Between +- Greater than / Less than +- Greater than or equal to / Less than or equal to +- Equal to / Not equal to +- Is empty / Not empty + +### Distribution + +Clicking on Distribution will summarize the data by counting the rows and grouping the counts by the values in the column. + +### Distinct values + +Get a count of unique values. + +### Combine columns + +You can combine one or more text columns. For example, a first name column with a last name column. + +You can tell Metabase how to combine the columns by specifying a separator, like a space, or comma, or the word "Danger". + +### Extract day, month... + +From a datetime, you can grab: + +- **Hour of day**: 0, 1, 2... +- **Day of month**: 0, 1, 2... +- **Day of week**: Monday, Tuesday... +- **Month of year**: Jan, Feb... +- **Quarter of year**: Q1, Q2... +- **Year**: 2024, 2025... + +### Extract domain, subdomain, host, or path + +Grab the domain or host from a URL or email. So if you have `https://www.example.com/path/to/page#heading-on-page`: + +- Host: `example.com` +- Domain: `example` +- Subdomain: `www` +- Path: `/path/to/page` + +> Extracting parts of a URL or email is unavailable for MongoDB, SQLite, and SQL Server. For Druid, extracting domain and host is only available for the Druid-JDBC driver. + +### Sum over time + +Add up all the values and group by a time period, generally by month. + +## Column formatting options + +To format the display of any column in a table, click on the column heading and choose the `Formatting` option (you can also get there by clicking on the gear on any column when in the `Columns` tab of the visualization settings). + +![Column formatting](../images/column-header-formatting.png) + +The options you see will differ depending on the type of column you're viewing: + +## Text formatting options + +### Title + +You can rename the column. + +## Align text + +You can display the text on the left, right, or in the middle (i.e., centered) of the column. + +## Wrap text + +You can toggle text wrapping, which is useful for columns with long text values like comments. + +### Display as + +You can display a column as: + +- Text +- [Link](#display-text-as-a-link) +- Email link +- [Image](#display-url-as-an-image) +- Automatic (Metabase guesses based on the values). + +#### Display text as a link + +If you select link, you can also change the text displayed, and use parameters for both the link text and the link's URL. + +For example, you could create a dynamic URL using a parameter from another column in the results: + +```html +{% raw %} https://www.example.com/{{category}} {% endraw %} +``` + +In the above example, Metabase would take the value for the `category` column for that row (in this case `widget`), and insert it into the URL: + +```html +https://www.example.com/widget +``` + +#### Display URL as an image + +If you select image, and the text is a link to an image asset, Metabase will display the image in the table cell. + +## Date formatting options + +Date formatting options include the same options as [Text formatting](#text-formatting-options), as well as: + +### Align date + +You can display the date on the left, right, or in the middle (i.e., centered) of the column. + +### Date style + +Styles include: + +- April 1, 2024 +- 1 April 2024 +- Monday, April 1, 2024 +- 4/1/2024 +- 1/4/2024 +- 2024/4/1 + +### Abbreviate days and months + +If you select a date style that includes words, this toggle will abbreviate them. For example: + +- Unabbreviated: Monday, April 1, 2024 +- Abbreviated: Mon, Apr 1, 2024 + +### Show the time + +This option determines whether Metabase includes the time along with the date. + +- Off +- HH:MM +- HH:MM:SS +- HH:MM:SS:MS + +### Time style + +You can choose either 12-hour clock style, or 24-hour clock style. + +- 5:24 PM (12-hour clock) +- 17:24 (24-hour clock) + +## Number formatting options + +### Show a mini bar chart + +This option displays a small horizontal bar next to each number in this column to show its size relative to the other values in the column. + +### Style + +Number styles include: + +- Number +- Percent +- Scientific +- Currency + +### Separator style + +Gives you various options for how commas and periods are used to separate the number. + +- 100,000.00 +- 100 000,00 +- 100.000,00 +- 100000.00 +- 100'000.00 + +### Number of decimal places + +Forces the number to be displayed with exactly this many decimal places. + +### Multiply by a number + +Multiplies each number in this column by whatever you type here. Just don't type an emoji here; there is a nontrivial chance that it will manifest a temporal vortex. + +### Add a prefix/suffix + +Lets you put a symbol, word, or whatever before or after each cell's value. + +## Currency formatting options + +Currency columns have all the same options as [numbers](#number-formatting-options), plus the following: + +### Unit of Currency + +Lets you change the unit of currency from whatever the system default is. + +### Currency label style + +Allows you to switch between displaying the currency label as: + +- a symbol (like $) +- a code (like USD) +- the full name of the currency (like "US dollars") + +### Where to display the unit of currency + +Lets you toggle between showing the currency label in the column heading or in every cell in the column. + +## Conditional table formatting + +Sometimes it's helpful to highlight certain rows or columns in your tables when they meet a specific condition. You can set up conditional formatting rules by going to the visualization settings while looking at any table, then clicking on the **Conditional Formatting** tab. + +![Conditional formatting](../images/conditional-formatting.png) + +When you add a new rule, you'll first need to pick which column(s) should be affected. Your columns can be formatted in one of two ways: + +- **Single color**. Pick single color if you want to highlight cells in the column if they're greater, less than, or equal to a specific number, or if they match or contain a certain word or phrase. You can optionally highlight the whole row of a cell that matches the condition you pick so that it's easier to spot as you scroll down your table. +- **Color range**. Choose color range if you want to tint all the cells in the column from smallest to largest or vice versa. This option is only available for numeric columns. + +You can set as many rules on a table as you want, and change the order in which those rules are applied. If two or more rules disagree with each other, the rule that's on the top of your list of rules will win. You can click and drag your rules to reorder them, and click on a rule to edit it. + +## Table pagination on dashboard cards + +When you add a table to dashboard, the table will be scrollable by default. You can paginate the rows by: + +1. Clicking on the **Pencil** icon to edit the dashboard. +2. Hovering over the dashcard containing the table, and clicking the **Visualization** icon. +3. In the **Columns** tab, toggle on **Paginate results**. + +![Paginate table results on dashboard card](../images/paginate-table-on-dashboard-card.png) + +### Pivoted tables + +> This auto-pivoting is distinct from the [pivot table](./pivot-table) visualization. + +If your table is a result that contains one numeric column and two grouping columns, Metabase will also automatically "pivot" your table, like in the example below. Pivoting takes one of your columns and rotates it 90 degrees ("pivots" it) so that each of its values becomes a column heading. If you open up the visualization settings by clicking the gear icon, you can choose which column to pivot in case Metabase got it wrong; or you can also turn the pivoting behavior off entirely. + +![Pivot table](../images/pivot.png) diff --git a/_docs/doc-update-detection/questions/visualizations/tooltips.md b/_docs/doc-update-detection/questions/visualizations/tooltips.md new file mode 100644 index 000000000..6aea07d79 --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/tooltips.md @@ -0,0 +1,37 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Tooltips +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/tooltips.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/tooltips +--- + +# Tooltips + +When you hover over a data point on a chart in Metabase, you'll see a tooltip about that data. + +![Tooltip](../images/tooltip.png) + +## Customizing tooltips with multiple metrics + +On line, bar, and area charts, you can display the values from multiple metrics either on the chart, or in the tooltips that Metabase adds to the data points on hover. + +For example, if you have a question with two metrics (i.e., two summarizations - they don't have to be Metabase [metrics](../../data-modeling/metrics)), like this question that has both the count and average of subtotal: + +![Question with multiple summarizations](../images/multiple-metrics.png) + +You can display the summarizations like so, with both the count and average on the chart. + +![Count and average](../images/count-and-average.png) + +Or you could display one of the metrics on the chart, and include the other metric(s) in the tooltip. To do this, remove one of the metrics from the chart by going to the **Data** tab in the visualization settings and clicking the X on the metric(s) you want to remove. + +Removing a metric will give you the option to add it as an additional metric to the tooltip. In the visualization settings, click on the **Display** tab, and add **Additional tooltip metrics**. Only metrics included in the summarization step of the question are available to add to the tooltip. + +![Add additional tooltip metrics from the display tab. Only available when your chart has multiple multiple metrics](../images/metrics-in-tooltip.png) + +Here we've kept the count on the chart, but now when you hover over a bar on the chart, the tooltip also includes the relevant average. diff --git a/_docs/doc-update-detection/questions/visualizations/trend.md b/_docs/doc-update-detection/questions/visualizations/trend.md new file mode 100644 index 000000000..e45d7526c --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/trend.md @@ -0,0 +1,40 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: Trend +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/trend.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/trend +--- + +# Trend + +![Trend settings](../images/trend-settings.png) + +The **Trend** visualization is great for displaying how a single number compares with: + +- Previous time period(s). +- Custom values, like a target or goal. +- Values from another column. + +To use this visualization, you'll need to have a single number grouped by a Time field, like the Count of Orders by Created At. + +By default, the Trend chart will display the value of the number during the most recent period, as well as how much the number has increased or decreased compared to its value in the previous period. The period is determined by your group-by field; if you're grouping by Day, the Trend will show you the most recent day compared to the day before that. + +By default, Trends will display increases as green (i.e., "good") and decreases as red ("bad"). If your number is something where an increase is bad and a decrease is good (such as Bounce Rate, or Costs), you can reverse this behavior in the visualization settings. + +## Adding comparisons + +![Add comparison to a trend chart](../images/add-comparison.png) + +To add a comparison, click on the **gear** icon in the lower left (next to Visualization). In the **Data** tab in the left sidebar, click **Add comparison**. You can select from: + +- **Previous time period** +- **Previous value**. If there is no previous value, Metabase will ignore the value so the chart doesn't show a comparison with a null value. +- **Custom value**. +- **Value from another column**. Metabase will only show this option if your results contain multiple columns with aggregate values in your results (e.g., if you have two Summarize columns). + +You can add up to three comparisons. diff --git a/_docs/doc-update-detection/questions/visualizations/visualizing-results.md b/_docs/doc-update-detection/questions/visualizations/visualizing-results.md new file mode 100644 index 000000000..be832bba3 --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/visualizing-results.md @@ -0,0 +1,183 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Visualization overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/visualizing-results.md' +redirect_from: + - /docs/doc-update-detection/users-guide/05-visualizing-results + - /docs/doc-update-detection/questions/sharing/visualizing-results +--- + +# Visualization overview + +While tables are useful for looking up information or finding specific numbers, it's usually easier to see trends and make sense of data using charts. + +## Visualize query results + +The query builder will automatically select an appropriate chart to visual your results. With native queries, however, you'll need to manually select a chart type. +### Visualizing questions in the query builder + +To visualize results of a question built in the [query builder](../query-builder/editor), click on the **Visualize** button under the last query builder step. Metabase will select a chart type most appropriate for your data, but you can [change the visualization type](#change-visualization-type). You can also toggle between the visualization and the table of results. + +You can switch between the visualization view and the query builder using the **Visualization**/**Editor** button in the top right. + +![Switch to editor](../images/switch-to-editor.png) + +### Visualizing native questions + +To visualize results of a native query, click on the **Visualization** button in the bottom of the screen and select a visualization type. + +![Visualize a native query](../images/visualize-native.png) + +As long as the shape of the native query results is appropriate for the chart type - for example, a metric grouped by a date column for a trend chart - you'll be able to use to use all chart types, except [pivot tables](./pivot-table). [Pivot tables](./pivot-table) are currently unavailable for native queries. + +## Change visualization type + +To change how the answer to your question is displayed, click on the **Visualization** button in the bottom-left of the screen to open the visualization sidebar. + +![Visualization options](../images/VisualizeChoices.png) + +If a particular visualization doesn’t really make sense for your answer, that option will appear in the "Other charts" section. You can still select one of these other charts, though you might need to fiddle with the chart options to make the chart work with your data. + +Not sure which visualization type to use? Check out [Which chart should you use?](/learn/metabase-basics/querying-and-dashboards/visualization/chart-guide) + +## Visualization options + +![Options for a chart](../images/viz-options.png) + +Each visualization type has its own advanced options. To change the settings for a specific chart, for example a row chart, click on the **Gear** button in the bottom left. + +## Area charts + +[Area charts](./line-bar-and-area-charts) are useful when comparing the proportions of two metrics over time. Both bar and area charts can be stacked. + +![Stacked area chart](../images/area.png) + +## Bar charts + +[Bar charts](./line-bar-and-area-charts) are great for displaying a number grouped by a category (e.g., the number of users you have by country). + +![Bar chart](../images/bar.png) + +## Combo charts + +[Combo charts](./combo-chart) let you combine bars and lines (or areas) on the same chart. + +![Line + bar](../images/combo-chart.png) + +## Detail + +The [Detail](./detail) visualization shows a single result record (row) in an easy-to-read, two-column display. + +![Detail of a record in the account table](../images/detail.png) + +## Funnel charts + +[Funnels](./funnel) are commonly used in e-commerce or sales to visualize how many customers are present within each step of a checkout flow or sales cycle. At their most general, funnels show you values broken out by steps, and the percent decrease between each successive step. + +![Funnel](../images/funnel.png) + +## Gauges + +[Gauges](./gauge) allow you to show a single number in the context of a set of colored ranges that you can specify. + +![Gauge](../images/gauge.png) + +## Line charts + +[Line charts](./line-bar-and-area-charts) are best for displaying the trend of a number over time, especially when you have lots of x-axis values. For more, check out our [Guide to line charts](/learn/metabase-basics/querying-and-dashboards/visualization/line-charts) and [Time series analysis](/learn/metabase-basics/querying-and-dashboards/time-series) tutorials. + +![Trend lines](../images/trend-lines.png) + +## Maps + +When you select the [Map](./map) visualization, Metabase will automatically try and pick the best kind of map to use based on the table or result set. + +![Region map](../images/map.png) + +## Numbers + +The [Numbers](./numbers) option is for displaying a single number, nice and big. + +![Number](../images/number.png) + +## Pie, donut, and sunburst charts + +A [pie chart or donut chart](./pie-or-donut-chart) can be used when breaking out a metric by a single dimension, especially when the number of possible breakouts is small, like accounts by plan. + +A [sunburst chart](./pie-or-donut-chart) is a pie chart with more than one ring to show the data broken out by additional dimensions. + +![Donut](../images/pie-sunburst-demo.png) + +## Pivot tables + +[Pivot tables](./pivot-table) allow you swap rows and columns, group data, and include subtotals in your table. You can group one or more metrics by one or more dimensions. + +![Pivot table options](../images/pivot-table-options.png) + +## Progress bars + +[Progress bars](./progress-bar) are for comparing a single number to a goal value that you set. + +![Progress bar](../images/progress.png) + +## Row charts + +[Row charts](./line-bar-and-area-charts) are good for visualizing data grouped by a column that has a lot of possible values, like a Vendor or Product Title field. + +![Row chart](../images/row.png) + +## Tables + +The [Table](./table) option is good for looking at tabular data (duh), or for lists of things like users or orders. + +![Conditional formatting](../images/conditional-formatting.png) + +## Trends + +The [Trend](./trend) visualization is great for displaying how a single number has changed between two time periods. + +![Trend settings](../images/trend-settings.png) + +## Histograms + +If you have a bar chart like Count of Users by Age, where the x-axis is a number, you'll get a special kind of bar chart called a [histogram](./line-bar-and-area-charts) where each bar represents a range of values (called a "bin"). + +![Histogram](../images/histogram.png) + +## Sankey charts + +[Sankey charts](./sankey) show how data flows through multi-dimensional steps. + +![Left-aligned sankey chart](../images/sankey-left-aligned.png) + +## Waterfall charts + +[Waterfall charts](./waterfall-chart) are a kind of bar chart useful for visualizing results that contain both positive and negative values. + +![Waterfall chart](../images/waterfall-chart.png) + +## Scatterplots and bubble charts + +[Scatterplots](./scatterplot-or-bubble-chart) are useful for visualizing the correlation between two variables, like comparing the age of your people using your app vs. how many dollars they've spent on your products. + +![Scatter](../images/scatter.png) + +## Styling and formatting data in charts + +![Chart formatting options](../images/chart-formatting-options.png) + +You can access formatting options for the columns used in a chart. Just open the visualization settings by clicking on the **Gear** icon in bottom left. + +Options differ depending on the chart, and can include settings for the chart's data, its display, and its axes. + +See also [Formatting defaults](../../data-modeling/formatting). + +## Further reading + +- [Charts with multiple series](../../dashboards/multiple-series) +- [Appearance](../../configuring-metabase/appearance) +- [BI dashboard best practices](/learn/metabase-basics/querying-and-dashboards/dashboards/bi-dashboard-best-practices) diff --git a/_docs/doc-update-detection/questions/visualizations/waterfall-chart.md b/_docs/doc-update-detection/questions/visualizations/waterfall-chart.md new file mode 100644 index 000000000..f348f6f16 --- /dev/null +++ b/_docs/doc-update-detection/questions/visualizations/waterfall-chart.md @@ -0,0 +1,21 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: Questions +title: 'Waterfall charts' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/questions/visualizations/waterfall-chart.md' +redirect_from: + - /docs/doc-update-detection/questions/sharing/visualizations/waterfall-chart +--- + +# Waterfall charts + +Waterfall charts are a kind of bar chart useful for visualizing results that contain both positive and negative values. Each bar on a waterfall chart shows either an increase or decrease, with a final bar on the right of the chart that represents the total value. + +![Waterfall chart](../images/waterfall-chart.png) + +In the example above, the waterfall chart displays "Profit" for each "Product:" apples, bananas, oranges, peaches, and mangos. From left to right, each bar indicates the change in total. The products with green bars indicate positive values (they made a profit). Peaches, however, lost money, indicated by a red bar, which signals a negative value. The bar at the end shows the total profit of all products combined. You can show values on each bar, and change the colors for increases and decreases. + +For waterfall charts, you'll want a query that is a single metric grouped by a single dimension: by time or category. diff --git a/_docs/doc-update-detection/troubleshooting-guide/bigquery-drive.md b/_docs/doc-update-detection/troubleshooting-guide/bigquery-drive.md new file mode 100644 index 000000000..99f414ac9 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/bigquery-drive.md @@ -0,0 +1,27 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting BigQuery and Google Drive connections in Metabase' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/bigquery-drive.md' +--- + +# Troubleshooting BigQuery and Google Drive connections in Metabase + +[This page](../databases/connections/bigquery) explains how to connect a BigQuery data source, including one that uses a file stored in Google Drive, like a Google Sheet (GSheets). + +## 403 Forbidden POST error + +If you encounter an error that looks like this: + +``` +403 Forbidden POST https://www.googleapis.com/bigquery/v2/projects/PROJECT-NAME/queries { "code" : 403, "errors" : [ { "domain" : "global", "message" : "Access Denied: BigQuery BigQuery: Permission denied while getting Drive credentials.", "reason" : "accessDenied" } ], "message" : "Access Denied: BigQuery BigQuery: Permission denied while getting Drive credentials.", "status" : "PERMISSION_DENIED" } +``` + +You may have forgotten to [share your Google Drive source](../databases/connections/bigquery#share-your-google-drive-source-with-the-service-account) with the service account email. Once that's been fixed, that error should disappear and you'll be able to view and query your data source. + +## Further reading + +- [Troubleshooting database connections](./db-connection) diff --git a/_docs/doc-update-detection/troubleshooting-guide/bugs.md b/_docs/doc-update-detection/troubleshooting-guide/bugs.md new file mode 100644 index 000000000..61ce634b9 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/bugs.md @@ -0,0 +1,27 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Reporting a bug' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/bugs.md' +--- + +# Reporting a bug + +If you come across something that looks like a bug, please start by searching our [Github issues][metabase-issues] to see if it has already been reported. If it has, please let us know you're experiencing the same issue by reacting with a thumbs up emoji or adding a comment to provide additional information. + +If the bug has not yet been reported, go ahead and [open a bug report][metabase-file-bug]. The following information will help us reproduce your issue: + +1. Metabase server logs +2. Javascript console logs +3. Whether it can be reproduced on the sample database +4. Your Metabase version +5. Where Metabase is running (Docker image, Linux/Ubuntu, etc.) +6. Which database you are using +7. What browser version you are using +8. Screenshots (if relevant) + +[metabase-file-bug]: https://github.com/metabase/metabase/issues/new/choose +[metabase-issues]: ./known-issues#how-to-find-a-known-bug diff --git a/_docs/doc-update-detection/troubleshooting-guide/cant-log-in.md b/_docs/doc-update-detection/troubleshooting-guide/cant-log-in.md new file mode 100644 index 000000000..65a7c07ee --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/cant-log-in.md @@ -0,0 +1,48 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'People can''t log in to Metabase' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/cant-log-in.md' +--- + +# People can't log in to Metabase + +## Reset password + +To reset a password for your Metabase instance, see: + +- [Reset a user's password](../people-and-groups/managing#resetting-someones-password). +- [Reset admin password](../people-and-groups/managing#resetting-the-admin-password). + +To reset password for your Metabase Store account, [contact support](/help-premium). + +## No access to Metabase login page + +If you're not a Metabase admin, you'll have to tag them for help here. + +1. Check that you have the correct [site URL](../configuring-metabase/settings) from **Settings** > **Admin settings** > **General**. +2. Check if the [account is deactivated](../people-and-groups/managing#deactivating-an-account). + +## No access to Metabase Cloud account + +The admin password for `store.metabase.com` (where you can find payment and subscription info) is not necessarily the same as the password for your Metabase instance (where you log in to look at data). + +If you've forgotten your Metabase Cloud admin password, you can [contact support](/help-premium) to reset the password. + +## Related topics + +- [Troubleshooting SAML](./saml). +- [Troubleshooting LDAP](./ldap). +- [Resetting someone's password](../people-and-groups/managing#resetting-someones-password). +- [Resetting the admin password](../people-and-groups/managing#resetting-the-admin-password). +- [Deleting an account that's set up incorrectly](../people-and-groups/managing#deleting-an-account). + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). diff --git a/_docs/doc-update-detection/troubleshooting-guide/cant-see-tables.md b/_docs/doc-update-detection/troubleshooting-guide/cant-see-tables.md new file mode 100644 index 000000000..aed124643 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/cant-see-tables.md @@ -0,0 +1,104 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'I can''t see my tables' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/cant-see-tables.md' +--- + +# I can't see my tables + +You've connected Metabase to a database, but: + +- you don't see the tables in the [Table Metadata](../data-modeling/metadata-editing) section of the Admin Panel, +- the tables don't appear in the [Data Browser](/learn/metabase-basics/querying-and-dashboards/data-browser), +- the tables don't show up as possible data sources when you create a query using the Query Builder, or +- you can no longer see tables that you used to be able to see. + +## Check for browser issues + +1. Clear your browser cache. +2. Check if a browser extension or plugin is interfering with Metabase: + - Disable all extensions and plugins, + - Open Metabase in an incognito browser session, or + - Open Metabase in a different browser. + +**Explanation** + +Sometimes your browser will show an old cached list of tables. Browser extensions can also prevent pages from loading correctly. + +## Test the database connection + +1. Go to the Metabase [SQL editor](../questions/native-editor/writing-sql). +2. Test the connection to your database by running: + ```sql + SELECT 1 + ``` + +If you get an error, see [Troubleshooting database connections](./db-connection). + +**Explanation** + +Something may have changed on the database side (if you were previously connected). For example, you may have connected to a test database while doing an evaluation but are now in a production environment. + +## Check table access + +To make sure that your table is actually queryable by Metabase: + +1. Go to the Metabase [SQL editor](../questions/native-editor/writing-sql). +2. Look for your table: + ```sql + SELECT * + FROM your_table + ``` + +If there's a problem with your table name or database permissions, you'll get an error message like: + +- [Table not found](/learn/grow-your-data-skills/learn-sql/debugging-sql/sql-syntax#column-or-table-name-is-not-found-or-not-recognized) +- [Permission denied](./data-permissions#getting-a-permission-denied-error-message) + +For less common errors, try searching or asking the [Metabase community](https://discourse.metabase.com/). + +**Explanation** + +Something might have changed on database side: your table could've been renamed or dropped, or the permissions revoked. + +## Metabase permissions + +If there are only a few people who can't view tables, see [A user group has the wrong access to a table or schema](./data-permissions#a-user-group-has-the-wrong-access-to-a-table-or-schema). + +**Explanation** + +Metabase uses a group-based permission model: people belong to groups, and admins can set permissions to hide tables from groups. + +## Check if the table is hidden + +1. Go to **Admin > Table Metadata** and choose the database where your table is. +2. Check that **Visibility** of your table is not set to **Hidden**. + +**Explanation** + +If an Admin sets the table visibility to **Hidden**, you will be able to use SQL to query the table but will not be able to see it in **Browse** > **Databases** or as a data source in the Query Builder. + +## MongoDB + +MongoDB lets you "successfully connect" to any collection name, even if the collection doesn't exist. If you don't see a MongoDB collection in Metabase, make sure that: + +- you have the correct collection name, and +- the collection is non-empty. + +## Related topics + +- [Table visibility](../data-modeling/metadata-editing#table-visibility). +- [My data sandboxes aren't working](./sandboxing). +- [I can't view or edit a question or dashboard](./cant-view-or-edit). +- [My visualizations are wrong](./visualization). + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). diff --git a/_docs/doc-update-detection/troubleshooting-guide/cant-send-email.md b/_docs/doc-update-detection/troubleshooting-guide/cant-send-email.md new file mode 100644 index 000000000..88ad89556 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/cant-send-email.md @@ -0,0 +1,54 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Metabase isn''t sending email' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/cant-send-email.md' +--- + +# Metabase isn't sending email + +You have told Metabase to send email notifications, but: + +- the notifications aren't arriving. + +Before any other troubleshooting, try sending a test email to isolate the problem. + +## Can you successfully send a test email? + +**Root cause:** The host, port, email address, or password may have been set up incorrectly, or the email server's host and port have been set up incorrectly. + +**Steps to take:** + +1. Navigate to the **Admin Panel** and click **Email** in the left sidebar. +2. Confirm that your host, port, email address, and password are entered correctly. If they are, click **Save changes**. If your changes have successfully saved, you'll see an option to **Send test email**. +3. Click **Send test email**. The test email will go the address associated with your Metabase account. +4. Verify that the email is delivered to your account. +5. If the message is not sent or an error message is displayed in Metabase, try to use the same account credentials in another email program and see if they work. See the logs for more detailed error by navigating to **Troubleshooting** and click **Logs** in the left sidebar. + +## Is the mail server actually sending the message? + +**Root cause:** Some email delivery services have very specific rules regarding valid "from" addresses, or have test modes that restrict delivery. + +**Steps to take:** + +1. Check that your delivery service allows you to send email to the domain you're trying to get email sent to. (Exactly how to do this depends on the delivery service you're connecting to.) +2. Make sure you've whitelisted the "from" address that you're using for Metabase. +3. Check the mail server's logs for any error messages. +4. If you have access to your email delivery service's outbound queue or a dashboard, check that for errors as well. + +## Is the mail being sent but not arriving? + +**Root cause:** The message is being sent correctly, but isn't being received (at least, not where you expect it to be). + +**Steps to take:** + +1. Check whether email sent to other accounts is arriving, e.g., are colleagues receiving their notifications? +2. If so, check your spam folder, any forwarding rules you have set up, etc. +3. Check whether you're using the same email provider as the people who are receiving their messages. If not, the problem might be with deliverability rules---look into signing your emails with [DomainKeys Identified Mail][dkim] (DKIM). + +[bugs]: ./bugs +[dkim]: https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail +[office-365-bug]: https://github.com/metabase/metabase/issues/4272 diff --git a/_docs/doc-update-detection/troubleshooting-guide/cant-view-or-edit.md b/_docs/doc-update-detection/troubleshooting-guide/cant-view-or-edit.md new file mode 100644 index 000000000..c0951c2a9 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/cant-view-or-edit.md @@ -0,0 +1,50 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Can''t view or edit' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/cant-view-or-edit.md' +--- + +# Can't view or edit + +1. Clear your browser cache. +2. Check if a browser extension or plugin is interfering with Metabase: + - Disable all extensions and plugins, + - Open the link in an incognito browser session, or + - Open the link in a different browser. +3. If you aren't the creator of the question, dashboard, or model, check if you have permissions to the collection where the item is saved. +4. Check the [Trash](../exploration-and-organization/delete-and-restore#see-items-in-trash). + +## Can't view cards on a dashboard + +1. Check the collections where each question (or card) on the dashboard is saved. +2. If a saved question is in a collection that you don't have access to, you'll need to ask someone with edit access to the collection to: + - Grant you permission to the collection. + - Or, to move the saved question to a collection that you have permissions to. +3. If the steps above don't solve your problem, ask your Metabase admin if you have [permission to the database that's used by the question](../permissions/data#blocked-view-data-permission). + +**Explanation** + +Moving a dashboard to a different collection doesn't move the dashboard's questions into that collection. + +If the saved questions are stored in a restricted collection (such as someone's personal folder), then other groups won't be able to view those cards. + +Someone with edit permissions (your Metabase admin is probably a safe bet) will need to move those questions into a collection that you have permissions to. + +## Related problems + +- [Error message: your question took too long](./timeout). +- [Error message: permission denied](./data-permissions#getting-a-permission-denied-error-message). +- [I can't view or edit queries from the SQL editor](./data-permissions#a-user-group-cant-access-the-sql-editor). +- [I can't save my question or dashboard](./proxies). +- [I can't see my tables](./cant-see-tables). + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). diff --git a/_docs/doc-update-detection/troubleshooting-guide/create-har-file.md b/_docs/doc-update-detection/troubleshooting-guide/create-har-file.md new file mode 100644 index 000000000..9da7a0659 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/create-har-file.md @@ -0,0 +1,66 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Creating a HAR file for troubleshooting' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/create-har-file.md' +--- + +# Creating a HAR file for troubleshooting + +HAR (short for _HTTP Archive_) files record network requests generated by your browser. HAR files can be helpful when troubleshooting issues with Metabase performance. + +> HAR files can contain sensitive information that you submit during the recording, like passwords and API keys. Before sharing the HAR file with anyone, review the file contents in a text editor. + +To create the HAR file, follow the instructions for your web browser: + +- [Chrome](#create-a-har-file-in-chrome) +- [Edge](#create-a-har-file-in-edge) +- [Firefox](#create-a-har-file-in-firefox) +- [Safari](#create-a-har-file-in-safari) + +## Create a HAR file in Chrome + +1. Open Chrome **Developer tools**. + You can right-click anywhere on the page and select "Inspect". + +2. In Developer tools, switch to the **Network** tab. + The network log recording should start automatically. + +3. With the Network tab open and recording in progress, repeat the steps to reproduce the issue. + +4. Once you're finished reproducing the issue, right-click anywhere in the table of network calls and select **Save all as HAR with content**. + +## Create a HAR file in Edge + +1. Open Edge **Developer tools**. You can right-click anywhere on the page and select "Inspect". + +2. In Developer tools, switch to the **Network** tab (look for the Wi-Fi icon). The network log recording should start automatically. + +3. With the Network tab open and recording in progress, repeat the steps to reproduce the issue. + +4. Once you're finished reproducing the issue, right-click anywhere in the table and select **Save all as HAR with content** + +## Create a HAR file in Firefox + +1. Open Firefox **Developer tools**. You can right-click anywhere on the page and select "Inspect". + +2. In Developer tools, switch to the **Network** tab. + +3. With the Network tab open and recording in progress, repeat the steps to reproduce the issue. + +4. Once you're finished reproducing the issue, right-click anywhere in the table of network calls and select **Save All As HAR**. + +## Create a HAR file in Safari + +1. If you haven't yet, enable the **Develop** menu by going to **Safari > Settings > Advanced**, and select **Show features for web developers**. + +2. Open the Safari developer tools by going to **Develop > Show Web Inspector**. + +3. In Developer tools, switch to the **Network** tab. The network log recording should start automatically. + +4. With the Network tab open and recording in progress, repeat the steps to reproduce the issue. + +5. Once you're finished reproducing the issue, click on **Export** in the top right of the Network tab. diff --git a/_docs/doc-update-detection/troubleshooting-guide/data-permissions.md b/_docs/doc-update-detection/troubleshooting-guide/data-permissions.md new file mode 100644 index 000000000..ff425ad50 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/data-permissions.md @@ -0,0 +1,135 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting data permissions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/data-permissions.md' +--- + +# Troubleshooting data permissions + +If a person has the wrong level of access to the data that's returned by a question or query, you'll need to troubleshoot different levels of [data permissions][data-permissions], starting from the most granular. + +### Row and column permissions + +- [Troubleshooting data sandboxing][troubleshooting-data-sandboxing]. + +### Native query (SQL) permissions + +- [A user group can't access the SQL editor][sql-access]. +- [A user group with SQL permissions isn't being restricted by their data sandbox][sql-sandboxing]. + +### Table or schema permissions + +- [A user group has the wrong access to a table or schema](#a-user-group-has-the-wrong-access-to-a-table-or-schema). +- [A user group can view collections that contain restricted data](#a-user-group-can-view-collections-that-contain-restricted-data). +- [Getting a "permission denied" error message](#getting-a-permission-denied-error-message). +- [Checking someone's access to a table or schema](#checking-someones-access-to-a-table-or-schema). + +## A user group can't access the SQL editor + +1. Ensure scripts are loading by disabling browser extensions and refreshing the browser. +2. Go to **Admin** > **Permissions** and select the relevant group. +3. Find the database that you want to grant SQL access to. +4. From the **View data** dropdown.elect **Can view**. +5. From the **Create queries** dropdown, select **Query builder and native**. +6. [Check if the access problem is fixed](#checking-someones-access-to-a-table-or-schema). + +For more information about the different types of database permissions, check out the [section on data access][data-access] in our permissions documentation. + +## A user group has the wrong access to a table or schema + +1. Go to **Admin** > **People** and check if the person is in [more than one group with conflicting permissions][group-permissions]. +2. If the person is in multiple groups: + - Remove the person from the group with wider permissions, or + - Go to **Admin** > **Permissions** and change the **Data access** permission type. +3. [Check if the access problem is fixed](#checking-someones-access-to-a-table-or-schema). + +**Explanation** + +If a person is a member of multiple [groups][groups], Metabase will grant the _most permissive_ level of access across all the groups in which they're a member. + +For example, if a person is a member of two groups — one which grants [View data] access of "Can view" to a database or table and another that grants "Blocked" access to that database — that person will be able to view the data. + +Remember that everyone is a member of the **All Users** group. We recommend you revoke permissions from the **All Users** group, and create new groups to selectively apply permissions to your data sources. + +## A user group can view collections that contain restricted data + +{% include plans-blockquote.html %} + +1. Go to **Admin** > **Permissions** and select the user group. +2. Select the database or table that you want to restrict. +3. Set **View data** permissions to **Blocked** and click **Save**. +4. [Check if the access problem is fixed](#checking-someones-access-to-a-table-or-schema). + +**Explanation** + +If you've granted a group View data access of "Can view" to a database or table, people can view saved questions and dashboards that draw on that database, as long as those questions and dashboards are stored in a collection that they have access to. + +The [**Blocked** data permission][block-data-permission] is available on [Pro and Enterprise versions of Metabase][pricing]. If you block a group's access to a database, members of that group will not be able to see any data from this database, regardless of their collection permissions. + +## Getting a "permission denied" error message + +If you get an error message that says something like "permission denied to \", you'll need to check if the Metabase application has the correct permissions to query your database. + +1. Go to the SQL editor and run a basic query against the table or schema in question: + ``` + SELECT 1 + FROM ; + ``` +2. Get the credentials that Metabase uses to connect to your database. If you're not sure what those credentials are, ask your database admin. +3. Using a different application (like your CLI or database IDE), connect to your database using the same credentials your Metabase uses to connect to that database, and run the query from step 1. +4. If you cannot access the table or schema in both step 1 and 3, ask your database admin to: + - [Grant database privileges](../databases/users-roles-privileges) to the role that Metabase is using to connect, or + - Provide a set of database credentials with the correct permissions. +5. [Check if the access problem is fixed](#checking-someones-access-to-a-table-or-schema). + +**Explanation** + +Your database has its own set of permissions that are configured for each person (or application) that logs in. + +Database permissions apply at the level of your database connection, _before_ your data and collection permissions are applied in Metabase. + +This means that settings configured on the database side can prevent Metabase from connecting to certain schemas or tables, regardless of what you've set up on the Metabase side. + +## Checking someone's access to a table or schema + +1. Open an incognito browser window. +2. Log in to Metabase as the person in question. +3. Run a question, dashboard, or native query to confirm that the person can see the data they're supposed to. + +## Do you have a different problem? + +- [I can't view or edit my question or dashboard][view-edit]. +- [I can't save my question or dashboard][proxies]. +- [I can't see my tables][cant-see-tables]. + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community][discourse]. +- Search for [known bugs or limitations][known-issues]. + +[admin-permissions]: ../permissions/introduction +[block-data-permission]: ../permissions/data#blocked-view-data-permission +[cant-see-tables]: ./cant-see-tables +[collection-permissions]: ../permissions/collections +[data-access]: ../permissions/data#data-permission-types +[data-permissions]: ../permissions/data +[discourse]: https://discourse.metabase.com/ +[groups]: ../people-and-groups/managing#groups +[group-permissions]: ../permissions/introduction#key-points-regarding-permissions +[known-issues]: ./known-issues +[learn-permissions]: /learn/metabase-basics/administration/permissions +[native-query-editing]: ../permissions/data#query-builder-and-native-create-queries-permission +[pricing]: /pricing +[proxies]: ./proxies +[sql-access]: ./data-permissions#a-user-group-cant-access-the-sql-editor +[sql-sandboxing]: ./sandboxing#is-the-question-written-in-sql +[troubleshooting-data-sandboxing]: ./sandboxing +[troubleshooting-permissions]: ./permissions +[unrestricted]: ../permissions/data#can-view-data-permission +[view-edit]: ./cant-view-or-edit diff --git a/_docs/doc-update-detection/troubleshooting-guide/db-connection.md b/_docs/doc-update-detection/troubleshooting-guide/db-connection.md new file mode 100644 index 000000000..40da9957b --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/db-connection.md @@ -0,0 +1,129 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting database connections' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/db-connection.md' +redirect_from: + - /docs/doc-update-detection/troubleshooting-guide/datawarehouse +--- + +# Troubleshooting database connections + +If you can't connect to your database, you'll need to figure out if the problem is happening with Metabase or your database server. + +If your database connection is successful, but the tables aren't showing up in the [Data Browser](/learn/metabase-basics/querying-and-dashboards/data-browser), go to [Troubleshooting missing tables](./cant-see-tables). + +## Troubleshooting connections to Metabase + +1. Go to **Admin** > **Databases** and select your database to confirm that your connection hasn’t been changed or deleted. + + - If Metabase hasn't started syncing with your database, click **Sync database schema**. + + - If Metabase is taking a long time to sync, go to [Troubleshooting syncs and scans](./sync-fingerprint-scan). + +2. Go to **Admin** > **Troubleshooting** > **Logs** to check if Metabase failed to sync [due to an error](#common-database-connection-errors). + + - If the logs feel overwhelming, check out [How to read the server logs](./server-logs). + +If you don't have access to the Metabase Admin panel, you'll need to ask the person who set up your Metabase. + +## Troubleshooting connections to the database server + +1. [Check that the data warehouse server is running](#checking-the-server-status). + +2. Check if you can connect to the data warehouse from another client using the machine that you’re running Metabase on. + + - If you can access the server from a bastion host or another machine, [check if your Metabase's IP address has access to your database server](#checking-your-server-access). + + - If you're running Metabase Cloud, check that you've [whitelisted our IP addresses](/cloud/docs/ip-addresses-to-whitelist). + +3. Make sure that Metabase is using a role with the necessary privileges to connect to your data warehouse. See [Granting database privileges](../databases/users-roles-privileges). + +The steps above will help you detect whether the problem is occurring outside of Metabase. To _fix_ problems with your database server, you'll need to refer to the docs for your database or cloud service. Remember to [test your database connection](#testing-the-connection-status) after you make changes. + +If you don't have access to the data warehouse server, you’ll need to ask the person who manages your database or data warehouse. + +## Troubleshooting BigQuery and Google Drive connections + +See [Troubleshooting BigQuery and Google Drive connections](./bigquery-drive) + +## Common database connection errors + +### Your question took too long + +If you see this error message in the Metabase interface, go to [Troubleshooting timeouts](./timeout). + +### Connections cannot be acquired from the underlying database + +If you see this error messages in the [logs](./server-logs) (**Admin** > **Troubleshooting** > **Logs**): + +1. Go to **Admin** > **Databases** and select your database. +2. Go to **Advanced options** > **Additional JDBC connection string options** and add `trustServerCertificate=true`. +3. Click **Save**. + +The version of Metabase you're using to connect to your data warehouse must support your database's version. For example, Metabase versions older than 46 lack support for Microsoft SQL Server 2022. + +## Testing a database connection + +As you work through the troubleshooting steps in this guide, you can check if each component is working as expected: + +- [Server status](#checking-the-server-status) +- [Server access](#checking-your-server-access) +- [Connection status](#testing-the-connection-status) + +### Checking the server status + +If you’re using a hosted database service, go to the console and verify its status. + +If you have direct access to a command-line interface, log in and make sure that your database is running and accepting queries. + +### Checking your server access + +To verify that your Metabase's IP address can access the database server: + +1. Use the [netcat](https://en.wikipedia.org/wiki/Netcat) command `nc` (or your operating system’s equivalent) to check if you can connect to the host on a given port. Note that different databases use different ports by default. + +2. If you're running Metabase Cloud, check that you've [whitelisted our IP addresses](/cloud/docs/ip-addresses-to-whitelist). + +3. Check that your database credentials are correct. + +#### Example commands + +To verify the port used in a default PostgreSQL configuration (which listens on port 5432): + +``` +nc -v your-db-host 5432 +``` + +To verify your credentials for a PostgreSQL database (you'll see an error if the database name or the user/password are incorrect): + +``` +psql -h HOSTNAME -p PORT -d DATABASENAME -U DATABASEUSER +``` + +### Testing the connection status + +1. Go to the Metabase [SQL editor](../questions/native-editor/writing-sql). +2. Test the connection to your database by running: + ```sql + SELECT 1 + ``` + +## Related problems + +- [My connection or query is timing out](./timeout). +- [My database is slow](./db-performance). + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community][discourse]. +- Search for [known bugs or limitations][known-issues]. +- Hire a [Metabase Expert](/partners/){:target="\_blank"}. + +[discourse]: https://discourse.metabase.com/ +[known-issues]: ./known-issues diff --git a/_docs/doc-update-detection/troubleshooting-guide/db-performance.md b/_docs/doc-update-detection/troubleshooting-guide/db-performance.md new file mode 100644 index 000000000..b9fd0a2b0 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/db-performance.md @@ -0,0 +1,89 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting database performance' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/db-performance.md' +--- + +# Troubleshooting database performance + +This guide deals with databases or data warehouses that are [connected to Metabase](../databases/connecting) as data sources. + +To fix problems with your Metabase [application database](../installation-and-operation/configuring-application-database), check out these troubleshooting guides: + +- [Running Metabase](./running). +- [Running Metabase on Docker](./docker). +- [Using or migrating from an H2 application database](./loading-from-h2). + +## Identifying bottlenecks + +1. Optional: use Metabase's [Usage analytics](../usage-and-performance-tools/usage-analytics) to look at your Metabase usage stats.\* +2. Go to your database's server logs and check whether: + - Your tables are growing in size, + - More people are using Metabase to access your database, + - People are accessing your database more often, or + - A script or application (other than Metabase) is accessing the database frequently. +3. If specific tables are being queried a lot, try [Optimizing your table schemas](/learn/metabase-basics/administration/administration-and-operation/making-dashboards-faster#organize-data-to-anticipate-common-questions). +4. Run a question from Metabase, then [run the same query](../questions/query-builder/editor#viewing-the-native-query-that-powers-your-question) directly against your database. + - If the queries take about the same time, your data or usage might be outgrowing your database. You can give your database more resources, or consider [upgrading your hardware](/learn/grow-your-data-skills/data-landscape/which-data-warehouse). + - If the query in Metabase takes longer than a direct query against your database, you might need to adjust the deployment of your Metabase app. Check out some options in [Metabase at scale](/learn/metabase-basics/administration/administration-and-operation/metabase-at-scale). +5. If a script or third-party application is hitting your database with a lot of queries at a time: + - Stop your script or application, and [clear any queued queries](#clearing-queued-queries). + - Recommended: add a timeout to your script, schedule the script or application to run during off-hours, or replicate your database (and point your tools there instead). + +\* Available on Pro and Enterprise plans. + +## Resetting a database connection + +1. Go to **Settings** > **Admin settings** > **Databases** > your database. +2. Click **Save changes** (without making changes) to reset Metabase's connections to your database. +3. Alternatively: kill the connection(s) directly from your database. + +**Explanation** + +"Turn it off, and on again" by disconnecting and reconnecting your database---an easy sanity check that can save you a lot of time. + +In general, Metabase will try to close hanging connections to your database after 10 minutes, and then again after 20 minutes. But if your database doesn't respond, you may need to close the connection to Metabase from the database side. + +## Clearing queued queries + +1. Stop the process (e.g., a script, or a dashboard with [too many cards](./my-dashboard-is-slow#dashboard-has-over-10-cards) that's launching a lot of queries at once. +2. Go to your database server and stop all queries (from Metabase) that are in progress. +3. Optional: Increase the [number of connections to your database](../configuring-metabase/environment-variables#mb_jdbc_data_warehouse_max_connection_pool_size). + +**Explanation** + +If someone or something creates 100 queries at the same time, this stampede of queries will take up all of the available connections between Metabase and your database, preventing any new queries from running. If other people continue running questions and dashboards while the first 100 queries are still in progress, the queue will grow at a faster rate than your database can keep up with. + +## Managing resource-intensive queries + +1. [Reschedule or disable Metabase syncs and scans](../databases/sync-scan). + +**Explanation** + +By default, Metabase makes regular sync and scan queries against your database to keep your tables up to date, get fresh values for filter dropdowns, and make helpful suggestions. If you've got a very large database, you can choose to trigger these queries manually instead of on a schedule. + +## Questions that use number, date, or timestamp columns + +1. Update your database schema so that the columns are typed correctly. +2. [Sync the updated columns](../databases/sync-scan#manually-syncing-tables-and-columns) to bring the changes into Metabase. + +**Explanation** + +If a question uses data stored as the wrong [data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview) in your database (most common with number, date, or timestamp values stored as strings), Metabase will generate a query that asks your database to convert the values on the fly. Typing your columns correctly at the schema level will help your database avoid that extra step to return results faster in Metabase. + +## Related problems + +- [My connection or query is timing out](./timeout). +- [I can't connect to a database](./db-connection). +- [My dashboard is slow or failing to load](./my-dashboard-is-slow). + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). diff --git a/_docs/doc-update-detection/troubleshooting-guide/diagnostic-info.md b/_docs/doc-update-detection/troubleshooting-guide/diagnostic-info.md new file mode 100644 index 000000000..45a72071b --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/diagnostic-info.md @@ -0,0 +1,41 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Diagnostic information for troubleshooting' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/diagnostic-info.md' +--- + +# Diagnostic information for troubleshooting + +To download diagnostic information, hit `Cmd + F1` on Macs, `Ctrl + F1` on PCs. Hit Cmd/Ctrl + K to bring up the command palette, search for "Diagnostic", and select "Open diagnostic error modal" + +Select the info you want to include in the diagnostic JSON file. Options include: + +- Item definition (like information about a dashboard) +- Browser error messages +- All server error messages +- All server logs +- Server logs from the current user only +- Metabase instance version information + +What data Metabase captures depends on the page you're on when you request diagnostic information. + +> Review the downloaded file before sharing it, as the diagnostic info may contain sensitive data. + +## Metabase server and console logs + +Metabase will log errors, both on the server and in the browser console, depending on where the error occurs, which can help you track down an issue. Administrators will have access to the server logs, and everyone with a browser can open the developer tools to see the console logs. + +**Accessing the Metabase server logs**: You can look for the logs that Metabase leaves on the server's file system (or wherever else you collect logs). If you're logged into Metabase with an Admin account, you can also access the logs by going to the top right of the screen and clicking on the **gear** icon > **Admin settings** > **Troubleshooting** > **Logs**. Check out [How to read the server logs](./server-logs) + +**Checking for Javascript console errors:** Metabase will send debugging information and errors to your browser's developer console. To open the developer console, follow the instructions for your web browser: + +- [Chrome](https://developers.google.com/web/tools/chrome-devtools/open#console) +- [Edge](https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium) +- [Firefox](https://firefox-source-docs.mozilla.org/devtools-user/) +- [Safari](https://support.apple.com/guide/safari-developer/develop-menu-dev39df999c1/mac) + +**Creating a HAR file**: HAR files record network requests generated by your browser. HAR files can be helpful when troubleshooting issues with Metabase performance. Check out [Creating HAR files for troubleshooting](./create-har-file). diff --git a/_docs/doc-update-detection/troubleshooting-guide/docker.md b/_docs/doc-update-detection/troubleshooting-guide/docker.md new file mode 100644 index 000000000..05e6eb144 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/docker.md @@ -0,0 +1,162 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting Metabase on Docker' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/docker.md' +--- + +# Troubleshooting Metabase on Docker + +Docker simplifies many aspects of running Metabase, but there are some pitfalls to keep in mind. If you have trouble with Metabase under Docker, try going through the troubleshooting process below, then look below for details about the specific issue you've found. + +1. Is the container running? +2. Is the server running inside the container? +3. Is Metabase using the correct application database? +4. Can you connect to the Docker host on the Metabase port? +5. Can you connect to the container from the Docker host? +6. Can you connect to the server from within the container? + +You may find these commands useful along the way. To get to the shell in the Metabase container: + +``` +docker exec -ti CONTAINER_NAME bash +``` + +And to get the logs for the Metabase container: + +``` +docker logs -f CONTAINER_NAME +``` + +## Metabase container exits without starting the server + +**How to detect this:** Run `docker ps` to see if the Metabase container is currently running. If it is, move on to the next step. + +If `docker ps` does not show the running container, then list the stopped containers by running: + +``` +docker ps -a | grep metabase/metabase +``` + +Look for the container that exited most recently and make a note of the container ID. Look at that container's logs with: + +``` +Docker logs CONTAINER_ID +``` + +## Metabase container is running but the server is not + +**How to detect this:** Run `docker ps` to make sure the container is running. The server should be logging to the Docker container logs. Check this by running: + +``` +docker logs CONTAINER_NAME +``` + +You should see a line like this at the beginning: + +``` +05-10 18:11:32 INFO metabase.util :: Loading Metabase... +``` + +Further down, you should eventually see a line like: + +``` +05-10 18:12:30 INFO metabase.core :: Metabase Initialization COMPLETE +``` + +If you see the lines below: + +``` +05-15 19:07:11 INFO metabase.core :: Metabase Shutting Down ... +05-15 19:07:11 INFO metabase.core :: Metabase Shutdown COMPLETE +``` + +then Metabase has shut itself down. + +**How to fix this:** Check the Docker container logs for errors about connecting to the application database. Watch the logs to see if Metabase is still being started; the command: + +``` +Docker logs -f CONTAINER_ID +``` + +will let you see the logs as they are printed. + +If the container is being terminated before it finished starting, the problem could be a health check timeout in the orchestration service used to start the container, such as Docker Cloud. + +If the container is _not_ being terminated from the outside, but is failing to start anyway, this problem is probably not specific to Docker. If you're using a Metabase-supplied image, please [open a GitHub issue](https://github.com/metabase/metabase/issues/new/choose). + +## Not connecting to a remote application database + +**How to detect this:** If this is a new Metabase instance, then the database you specified via the environment variables will be empty. If this is an existing Metabase instance with incorrect environment parameters, the server will create a new H2 embedded database to use for application data and you’ll see lines similar to these in the log: + +``` +05-10 18:11:40 INFO metabase.core :: Setting up and migrating Metabase DB. Please sit tight, this may take a minute... +05-10 18:11:40 INFO metabase.db :: Verifying h2 Database Connection ... + +05-10 18:11:40 INFO metabase.db :: Verify Database Connection ... ✅ +``` + +**How to fix this:** Check that you are passing environments to Docker correctly. You can list the environment variables for a container with this command: + +``` +docker inspect some-postgres -f '{% raw %}{{ .Config.Env }}{% endraw %}' +``` + +## The Metabase server isn't able to connect to a MySQL or PostgreSQL database + +**How to detect this:** The logs for the Docker container return an error message after the "Verifying Database Connection" line. + +**How to fix this:** Try to connect using the `mysql` or `psql` command with the connection string parameters you are passing in [via the environment variables][configuring-application-database]. If you can't connect to the database, the problem is due to either the credentials or connectivity. To verify that the credentials are correct, log in with those credentials from another machine and then try to make the same connection from the host running the Docker container. + +One easy way to run this is to use Docker to start a container that has the appropriate client for your database. For Postgres this would look like: + +``` +docker run --name postgres-client --rm -ti --entrypoint /bin/bash postgres +``` + +From within that container, try connecting to the database host using the client command in the container such as `psql`. If you are able to connect from another container on the same host, then try making that connection from within the Metabase Docker container itself: + +``` +docker exec -ti container-name bash +``` + +You can also try to connect to the database host using the `nc` command and check if the connection can be opened: + +``` +nc -v your-db-host 5432 +``` + +These steps will help you determine whether this the problem is with the network or with authentication. + +## The Metabase application database is not being persisted + +**How to detect this:** This is occurring if you are getting the Setup screen every time you start the application. The most common cause is not giving the Docker container a persistent filesystem mount to put the application database in. + +**How to fix this:** Make sure you are giving the container a [persistent volume][persistent-volume]. + +## The internal port isn't being remapped correctly + +**How to detect this:** Run `docker ps` and look at the port mapping, then run `curl http://localhost:port-number-here/api/health`. This should return a JSON response that looks like: + +``` +{"status":"ok"} +``` + +**How to fix this:** Make sure to include `-p 3000:3000` or similar port remapping in the `docker run` command you use to start the Metabase container image. + +## Metabase can't write or read to/from a file or directory + +**How to detect this:** A message in the logs will clearly indicate an IOError or "Permission denied" from Java, or errors from SQLite containing `org.sqlite.core.NativeDB._open_utf8`. + +**How to fix this:** Ensure that the user who is running Metabase has permission to read and write to the file or directory: + +- If you are running Metabase as a JAR file in your local machine or server, check the user who is running the Java process. +- If you're running Metabase from the Docker container, make sure you're using the `/metabase.db` directory. + +If you're running Metabase from the JAR in any Unix-like operating system, you can see which user is running Metabase by opening a terminal and typing `ps -uA | grep metabase`. + +[configuring-application-database]: ../installation-and-operation/configuring-application-database +[persistent-volume]: ../installation-and-operation/running-metabase-on-docker#mounting-a-mapped-file-storage-volume diff --git a/_docs/doc-update-detection/troubleshooting-guide/error-message.md b/_docs/doc-update-detection/troubleshooting-guide/error-message.md new file mode 100644 index 000000000..2272a0ce2 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/error-message.md @@ -0,0 +1,37 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting error messages' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/error-message.md' +--- + +# Troubleshooting error messages + +An error message can help you find the right troubleshooting guide. The exact wording depends on your database and Metabase version, so try to look for the closest match. + +## SQL editor + +See if your error details contain any of: + +- [Table or column "not found" or "not recognized"](/learn/grow-your-data-skills/learn-sql/debugging-sql/sql-syntax#column-or-table-name-is-not-found-or-not-recognized). +- [Function does not exist](/learn/grow-your-data-skills/learn-sql/debugging-sql/sql-syntax#sql-function-does-not-exist). +- [Permission denied](./data-permissions#getting-a-permission-denied-error-message). + +For example, this SQL error tells you that the function `DATEFROMPARTS` does not work on a BigQuery database: + +![Sample SQL error message](./images/sample-error-sql.png) + +## Questions and dashboards + +- [Your question took too long](./timeout). +- [Still waiting...](./my-dashboard-is-slow). + +## Are you still stuck? + +If you can't find your error on this page: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). diff --git a/_docs/doc-update-detection/troubleshooting-guide/filters.md b/_docs/doc-update-detection/troubleshooting-guide/filters.md new file mode 100644 index 000000000..982d48076 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/filters.md @@ -0,0 +1,117 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting filters' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/filters.md' +--- + +# Troubleshooting filters + +It's always a good idea to start with a quick sanity check: + +1. Clear your browser cache. +2. Refresh the page. +3. Open your question or dashboard in an incognito window. + +## Dashboard filters + +If a dashboard filter is giving you no results or the wrong results: + +1. Click the **pencil** icon to go into edit mode. +2. Click the **gear** icon beside your filter widget. +3. Make sure you've selected a column for your filter under **Column to filter on**. +4. If you can't find the right **Column to filter on**, or you're getting "No Results" when you apply the filter: + - Exit edit mode and click on a dashboard card to go to the _original question_. + - Follow the troubleshooting steps under [Question filters](#question-filters). + +## Question filters + +If a question filter is giving you no results or the wrong results: + +1. Make sure the question includes the column you want to filter on. +2. Check that the column actually contains the value(s) you're filtering on. You can do this by: + - sorting number or date columns, + - creating a "contains" filter for string columns, or + - asking your database admin. +3. Ask your Metabase admin to help you check if: + - Metabase is [up to date](../databases/sync-scan) with your database, + - the column is [visible](../data-modeling/metadata-editing#column-visibility) in Metabase, + - you have the correct [data permissions](../permissions/data) to access the column. + +### Special cases + +If you're having trouble filtering on a: + +- [Custom column](../questions/query-builder/editor#custom-columns): check if the custom expression is working as expected. For example, your custom expression might be returning blank values when you expect numbers. +- [SQL field filter](../questions/native-editor/sql-parameters#the-field-filter-variable-type): make sure you're using the correct [field filter syntax](../questions/native-editor/sql-parameters#field-filter-syntax), then see [Troubleshooting SQL variables](./sql#sql-variables-and-field-filters). + +**Explanation** + +When we first set up a filter, we need to link the filter to a column. If we make the wrong assumptions about a column's values or data type, the filter won't work at all. If a column changes on the database side, the filter might suddenly stop working. + +For example, let's say we want to create a filter named "Select Product ID" linked to a column named **Product ID**. The filter won't work if any of these things happen: + +- Our question doesn't include the **Product ID** column. +- We type the number 4 into the "Select Product ID" filter, when the **Product ID** column only contains the values 1, 2, and 3. +- **Product ID** is renamed to something else in the database or Table Metadata page. +- **Product ID** is deleted from the database, or hidden in the Table Metadata page. +- **Product ID** is a custom column that's not working as expected. +- We don't have data permissions to access the **Product ID** column. +- We made "Select Product ID" a numerical filter, but **Product ID** is a string column (see the section below). + +## Time, ID, and number filters + +To debug dashboard and question filters that involve timestamps, UUIDs, or numeric data: + +1. Find the [data type](/learn/grow-your-data-skills/data-fundamentals/data-types-overview) of the column that you want to filter on. You can find this info from: + - the [Data reference](../exploration-and-organization/data-model-reference), + - the [Table Metadata page](../data-modeling/metadata-editing) (admins only), or + - directly from the database. +2. Cast the column to a data type that matches the desired [filter type](../questions/query-builder/filters#filter-types). You can: + - [cast strings or numbers to dates](../data-modeling/metadata-editing#casting-to-a-specific-data-type) from the Table Metadata page, or + - change the data type of the column in your database, and [re-sync](../databases/sync-scan#manually-syncing-tables-and-columns) the database schema. + +If you're not a Metabase admin, you might have to ask your admin to help you with some of these steps. + +**Explanation** + +Metabase needs to know the data type of a column in order to present you with a curated selection of filter types. Sometimes these columns are mistyped---if a column stores your numbers as strings, Metabase will only show you text or category filters (with options like "is", "is not") instead of number filters (with options like "greater than", "less than"). + +Timestamps, in particular, are the root of all evil, so please be patient with your Metabase admin (or yourself!) when trying to get the data type right. + +## Field filters in BigQuery and Oracle + +If you are getting an error when using field filters with BigQuery or Oracle, make sure you use the correct syntax for the `FROM` clause. See [Field filters in BigQuery and Oracle](../questions/native-editor/sql-parameters#field-filters-in-bigquery-and-oracle). + +## Missing or incorrect filter values + +If your filter dropdown menu displays the wrong values for a column: + +1. Go to **Admin settings** > **Table Metadata**. +2. Find your database, table, and column. +3. Click the **gear** icon at the right of a column's settings box. +4. Scroll to **Cached field values**. +5. Optional: click **Discard cached field values**. +6. Click **Re-scan this field**. + +**Explanation** + +Metabase [scans](../databases/sync-scan#how-database-scans-work) get the values for your filter dropdown menus by querying and caching the first 1,000 distinct records from a table. You might see outdated filter values if your tables are getting updated more frequently compared to your [scan schedule](../databases/sync-scan#scanning-for-filter-values). + +## Related topics + +- [Troubleshooting linked filters](./linked-filters) +- [Troubleshooting SQL variables and field filters](./sql#sql-variables-and-field-filters) +- [Troubleshooting dates and times](./timezones) +- [Creating dropdown filters](../data-modeling/metadata-editing#changing-a-search-box-filter-to-a-dropdown-filter) +- [Creating SQL filters](../questions/native-editor/sql-parameters) + +## Are you still stuck? + +If you can't solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). diff --git a/_docs/doc-update-detection/troubleshooting-guide/images/sample-error-sql.png b/_docs/doc-update-detection/troubleshooting-guide/images/sample-error-sql.png new file mode 100644 index 000000000..b53abf95d Binary files /dev/null and b/_docs/doc-update-detection/troubleshooting-guide/images/sample-error-sql.png differ diff --git a/_docs/doc-update-detection/troubleshooting-guide/index.md b/_docs/doc-update-detection/troubleshooting-guide/index.md new file mode 100644 index 000000000..1c51c5fc4 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/index.md @@ -0,0 +1,120 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: 'Troubleshooting Guide' +title: 'Troubleshooting guides' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/index.md' +--- + +# Troubleshooting guides + +Problems, their causes, how to detect them, and how to fix them. + +## Getting diagnostic info + +- [Download diagnostic info](./diagnostic-info) +- [Create a HAR file](./create-har-file) + +## Installation + +- [Running the Metabase JAR][running]. +- [Running Metabase on Docker][docker]. +- [Using or migrating from an H2 application database][appdb]. + +## Authentication + +- [People can't log in to Metabase][login]. +- [LDAP][ldap]. +- [SAML][saml]. + +## Permissions + +- [My permissions aren't working][permissions]. +- [My data sandboxes aren't working][sandbox]. + +## Databases + +- [I can't connect to a database][db-connection]. +- [I can't see my tables][cant-see-tables]. +- [The data in Metabase doesn't match my database][sync-fingerprint-scan]. +- [My database is slow][db-performance]. +- [My connection or query is timing out][timeout]. + +## Questions and dashboards + +- [I can't save my question or dashboard][proxies]. +- [I can't view or edit my question or dashboard][view-edit]. +- [My visualizations are wrong][visualization]. +- [My dashboard is slow or failing to load][slow-dashboard]. +- [My SQL question doesn't work][sql]. +- [The dates and times in my questions and charts are wrong][incorrect-times]. +- [My filters don't work][filters]. +- [My linked filters don't work][linked-filters]. + +## Models + +- [My model doesn't work][models]. + +## Email and alerts + +- [Metabase isn't sending email][not-sending-email]. + +## Error messages + +- [I'm getting an error message][error-message]. + +## Think you found a bug? + +- [How to find known bugs or limitations][known-issues]. +- [Filing a bug report][bugs]. + +## Feature requests + +See [Requesting new features][feature-request]. + +## Metabase tutorials + +For tutorials that walk you through how to use Metabase features, check out [Learn Metabase][learn]. + +## Metabase forum + +To see if someone else has run into a similar issue, check out [our forum on Discourse][forum]. + +## Upgrading Metabase + +Metabase adds new features and squashes bugs with each release. [Upgrading to the latest and greatest][upgrade] may resolve your issue. If you're using [Metabase Cloud][cloud], we'll handle the upgrades for you. To see what's new, check out the [release notes][releases]. + +[appdb]: ./loading-from-h2 +[bugs]: ./bugs +[cant-see-tables]: ./cant-see-tables +[cloud]: /cloud/ +[db-connection]: ./db-connection +[db-performance]: ./db-performance +[docker]: ./docker +[error-message]: error-message +[feature-request]: requesting-new-features +[filters]: ./filters +[forum]: https://discourse.metabase.com/ +[incorrect-times]: ./timezones +[known-issues]: ./known-issues +[ldap]: ./ldap +[learn]: /learn +[linked-filters]: ./linked-filters +[login]: ./cant-log-in +[models]: ./models +[not-sending-email]: ./cant-send-email +[permissions]: ./permissions +[proxies]: ./proxies +[releases]: https://github.com/metabase/metabase/releases +[running]: ./running +[saml]: ./saml +[sandbox]: ./sandboxing +[slow-dashboard]: ./my-dashboard-is-slow +[sql]: ./sql +[sync-fingerprint-scan]: ./sync-fingerprint-scan +[timeout]: ./timeout +[upgrade]: ../installation-and-operation/upgrading-metabase +[view-edit]: ./cant-view-or-edit +[visualization]: ./visualization diff --git a/_docs/doc-update-detection/troubleshooting-guide/known-issues.md b/_docs/doc-update-detection/troubleshooting-guide/known-issues.md new file mode 100644 index 000000000..bb49b6a62 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/known-issues.md @@ -0,0 +1,51 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'How to find a known bug or limitation' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/known-issues.md' +--- + +# How to find a known bug or limitation + +If you can't find or solve your problem using the [troubleshooting guides](./index), you may be running into an issue that we're still working on. + +## How to find a known bug + +If your work in Metabase is crashing, missing, or not being saved, you might have found a bug. + +1. Go to the [Metabase Github issues page](https://github.com/metabase/metabase/issues). + +2. Click on the **Label** dropdown and select `Type: Bug`. + + > If you're encountering problems after your Metabase version was recently upgraded, you can add the label `.Regression`. + +3. Choose least one value in the **Label** dropdown that matches the feature you're having trouble with. + + > Add additional keywords to the search bar above the list of results. Hit Enter/Return to run the search. + + > Click **Sort** and select the thumbs up emoji (👍) to view the most commonly encountered bugs. + +4. If you find an existing bug that matches your problem, add a thumbs up emoji to help the team prioritize it. + +5. If you can't find your problem, and you're sure that it's not a [product limitation](#how-to-find-a-known-product-limitation), you can [create a new bug report](./bugs). + +## How to find a known product limitation + +If the functionality you're looking for simply doesn't exist (i.e., it hasn't suddenly gone missing), you might be running into a product limitation. + +1. Go to the [Metabase Github issues page](https://github.com/metabase/metabase/issues). + +2. Click on the **Label** dropdown and select `Type: New Feature`. + +3. Choose at least one value in the **Label** dropdown that matches the feature you're looking for. + + > Add additional keywords to the search bar above the list of results. Hit Enter/Return to run the search. + + > Click **Sort** and select the thumbs up emoji (👍) to view the most highly requested features. + +4. If you find a feature request that matches what you want to do, add a thumbs up emoji to help the team prioritize it. + +5. If a feature request doesn't exist, and your issue isn't [caused by a known bug](#how-to-find-a-known-bug), you can [submit a new feature request](./requesting-new-features). diff --git a/_docs/doc-update-detection/troubleshooting-guide/ldap.md b/_docs/doc-update-detection/troubleshooting-guide/ldap.md new file mode 100644 index 000000000..31473b143 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/ldap.md @@ -0,0 +1,91 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting LDAP' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/ldap.md' +--- + +# Troubleshooting LDAP + +Metabase can use LDAP for authentication. [This article](../people-and-groups/ldap) explains how to set it up, and the guide below will help you troubleshoot if anything goes wrong. If your problem isn't specific to LDAP, go to [our troubleshooting guide for logging in](./cant-log-in). + +## LDAP sample configuration + +You can test Metabase with LDAP by using this `docker-compose` definition: + +```yml +version: "3.7" +services: + metabase-ldap: + image: metabase/metabase:latest + container_name: metabase-ldap + hostname: metabase-ldap + volumes: + - /dev/urandom:/dev/random:ro + ports: + - 3000:3000 + networks: + - metanet1 + environment: + - "MB_LDAP_BIND_DN=cn=admin,dc=example,dc=org" + - "MB_LDAP_ENABLED=true" + - "MB_LDAP_GROUP_BASE=cn=readers" + - "MB_LDAP_HOST=openldap" + - "MB_LDAP_PASSWORD=adminpassword" + - "MB_LDAP_PORT=1389" + - "MB_LDAP_USER_BASE=ou=users,dc=example,dc=org" + - "MB_LDAP_ATTRIBUTE_EMAIL=uid" + # We are using the same field for email and first name, just for this example to work without modifications to the LDAP objects + - "MB_LDAP_ATTRIBUTE_FIRSTNAME=uid" + - "MB_LDAP_ATTRIBUTE_LASTNAME=sn" + openldap: + image: bitnami/openldap:2.4.57 + hostname: openldap + container_name: openldap + ports: + - 1389:1389 + environment: + - LDAP_ADMIN_USERNAME=admin + - LDAP_ADMIN_PASSWORD=adminpassword + - LDAP_USERS=user01@metabase.com,user02@metabase.com + - LDAP_PASSWORDS=password1!,password2! + - LDAP_PORT_NUMBER=1389 + - LDAP_ROOT=dc=example,dc=org + - LDAP_USER_DC=users + - LDAP_GROUP=readers + networks: + - metanet1 +networks: + metanet1: + driver: bridge +``` + +If you don't pass environment variables to Metabase and you want to configure the environment manually, you can go to the Admin Panel, selectin "Settings", select "Authentication", and then select "LDAP Configuration" and enter the following values: + +- `USERNAME OR DN`: `cn=admin,dc=example,dc=org` +- `PASSWORD`: `adminpassword` +- `USER SEARCH BASE`: `ou=users,dc=example,dc=org` +- `USER FILTER`: `(&(objectClass=inetOrgPerson)(|(uid={login})))` +- `GROUP SEARCH BASE`: `cn=readers` + +For the `USER FILTER`, you can leave the default value, which will look for the user ID in both the `uid` or `email` field. + +## Related software for troubleshooting + +If you run into an issue, check that you can login to your LDAP directory and issue queries using software like [Apache Directory Studio][apache-directory-studio]. It will let you see the whole LDAP tree and view the logs of your LDAP application to see queries run. + +

Current limitations

+ +- When using Metabase Enterprise with a MySQL database and LDAP enabled, make sure that you disable synchronization of binary fields from your LDAP directory by using the `MB_LDAP_SYNC_USER_ATTRIBUTES_BLACKLIST` environment variable. If you do not, you may hit the 60K field size limitation of the text field in MySQL, which will prevent you from creating users or those users from logging in. + +[apache-directory-studio]: https://directory.apache.org/studio/ + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). diff --git a/_docs/doc-update-detection/troubleshooting-guide/linked-filters.md b/_docs/doc-update-detection/troubleshooting-guide/linked-filters.md new file mode 100644 index 000000000..14bb8355d --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/linked-filters.md @@ -0,0 +1,80 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'My linked filters don''t work' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/linked-filters.md' +--- + +# My linked filters don't work + +You have created a [linked filter][linked-filter-gloss] so that (for example) if a dashboard contains both a "State" and a "City" filter, the "City" filter only shows cities in the state selected by the "State" filter. However: + +- your cards are showing "No result" when you apply the linked filter, +- your linked filter seems to have no effect, or +- your linked filter widget does not display a dropdown of filtered values. + +If you are having problems with a regular [filter widget][filter-widget-gloss], please see [this guide](./filters). In order to fix problems with linked filters, you need a clear understanding of how they work: + +## Does a connected dashboard card use a SQL variable? + +**Root cause**: Native/SQL questions must have a [field filter](../questions/native-editor/sql-parameters#the-field-filter-variable-type) variable in order to be linked. Regular SQL variables won't work. + +**Steps to take**: + +1. Update the card's query to change the regular variable to a [field filter](../questions/native-editor/sql-parameters#the-field-filter-variable-type) variable. + +See [Limitations of linking filters](../dashboards/linked-filters#limitations-of-linked-filters). + +## Do you understand the directionality of linked filters? + +**Root cause:** Linked filters are one of the more complex features of Metabase, and many problems stems from misunderstanding their operation. + +**Steps to take:** Check that you understand the points below, and that your linked filter is set up with them in mind. + +1. A filter isn't part of a specific question. Instead, a filter is added to a dashboard and its value is used to fill in variables in questions. + +2. In order for Metabase to display a dropdown list of possible filter values, it must know that the column corresponds to a category. This happens automatically if the question is created from tables via the Notebook Editor, since Metabase has knowledge about the table and columns from synchronization. + +3. If the question that contains the variable is written in SQL, on the other hand, the author of the question must have selected "Field Filter". Also, the field referenced must be set as a category in the Table Metadata in order for Metabase to show a dropdown list of values. + +## Are the filters linked in the correct direction? + +**Root cause:** The most common cause is that the filters have been linked in the wrong direction. If you want the values shown by Filter B to be restricted by the setting of Filter A, you have to change the settings for Filter B, not Filter A---i.e., the downstream filter has the setting, not the upstream filter. + +**Steps to take:** + +1. Remove the existing linkage and create a new one in the opposite direction. + +## Do some rows actually satisfy the full filter condition? + +**Root cause:** There aren't any rows that satisfy all the conditions in a linked filter. Continuing with the city and state example, if you manually enter the name of a city that isn't in the selected state, no record will satisfy both conditions. + +**Steps to take:** + +1. Create a question that only uses the first filter and check that it produces some rows. (If it does not, adding a second filter isn't going to make any rows appear.) +2. Create a question that you think should produce the same result as the combination of linked filter settings that isn't producing any data. If it produces the result you expect, check for typing mistakes and that you are using [the correct type of join][join-types]. + +## Do all rows that pass the first test also pass the second? + +**Root cause:** In some cases all of the rows that satisfy the first filter's condition also satisfy the second filter's condition, so the second filter has no effect. + +**Steps to take:** + +1. Create a question that includes the first filter condition directly (i.e., in the question rather than using a variable), then add the second filter's condition. If the result set does not change, the problem is in the logic rather than in the filters. + +## Does the linked filter widget display a dropdown of filtered values? + +**Root cause:** In order for a linked filter widget to display the correct subset of values as a dropdown, an explicit [foreign key][foreign-key-gloss] definition must be set up---linking the filters does not by itself tell Metabase about the relationship. + +**Steps to take:** + +1. Check that Metabase's table metadata for your database includes the foreign key relationship. + +[filter-widget-gloss]: /glossary/filter_widget +[foreign-key-gloss]: /glossary/foreign_key +[join-types]: /learn/grow-your-data-skills/learn-sql/working-with-sql/sql-join-types +[learn-linking]: /learn/metabase-basics/querying-and-dashboards/dashboards/linking-filters +[linked-filter-gloss]: /glossary/linked_filter diff --git a/_docs/doc-update-detection/troubleshooting-guide/loading-from-h2.md b/_docs/doc-update-detection/troubleshooting-guide/loading-from-h2.md new file mode 100644 index 000000000..3ccebb690 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/loading-from-h2.md @@ -0,0 +1,141 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Using or migrating from an H2 application database' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/loading-from-h2.md' +--- + +# Using or migrating from an H2 application database + +You've installed Metabase, but: + +- You're trying to migrate the application database from H2 to another database and something has gone wrong, +- You're trying to downgrade rather than upgrade, +- Metabase logs a `liquibase` error message when you try to run it, +- Metabase logs another error message that mentions `H2` or `h2` while it is running, or +- You're on Windows 10 and get a warning about file permissions. + +## Are you currently using H2 as your application database? + +**Root cause:** Metabase stores information about users, questions, and so on in a database of its own called the "application database", or "app database" for short. By default Metabase uses H2 for the application database, but we don't recommended it for production---because it's an on-disk database, it's sensitive to filesystem errors, such as a drive being corrupted or a file not being flushed properly. + +**Steps to take:** + +1. To check what you're using as the app database, go to **Admin Panel**, open the **Troubleshooting** tab, scroll down to "Diagnostic Info", and look for the `application-database` key in the JSON it displays. +2. See [Migrating from H2](../installation-and-operation/migrating-from-h2) for instructions on how to migrate to a more robust app database. + +## Are you trying to migrate the application database from H2 to something else? + +**Root cause:** You are trying to [migrate](../installation-and-operation/migrating-from-h2) the app database from H2 to a production database such as PostgreSQL or MySQL/MariaDB using the `load-from-h2` command, but this has failed because the database filename is incorrect with an error message like: + +``` +Command failed with exception: Unsupported database file version or invalid file header in file +``` + +**Steps to take:** + +1. Create a copy of the exported H2 database (see [Backing up Metabase Application Data][backup]). _Do not proceed until you have done this_ in case something goes wrong. + +2. Check that the H2 database file you exported is named `metabase.db.mv.db`. + +3. H2 automatically adds `.mv.db` extension to the database path you specify on the command line, so make sure the path to the DB file you pass to the command does _not_ include the `.mv.db` extension. For example, if you've exported an application database, and you want to load the data from that H2 database into a PostgreSQL database using `load-from-h2`, your command will look something like: + + ``` + export MB_DB_TYPE=postgres + export MB_DB_DBNAME=metabase + export MB_DB_PORT=5432 + export MB_DB_USER= + export MB_DB_PASS= + export MB_DB_HOST=localhost + java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar load-from-h2 /path/to/metabase.db # do not include .mv.db + ``` + +If you're using a [Pro or Enterprise version of Metabase][enterprise], you can use [serialization][serialization-docs] to snapshot your application database. Serialization is useful when you want to [preload questions and dashboards][serialization-learn] in a new Metabase instance. + +## Are you trying to downgrade? + +**Root cause:** Metabase does not support downgrading (i.e., reverting to an early version of the application). + +**Steps to take:** + +1. Shut down Metabase. +2. Restore the backup copy of the app database you made before trying to upgrade or downgrade. +3. Restore the JAR file or container of the older version you want to revert to. +4. Restart Metabase. + +## Is the app database locked? + +**Root cause:** Sometimes Metabase fails to start up because an app database lock did not clear properly during a previous run. The error message looks something like: + +``` +liquibase.exception.DatabaseException: liquibase.exception.LockException: Could not acquire change log lock. +``` + +**Steps to take:** + +1. Open a shell on the server where Metabase is installed and manually clear the locks by running: + + ``` + java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar migrate release-locks + ``` + +2. Once this command completes, restart your Metabase instance normally (_without_ the `migrate release-locks` flag). + +## Is the app database corrupted? + +**Root cause:** H2 is less reliable than production-quality database management systems, and sometimes the database itself becomes corrupted. This can result in loss of data in the app database, but can _not_ damage data in the databases that Metabase is connected. + +**Steps to take:** Error messages can vary depending on how the app database was corrupted, but in most cases the log message will mention `h2`. A typical command and message are: + +``` +myUser@myIp:~$ java --add-opens java.base/java.nio=ALL-UNNAMED -cp metabase.jar org.h2.tools.RunScript -script whatever.sql -url jdbc:h2:~/metabase.db +Exception in thread "main" org.h2.jdbc.JdbcSQLException: Row not found when trying to delete from index """"".I37: ( /* key:7864 */ X'5256470012572027c82fc5d2bfb855264ab45f8fec4cf48b0620ccad281d2fe4', 165)" [90112-194] + at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) + [etc] +``` + +**How to fix this:** not all H2 errors are recoverable (which is why if you're using H2, _please_ have a backup strategy for the application database file). + +If you are running a recent version and using H2, the app database is stored in `metabase.db.mv.db`. - Open a shell on the server where the Metabase instance is running and attempt to recover the corrupted H2 file by running the following four commands: + +``` +java -cp metabase.jar org.h2.tools.Recover + +mv metabase.db.mv.db metabase-old.db.mv.db + +touch metabase.db.mv.db + +java --add-opens java.base/java.nio=ALL-UNNAMED -cp target/uberjar/metabase.jar org.h2.tools.RunScript -script metabase.db.h2.sql -url jdbc:h2:`pwd`/metabase.db +``` + +## Are you running Metabase with H2 on Windows 10? + +**Root cause:** In some situations on Windows 10, the Metabase JAR needs to have permissions to create local files for the application database. When running the JAR, you'll see an error message like this: + +``` +Exception in thread "main" java.lang.AssertionError: Assert failed: Unable to connect to Metabase DB. +``` + +**Steps to take:** + +1. Right-click on the Metabase JAR file (_not_ the app database file). +2. Select "Properties". +3. Select "Unblock." + +## Is the application database taking too long to load? + +**Root cause:** You're using H2 as your app database, and the app database is so large that it can't be loaded in less than 5 seconds (which is the default timeout value). You'll see the message "Timeout" appear in the console when you try to start Metabase. + +**Steps to take:** + +1. Use a production-quality database such as PostgreSQL for the app database (preferred). +2. Go to the **Admin Panel** and increase the timeout setting for the app database. +3. Move Metabase to a faster server (in particular, a server with faster disks). + +[backup]: ../installation-and-operation/backing-up-metabase-application-data +[enterprise]: /pricing +[serialization-docs]: ../installation-and-operation/serialization +[serialization-learn]: /learn/metabase-basics/administration/administration-and-operation/serialization diff --git a/_docs/doc-update-detection/troubleshooting-guide/models.md b/_docs/doc-update-detection/troubleshooting-guide/models.md new file mode 100644 index 000000000..3b6375893 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/models.md @@ -0,0 +1,82 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting models' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/models.md' +--- + +# Troubleshooting models + +What kind of problem are you having with your [model][model-docs]? + +## Can't create a model + +If you don't see [the model button][model-button-image] (three squares): + +1. Check if you're using a Metabase version that's 0.42.0 or greater by going to the top right of the screen and clicking on the **gear** icon > **About Metabase**. +2. Clear your browser cache. +3. Ask your Metabase admin to clear the proxy cache (if you're using one). + +## Can't edit or save changes to a model + +If your changes to a model's metadata or underlying question aren't showing up: + +1. Refresh your browser to confirm you're not viewing cached results. +2. Search for [known model issues][known-issues-models] using the label `Querying/Models`. For more information, go to [How to find a known bug or limitation][known-issues]. + +## Model performance is poor + +1. Use model persistence. + + - Metabase can [write back to your data warehouse][model-persistence]. If you enable model persistence, Metabase will read a pre-computed and materialized version of the model directly from the database instead of running the query from scratch. Please consider this option is only available in some supported data warehouses. + +2. Optimize the underlying saved question or SQL query. + + - [Ask for less data][limit-data-learn]. + - For models that use SQL questions, [look for bottlenecks using SQL EXPLAIN][sql-explain-learn]. + +3. Optimize your database schemas. + + - [Aggregate data ahead of time with summary tables][summary-tables-learn]. + - [Index frequently queried columns][indexes-learn]. + - [Denormalize your data][denormalize-data-learn]. + - [Materialize views][materialize-views-learn]. + - [Pull data out of JSON and slot its keys into columns][flatten-json-learn]. + +4. Optimize your data warehouse(s) or database(s). + + - [Replicate your database][replicate-database-learn]. + - [Consider a database optimized for analytics][analytics-database-learn]. + +**Explanation** + +Models are a type of saved question, so they will only perform as fast as the original question or SQL query. + +If you want to improve the performance of a model, you can make optimizations at the query, schema, or database level (depending on your data permissions, technical expertise, and willingness to tinker). + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community][discourse]. +- Search for [known model issues][known-issues-models] using the label `Querying/Models`. For more information, go to [How to find a known bug or limitation][known-issues]. + +[analytics-database-learn]: /learn/metabase-basics/administration/administration-and-operation/making-dashboards-faster#consider-a-database-optimized-for-analytics +[denormalize-data-learn]: /learn/metabase-basics/administration/administration-and-operation/making-dashboards-faster#denormalize-data +[discourse]: https://discourse.metabase.com/ +[flatten-json-learn]: /learn/metabase-basics/administration/administration-and-operation/making-dashboards-faster#pull-data-out-of-json-and-slot-its-keys-into-columns +[indexes-learn]: /learn/metabase-basics/administration/administration-and-operation/making-dashboards-faster#index-frequently-queried-columns +[known-issues]: ./known-issues +[known-issues-models]: https://github.com/metabase/metabase/labels/Querying%2FModels +[limit-data-learn]: /learn/metabase-basics/administration/administration-and-operation/making-dashboards-faster#ask-for-less-data +[materialize-views-learn]: /learn/metabase-basics/administration/administration-and-operation/making-dashboards-faster#materialize-views-create-new-tables-to-store-query-results +[model-button-image]: /learn/images/models/model-icon.png +[model-docs]: ../data-modeling/models +[replicate-database-learn]: /learn/metabase-basics/administration/administration-and-operation/making-dashboards-faster#replicate-your-database +[sql-explain-learn]: /learn/grow-your-data-skills/learn-sql/working-with-sql/sql-best-practices#explain +[summary-tables-learn]: /learn/metabase-basics/administration/administration-and-operation/making-dashboards-faster#aggregate-data-ahead-of-time-with-summary-tables +[troubleshooting-sandboxing]: ./sandboxing +[model-persistence]: /docs/latest/data-modeling/model-persistence diff --git a/_docs/doc-update-detection/troubleshooting-guide/my-dashboard-is-slow.md b/_docs/doc-update-detection/troubleshooting-guide/my-dashboard-is-slow.md new file mode 100644 index 000000000..3d112d61c --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/my-dashboard-is-slow.md @@ -0,0 +1,83 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'My dashboard is slow' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/my-dashboard-is-slow.md' +--- + +# My dashboard is slow + +First, you'll want to make sure your browser is on friendly terms with Metabase: + +- Clear your browser cache and disable all extensions before refreshing the page, or +- Try loading the dashboard in a private/incognito session. + +## Dashboard has over 10 cards + +1. Create a new dashboard for each group of cards that are related to the same time period or segment. + - For example, create new dashboards for weekly vs. monthly metrics, or new vs. returning customers. +2. Move your cards to the new dashboard(s) until each dashboard has 10 or fewer cards. +3. Use [custom destinations](/learn/metabase-basics/querying-and-dashboards/dashboards/custom-destinations) to link related cards on different dashboards. + +**Explanation** + +A dashboard with 50 cards is almost always going to be slower than 5 dashboards with 10 cards. Metabase displays a dashboard by refreshing all of the questions on it (that is, re-executing all of the queries against your database). Your data warehouse may try to run these queries at the same time to return the results faster, however, these queries can actually compete with each other and slow things down (like having too many programs open on your computer at once). + +Aside from running faster, a small and focused dashboard is also easier for people to understand without getting overwhelmed. For more tips, check out our article on [BI dashboard best practices](/learn/metabase-basics/querying-and-dashboards/dashboards/bi-dashboard-best-practices). + +## Dashboard used by many people at the same time + +1. Optional: use Metabase's [Usage analytics](../usage-and-performance-tools/usage-analytics) to look at your Metabase usage stats\*. +2. Set up [caching](../configuring-metabase/caching) for the questions on your popular dashboard. +3. Run the dashboard during off-hours so that people can load the cached results in seconds instead of executing a fresh query to your database. + +\* Available on Pro and Enterprise plans. + +**Explanation** + +If you have a dashboard that many people check around the same time (e.g., at the start of the work day), you may end up with queued queries or saturated database connections. Caching allows you to prepare for peak traffic by running those slow queries once, ahead of time, so that the results are ready to go. + +Caching takes less effort because it doesn't involve any changes to your schemas or databases. If you're ready to invest more resources into the root cause of dashboard performance issues, check out this list of common [schema and database optimizations](/learn/metabase-basics/administration/administration-and-operation/making-dashboards-faster#organize-data-to-anticipate-common-questions). + +## Embedded dashboard is slow compared to original dashboard + +1. To speed up the embedded dashboard, set up a [locked parameter to pre-filter your data](../embedding/static-embedding-parameters#restricting-data-in-a-static-embed-with-locked-parameters). + +**Explanation** + +One of the easiest ways to make a question or dashboard run faster is to work with a smaller dataset. Your Metabase admin can apply automatic data limitations using things like [SSO](../people-and-groups/start#authentication), [data permissions](../permissions/data), and [data sandboxing](../permissions/data-sandboxes). + +When someone loads a question or a dashboard in a static embed, however, that question or dashboard will query the full dataset (rather than a smaller dataset limited by permissions). Static, [signed embeds](../embedding/static-embedding) don't require people to be logged in, and unauthenticated people viewing the signed embed won't be subject to the permissions and data restrictions set up by your admin. + +## Dashboard is slow compared to similar dashboards + +1. Remove fields (columns) that you don't need in the final result. +2. Add a [filter](../questions/query-builder/filters) to reduce the amount of data being queried. For example: + - Narrow down the time frame to the reporting period that you care about. + - Exclude invalid records, such as: blanks, nulls, or rows with values like "cancelled", "expired", "invalid", and so on. +3. Remove [joins](../questions/query-builder/join) to tables that aren't being used. +4. If you're aggregating data from the query builder, ask your database admin if there's a pre-aggregated [view](/glossary/view) that you can use instead. + +**Explanation** + +When you update your question to use a minimal number of rows or columns (or switch your question to use a smaller table, such as a summary table) your database can spend less time scanning those records in order to return your results. Narrowing the scope of your question is especially important to think about if you're starting from someone else's saved question or model, because you might not need all of the data that the original creator decided to include. + +If all of your dashboards are slow, you might be limited by the performance of a particular data source. In that case, we recommend teaming up with your database admin to [Troubleshoot database performance](./db-performance). + +## Related problems + +- [Error message: your question took too long](./timeout). +- [Questions that use numbers, dates, or times are slower than other questions](./db-performance#questions-that-use-number-date-or-timestamp-columns). +- [I can't save my question or dashboard](./proxies). +- [I can't view or edit a question or dashboard](./cant-view-or-edit). +- [My visualizations are wrong](./visualization). + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). diff --git a/_docs/doc-update-detection/troubleshooting-guide/permissions.md b/_docs/doc-update-detection/troubleshooting-guide/permissions.md new file mode 100644 index 000000000..d4f0c0e6b --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/permissions.md @@ -0,0 +1,75 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting permissions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/permissions.md' +--- + +# Troubleshooting permissions + +If someone has the wrong level of access to a dashboard or a question, the problem may be coming from group settings, collection permissions, or data permissions. + +1. Go to **Admin** > **People** and check if the person is in [more than one group with different permissions][group-permissions]. +2. If a person **can't view or edit** questions or dashboards, see [Troubleshooting collection permissions](#troubleshooting-collection-permissions). +3. If a person **can't access data**, such as schema, tables, rows, or columns, see [Troubleshooting data permissions](#troubleshooting-data-permissions). + +If you have a different issue, see [related problems](#do-you-have-a-different-problem). + +## Troubleshooting collection permissions + +- [A user group can't access a dashboard in a collection that they have permissions for][troubleshooting-viewing-editing]. +- [A user group can view collections that contain restricted data][collections-restricted-data]. + +## [Troubleshooting data permissions][troubleshooting-data-permissions] + +### Row and column permissions + +- [Troubleshooting data sandboxing][troubleshooting-data-sandboxing]. + +### Native query (SQL) permissions + +- [A user group can't access the SQL editor][sql-access]. +- [A user group with SQL permissions isn't being restricted by their data sandbox][sql-sandboxing]. + +### Table or schema permissions + +- [A user group has the wrong access to a table or schema][table-schema-access]. +- [Getting a "permission denied" error message][permission-denied]. +- [Checking someone's access to a table or schema](./data-permissions#checking-someones-access-to-a-table-or-schema) + +## Do you have a different problem? + +- [I can't save my question or dashboard][proxies]. +- [I can't see my tables](./cant-see-tables). + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community][discourse]. +- Search for [known bugs or limitations][known-issues]. + +[admin-permissions]: ../permissions/start +[collection-permissions]: ../permissions/collections +[collections-restricted-data]: ./data-permissions#a-user-group-can-view-collections-that-contain-restricted-data +[connecting-database]: ../databases/connecting +[data-browser]: /learn/metabase-basics/querying-and-dashboards/data-browser +[data-model]: ../data-modeling/metadata-editing +[data-permissions]: ../permissions/data +[discourse]: https://discourse.metabase.com/ +[group-permissions]: ../permissions/introduction#key-points-regarding-permissions +[known-issues]: ./known-issues +[learn-permissions]: /learn/metabase-basics/administration/permissions +[permission-denied]: ./data-permissions#getting-a-permission-denied-error-message +[proxies]: ./proxies +[sandboxing]: ./sandboxing +[setting-collection-permissions]: ../permissions/collections#setting-permissions-for-collections +[sql-access]: ./data-permissions#a-user-group-cant-access-the-sql-editor +[sql-sandboxing]: ./sandboxing#is-the-question-written-in-sql +[table-schema-access]: ./data-permissions#a-user-group-has-the-wrong-access-to-a-table-or-schema +[troubleshooting-data-permissions]: ./data-permissions +[troubleshooting-data-sandboxing]: ./sandboxing +[troubleshooting-viewing-editing]: ./cant-view-or-edit diff --git a/_docs/doc-update-detection/troubleshooting-guide/proxies.md b/_docs/doc-update-detection/troubleshooting-guide/proxies.md new file mode 100644 index 000000000..1960bb0be --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/proxies.md @@ -0,0 +1,40 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Can''t save questions or dashboards, or getting a blank page' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/proxies.md' +--- + +# Can't save questions or dashboards, or getting a blank page + +If attempting to save a question or dashboard sometimes fails, or Metabase only loads a blank page, the problem might be the use of a proxy. A proxy could include other functions like a web application firewall (WAF), content optimization, or cache. Examples of proxies that are known to cause issues with Metabase include: + +- Cloudflare's Rocket Loader and WAF +- Azure's WAF +- PageSpeed module for Apache +- Some anti-virus browser extensions or add-ons + +## Saving questions or dashboards fails + +If saving questions or dashboards fails and the save button displays "Save Failed," or if you get the error, "Sorry you do not have permission to see that," the problem might be with a WAF like Cloudflare or Azure. + +- When the save fails, check the Console tab of your browser's Developer Tools for any errors. +- You should also check the Network tab in the Developer Tools in your browser to view the network request. It will usually fail with error code 403, indicating the error is coming from the WAF and not Metabase. + +Clicking on the request will show more information, and looking at the headers will usually indicate where it originated from. + +Some WAFs have dynamic protection, which means that the problem might only occur after an upgrade of Metabase, and might go away after a few days. + +The solution is to disable the WAF for Metabase. Some services will show which rules were triggered, so it might be enough to disable those rules. + +## Seeing a blank page instead of the Metabase interface + +If Metabase displays a blank page instead of its interface, the problem is usually with content optimization like PageSpeed or Cloudflare's Rocket Loader. + +- Check the Console tab of your browser's Developer Tools for any errors involving Content Security Policy (CSP). +- See if Metabase has been able to deliver the HTML code by right clicking on the blank page and selecting "View page source." It might look like gibberish, but it should say `Metabase` near line 25. + +The solution is to disable content optimization for Metabase. diff --git a/_docs/doc-update-detection/troubleshooting-guide/requesting-new-features.md b/_docs/doc-update-detection/troubleshooting-guide/requesting-new-features.md new file mode 100644 index 000000000..5e4a20c63 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/requesting-new-features.md @@ -0,0 +1,43 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'How to request new features' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/requesting-new-features.md' +--- + +# How to request new features + +1. Check out the [issues in the github repo][github-issues] to make sure someone hasn't already requested the feature. +2. If someone has already requested the feature, click on the thumbs emoji to vote for the issue. +3. If you can add more context about the feature, add a comment that describes your use case or any nuances important to the feature that the description of the issue doesn't already cover. Avoid comments like "Any updates?" +4. If your feature idea isn't listed, create a [new feature request issue][feature-request]. + +## Feature description prompts + +Follow these prompts when creating your issue. + +**Is your feature request related to a problem? Please describe.** + +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** + +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** + +A clear and concise description of any alternative solutions or features you've considered. + +**How important is this feature to you?** + +Note: the more honest and specific you are here the more we will take you seriously. + +**Additional context** + +Add any other context or screenshots about the feature request here. + +[github-issues]: ./known-issues#how-to-find-a-known-product-limitation +[feature-request]: https://github.com/metabase/metabase/issues/new?assignees=&labels=.Needs+Triage%2C+Type%3ANew+Feature&template=feature_request.md diff --git a/_docs/doc-update-detection/troubleshooting-guide/running.md b/_docs/doc-update-detection/troubleshooting-guide/running.md new file mode 100644 index 000000000..c381e7411 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/running.md @@ -0,0 +1,102 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting memory and JVM issues' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/running.md' +--- + +# Troubleshooting memory and JVM issues + +Metabase runs on the Java Virtual Machine (JVM), and depending on how it's configured, it may use the server's filesystem to store some information. Problems with either the JVM or the filesystem can therefore prevent Metabase from running. + +## Java version + +Metabase should be run on Java version 21 (older versions are unsupported). + +When searching for versions of Java, always use the latest minor version of the major version you're choosing. E.g., when choosing between Java 21.0.1 and Java 21.0.4, choose the latest version (in this case, 21.0.4). + +We recommend running only one version of Java on a single server, because running more than one version of Java on a single server can cause application problems. If you need to run multiple applications that each require a different java version, consider using containers (as containers were meant to solve this problem). Otherwise, just make sure that you can run all your applications with a single Java version. + +## Metabase's memory usage + +Metabase ships as a JAR file that runs on the Java Virtual Machine (JVM). + +It's important to distinguish _Metabase's_ memory usage from the _JVM's_ memory usage. + +The JVM will consume a constant amount of memory. By default, the JVM will use about one fourth of a machine's RAM (though you can [change how much RAM you want the JVM to use](#allocating-more-memory-to-the-jvm)). + +JVM applications (like Metabase) will consume and release the RAM allocated to the JVM. The JVM, however, won't release unused RAM to the machine; the JVM's memory use will be constant. + +So on a machine with 8 GB of RAM, by default the JVM will use 2 GB of RAM. Metabase will use some or all of these 2 GBs of JVM-allocated RAM, depending on Metabase's activity. But from the machine's perspective, the JVM will always be using that allocated 2GB of RAM, even when Metabase is only using a fraction of that allocated RAM. + +## Diagnosing memory issues + +Given the above explanation of how the JVM handles memory, if you're having performance issues with Metabase that you don't think are due to your data warehouse, you'll want to check for these red flags: + +## Metabase crashes due to Java heap space `OutOfMemoryError` + +The JVM can normally figure out how much RAM is available on the system and automatically set a sensible upper bound for heap memory usage. On certain shared hosting environments, however, this doesn't always work as desired. The usual symptom of this is an error message like: + +``` +java.lang.OutOfMemoryError: Java heap space +``` + +If you're seeing this "Out of memory" (OOM) error, you'll need to [allocate more memory to the JVM](#allocating-more-memory-to-the-jvm). + +### When viewing memory usage over time as a line chart, you see a sawtooth pattern + +You can use tools to view how Metabase uses the memory available to it over time. Check out: + +- [Observability with Prometheus](../installation-and-operation/observability-with-prometheus) +- [Monitoring your Metabase](../installation-and-operation/monitoring-metabase) + +The specific Prometheus metric you need to check is jvm_memory_bytes_used{area="heap"} + +A red flag to look out for: the sawtooth pattern. Metabase will quickly consume a lot of memory, which will trigger garbage collection, which frees up memory, which Metabase quickly consumes again. This up-down-up-down pattern of memory usage is the signature of frequent garbage collection cycles. The garbage collection will tie up CPU cycles, which can slow down your application. + +If you're seeing this, you'll need to [increase the amount of memory allocated to the JVM](#allocating-more-memory-to-the-jvm). + +## Allocating more memory to the JVM + +You can set a JVM option to allocate more memory to the JVM's heap. For example, your Java runtime might use the `-X` flag to do this: + +```sh +java -Xmx2g -jar metabase.jar +``` + +Adjust the memory allocation upward until Metabase seems happy, but make sure to keep the number lower than the total amount of RAM available on your machine, because Metabase won't be the only process running. Leaving 1 to 2 GB of RAM for other processes on the machine is generally enough, so you might set `-Xmx` to `1g` on a machine with 2 GB of RAM, `2g` on one with 4 GB of RAM, and so on. You may need to experiment with this settings to find one that makes Metabase and everything else play nicely together (and this experimentation may require upgrading to a machine with more memory). + +You can also use the environment variable `JAVA_OPTS` to set JVM args instead of passing them directly to `java`. This is particularly useful when running the Docker image: + +```sh +docker run -d -p 3000:3000 -e "JAVA_OPTS=-Xmx2g" metabase/metabase +``` + +## Diagnosing memory issues causing OutOfMemoryErrors + +If the Metabase instance starts and runs for a significant amount of time before running out of memory, there might be a specific event, such as a large query, triggering the `OutOfMemoryError`. One way to diagnose where the memory is being used is to enable heap dumps when an `OutOfMemoryError` is triggered. To enable this, you need to add two flags to the `java` invocation: + +``` +java -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/a/directory -jar metabase-jar +``` + +The `-XX:HeapDumpPath` flag specifies where to put the dump---the current directory is the default. When an `OutOfMemoryError` occurs, the JVM will dump an `hprof` file to the directory specified. These `hprof` files can be large (the size of the `-Xmx` argument) so make sure your disk has enough space. These `hprof` files can be read with many different tools, such as `jhat` (which is included with the JDK) or the [Eclipse Memory Analyzer Tool][eclipse-memory-analyzer]. + +## Metabase cannot read or write from a file or folder (IOError) + +If you see an error regarding file permissions, like Metabase being unable to read a SQLite database or a custom GeoJSON map file, check out the section "Metabase can't read to/from a file or directory" in our [Docker troubleshooting guide](./docker). + +## WARNING: sun.reflect.Reflection.getCallerClass is not supported + +Don't worry about it. + +``` +WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance. +``` + +If you see the above error, ignore it. Your Metabase is perfectly healthy and performing as it should. + +[eclipse-memory-analyzer]: https://www.eclipse.org/mat/ diff --git a/_docs/doc-update-detection/troubleshooting-guide/saml.md b/_docs/doc-update-detection/troubleshooting-guide/saml.md new file mode 100644 index 000000000..d9e5bb244 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/saml.md @@ -0,0 +1,77 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting SAML authentication setup' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/saml.md' +--- + +# Troubleshooting SAML authentication setup + +{% include plans-blockquote.html feature="SAML authentication" %} + +Some common problems when setting up SAML. + +## Does your app support SAML? + +Verify that the application you created in your IdP supports SAML. Sometimes other options are presented during the app creation process. + +## Is the issuer or Entity ID correct? + +After filling out the authentication form with your identity provider, you're taken back to Metabase but it throws an error. To see the error, go to **Admin settings** > **Troubleshooting** > **Logs**. You'll see an error that says something like **Incorrect response **. + +**Root cause**: Your issuer or Entity ID is incorrect. + +**Steps to take**: + +1. You should have received an XML file of metadata from your identity provider. Open that metadata file, and look for the correct issuer or Entity ID. This ID is a unique identifier for the identity provider. Depending on your provider, the issuer or Entity ID usually looks something like this: + ``` + http://www.example.com/141xkex604w0Q5PN724v + ``` +2. Copy the issuer or Entity ID from the XML file. +3. Go to Metabase and select **Admin settings** > **Settings** > **Authentication** > **SAML**. Enter the issuer or Entity ID into the **SAML Identity Provider Issuer** field. + +## Is the SAML identity provider certificate value correct? + +After filling out the authentication form with your identity provider, you go back to Metabase but it throws an error. Go to **Admin settings** > **Troubleshooting** > **Logs**. You'll see an error that says something like **Invalid assertion error **. + +**Root cause**: The certificate value you entered is incorrect. + +**Steps to take**: + +1. Go to Metabase and select **Admin settings** > **Settings** > **Authentication** > **SAML**. Check that the certificate that you entered into the **SAML Identity Provider Certificate** field matches the certificate in the XML file you got from your identity provider. + + - Depending on your provider, you might need to download the XML file, open it in a text editor, then copy and paste the certificate's contents into the **SAML Identity Provider Certificate** field in Metabase. + + - Note that your certificate text may include header and footer comments that look like `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`. These comments should be included when pasting your certificate text into Metabase. + +## Is the SSO URL correct? + +Verify that the Single Sign On URL (or equivalent) that you enter on your SAML provider’s website has `/auth/sso` appended to it. For instance, if you want your users to end up at `https://metabase.mycompany.com`, the full URL should be `https://metabase.mycompany.com/auth/sso`. + +## Searching for private key and found a null + +This error will only occur if you're using **Signed SSO requests**. That is, in Metabase, you've filled out the fields in the configuration section in **Admin settings** > **Settings** > **Authentication** > **SAML** > **Signed SSO requests**. Those fields are: + +- **SAML Keystore Path**: the absolute path to the Keystore file to use for signing SAML requests. +- **SAML Keystore Password**: the password for opening the keystore. +- **SAML Keystore Alias**: the alias for the key that Metabase should use for signing SAML requests. + +**Root cause**: The certificate in the keystore file lacks a private key. + +**Steps to take**: + +1. Add a certificate with a private key to your keystore. + +## Checking if SAML is working correctly + +Go to your Metabase login page. If SAML is working correctly, you should see [a single button to sign in](/glossary/sso) with your identity provider (IdP). Once you're authenticated, you should be automatically redirected to the Metabase home page. + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). diff --git a/_docs/doc-update-detection/troubleshooting-guide/sandboxing.md b/_docs/doc-update-detection/troubleshooting-guide/sandboxing.md new file mode 100644 index 000000000..df087f5c2 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/sandboxing.md @@ -0,0 +1,187 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting sandbox access to rows and columns' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/sandboxing.md' +--- + +# Troubleshooting sandbox access to rows and columns + +[Sandboxing data][sandboxing-your-data] gives some people access to only a subset of the data. (The term comes from the practice of putting children in a sandbox to play safely.) To implement sandboxing, Metabase runs a query that filters rows and/or selects a subset of columns from a table based on [the person's permissions][permissions]; the person's query then runs on the initial query's result (i.e., it runs on the sandboxed data). + +These articles will help you understand how sandboxing works: + +- [Data Sandboxing: setting row-level permissions][row-permissions]. +- [Advanced data sandboxing: limiting access to columns][column-permissions]. + +If you have a different data access issue, see [related problems](#do-you-have-a-different-problem). + +## People can't see **rows** in a table they _should_ be able to see + +### Is a sandbox filtering rows by a user attribute? + +**Root cause:** A sandbox is using user attribute to filter rows. + +**Steps to take:** + +This is expected behavior: using a user attribute to filter rows for a sandboxed table is how sandboxing works. But if you _don't_ want Metabase to filter those rows, you'll need to either: + +- Remove the sandbox (which would grant full access to all rows to everyone with access to that table). Go to **Admin** > **Permissions**, and change the access level for the table. +- Add the person to a group (or create a group) with different permissions to the table. Check out [Guide to data permissions][data-permissions]. + +## People can see **rows** they're _not_ supposed to see + +There are several reasons people could be seeing rows that they're not supposed to see. + +### Are those people also in groups with permission to view the entire table? + +**Root cause:** People are in groups with permissions to view the table, and therefore can see all rows, not just the sandboxed rows. + +**Steps to take:** + +For the person in question, check to see which groups they belong to. Do any of the groups have access to the table you're trying to sandboxed? If so, remove them from that group. Remember that everyone is a member of the "All users" group; which is why we recommend you revoke permissions from the all users group, and create new groups to selectively apply permissions to your data sources. + +### Is the question available via Static embedding or Public Sharing? + +**Root cause**: The question is public. [Public questions][public-sharing], even those that use [Static embedding][static-embedding], can't be sandboxed. If someone views the question without logging into Metabase, Metabase lacks user attributes or group information for filtering the data, so it will show all results. + +**Steps to take**: + +You should _avoid_ public sharing when you are sandboxing data. See [public sharing][public-sharing]. + +### Is the question written in SQL? + +**Root cause**. People with SQL access to a database cannot be sandboxed. They have as much access to the database as the user account used to connect Metabase to the database. Even if you hide tables in Metabase, someone with SQL access to a database would still be able to query those tables. Which is also to say that SQL questions cannot be sandboxed. Sandboxing exclusively applies to questions composed in the query builder (even though you can use a SQL question to create a sandbox, e.g., to create a result set of a table that excludes some columns) +. + +**Steps to take** + +- Don't try to sandbox a question written in SQL, because you can't. + +- If you want to sandbox access, avoid adding the person to a group with SQL access to that table (or any other more permissive access to that table, for that matter). + +- If you want to give them SQL access, but still limit what the person can see, you'll need to set up permissions in your database, and connect that database via the user account with that restricted access. You can connect the same database to Metabase multiple times, each with different levels of access, and expose different connections to different groups. But again, you won't be able to sandbox the data from a person with SQL access. + +### Is the question retrieving data from a non-SQL data source? + +**Root cause:** Data sandboxes do not support non-SQL databases. + +**Steps to take:** + +There is not much you can do here: if you need to sandbox data, [you can't use these databases][unsupported-databases]. + +### If using Single Sign-on (SSO), are user attributes correct? + +**Root cause**: If people are logging in with SSO, but the expected attributes aren't being saved and made available, sandboxing will deny access. + +**Steps to take**: + +Our docs on [Authenticating with SAML][authenticating-with-saml] and [Authenticating with JWT][jwt-auth] explain how to use your identity provider to pass user attributes to Metabase, which (the user attributes) can be used to sandbox data. + +## People can see **columns** they're _not_ supposed to see + +### Did the administrator forget to set up a sandbox? + +**Root cause:** The administrator didn't restrict access to the underlying table when setting up sandboxing. + +**Steps to take**: + +1. Go into **Admin Panel** > **Permissions** for the table in question. +2. Check that the sandbox exists, and that the question used to sandbox the table excludes the columns you don't want people to see. + +### Does the question used to set up the sandbox include the columns? + +**Root cause:** The question used to create the sandbox includes the columns they're not supposed to see. + +**Steps to take**: + +Make sure that you're using a SQL question to create the sandbox, and that you're not including columns you should be excluding. + +If you build a question using the query builder (i.e., use a simple or custom question), you may unintentionally pull in additional columns. You can check exactly which columns are included by viewing the question in the Notebook Editor and clicking on the **View the SQL** button. But again: if you use SQL questions to sandbox the data, this problem goes away. + +## Is the person in _another_ group with a different permission level for the table? + +**Root cause:** You've sandboxed the table with the question, but the person is also in an group with a higher level of access to the table. If a person is in multiple groups, they'll get the most permissive access to a data source across all of their groups. + +**Steps to take**: + +Remove the person from all groups with higher level access to the sandboxed table. If they need some permissions from those other groups, you'll need to create a new group with a new set of permissions that only has sandboxed access to the table in question. + +## People can't see **columns** they _should_ be able to see + +### Do they only have sandboxed access to the table? + +**Root cause:** They only have access to a sandboxed version of the table, where only some columns are shown. + +**Steps to take**: + +Add these people to a group (or create a new group) that has permissions to view the table. + +### Has an administrator hidden fields in the table? + +**Root cause:**: An administrator has hidden fields in the table. + +**Steps to take:** + +Go to **Admin** > **Table Metadata** and find the table. Check to make sure that the fields you want to make visible are not hidden. + +### Is a field remapped to display info from a restricted table? + +**Root cause:** If a table which the person _does_ have sandboxed access has a field that uses remapping to display information from another table which the person lacks sandboxed access to, they won't be able to see the table. For example, if you have remapped an ID field to display a product's name instead, but the person lacks access to the product table, they won't be able to see the column. + +**Steps to take:** + +1. Go to **Admin Panel** > **Table Metadata** for the fields in question. +2. If the value is remapped from a restricted table, change it so that Metabase will use the original value from the table. See [Metadata editing][data-model] for more information. + +### Is the question available via static embedding? + +**Root cause**: [Static embedding][static-embedding] will show all results by default. While it's possible to control filtering with [locked parameters][locked-parameters], static embedding depends only on the token generated by the including page, not whether someone is logged into Metabase. + +**Steps to take**: + +Since someone must log in so that Metabase can apply sandboxed views to that person, avoid using static embedding when you want to restrict row or column access to a table. + +## People can't see data they're supposed to be able to see + +Someone is supposed to be able to view some of the values in a table in their queries, but are denied access or get an empty set of results where there should be data. + +**Root cause**: The administrator restricted access to the table. Administrators usually restrict access to tables as part of sandboxing; if the restrictions are too tight by mistake (e.g., "no access") then people might not be able to see any data at all. + +**Steps to take:** + +1. Check the access level for the groups by going to **Admin Panel** and viewing **Permissions** for the table in question. +2. If the person isn't in a group with access to that table, add them to a group that does, or create a new group with access to that table and add them to that new group. + +## Is the person who can't see the sandboxed data in multiple groups? + +**Root cause:** We only allow one sandbox per table: if someone is a member of two or more groups with different permissions, every rule for figuring out whether access should be allowed or not is confusing. We therefore only allow one rule. + +**Steps to take:** + +The administrator can [create a new group][groups] to capture precisely who's allowed access to what. + +## Do you have a different problem? + +- [I have a different permissions issue][troubleshooting-permissions]. +- [I can't see my tables][cant-see-tables]. + +[authenticating-with-saml]: ../people-and-groups/authenticating-with-saml +[cant-see-tables]: cant-see-tables +[column-permissions]: /learn/metabase-basics/administration/permissions/data-sandboxing-column-permissions +[data-model]: ../data-modeling/metadata-editing +[data-permissions]: /learn/metabase-basics/administration/permissions/data-permissions +[groups]: ../people-and-groups/managing#groups +[jwt-auth]: ../people-and-groups/authenticating-with-jwt +[locked-parameters]: /learn/metabase-basics/embedding/charts-and-dashboards#hide-or-lock-parameters-to-restrict-what-data-is-shown +[permissions]: /learn/metabase-basics/administration/permissions/data-permissions +[public-sharing]: ../embedding/public-links +[row-permissions]: /learn/metabase-basics/administration/permissions/data-sandboxing-row-permissions +[sandboxing-your-data]: ../permissions/data-sandboxes +[static-embedding]: /learn/metabase-basics/embedding/charts-and-dashboards#enable-embedding-in-other-applications +[sandbox-limitations]: ../permissions/data-sandboxes#limitations +[troubleshooting-permissions]: ./permissions +[unsupported-databases]: ../permissions/data-sandboxes#limitations diff --git a/_docs/doc-update-detection/troubleshooting-guide/server-logs.md b/_docs/doc-update-detection/troubleshooting-guide/server-logs.md new file mode 100644 index 000000000..dfce86d7b --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/server-logs.md @@ -0,0 +1,37 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'How to read the server logs' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/server-logs.md' +--- + +# How to read the server logs + +Here's an example log from running a query: + +``` +2021-07-07 15:53:18,560 DEBUG middleware.log :: POST /api/dataset 202 [ASYNC: completed] 46.9 ms (17 DB calls) App DB connections: 1/10 Jetty threads: 3/50 (4 idle, 0 queued) (72 total active threads) Queries in flight: 0 (0 queued); h2 DB 4 connections: 0/1 (0 threads blocked) +``` + +Let's unpack the log: + +- **Time of log:** `2021-07-07 15:53:18,560`. +- **Log level:** `DEBUG`. There are different types of log levels. To learn more, check out [Metabase logs][log-level]. +- **Namespace:**. `middleware.log`. You can tweak your logging level to get more or less information from this namespace. +- **Method:** `POST`. The HTTP method verb, like POST, PUT, GET, DELETE. +- **Path:** `/api/dataset`. The handling URL. Note that URL parameters aren't included, which can make debugging certain issues a little tricky. +- **Code:** `202`. The HTTP status code. +- **ASYNC:** `[ASYNC: completed]`. Whether Metabase could deliver the results to the browser. If Metabase couldn't deliver the results, for example if someone starts a query and closes their browser before the query finishes, the ASYNC status will say "cancelled". +- **Response time:** `46.9 ms`. The time Metabase takes to handle the request (from when Metabase receives the request until it's returned results back to the browser). +- **Database calls:** `(17 DB calls)`. The number of query statements used, which in addition to calls to the queried data source(s), includes calls to the Metabase application database. +- **Application database connections:** `App DB connections: 1/10`. The number of active connections, and the available pool of connections. +- **Jetty threads:** `Jetty threads: 3/50 (4 idle, 0 queued)`. List the number of active threads, and the total pool of threads available. The `(4 idle, 0 queued)` are the spare hot threads, and the number of threads queued. If you find you're maxing out the number threads in your pool, check out [Metabase at scale][scale]. +- **Java threads:** `(72 total active threads)`. The total number of threads Metabase is using. +- **Queries in flight:** `Queries in flight: 0 (0 queued)`. The number of active and queued queries across all database sources connected to Metabase. We recommend checking the **Database info** below for troubleshooting issues with the database related to the request. +- **Database info**:`h2 DB 4 connections: 0/1 (0 threads blocked)`. Shows database type, database ID, connections active/pool (and queue). This info is specific to the database related to the request (in this case a `POST` request), and not to the overall queries in flight. + +[log-level]: ../configuring-metabase/log-configuration +[scale]: /learn/metabase-basics/administration/administration-and-operation/metabase-at-scale diff --git a/_docs/doc-update-detection/troubleshooting-guide/sql.md b/_docs/doc-update-detection/troubleshooting-guide/sql.md new file mode 100644 index 000000000..41990d61f --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/sql.md @@ -0,0 +1,43 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting SQL questions' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/sql.md' +--- + +# Troubleshooting SQL questions + +## Incorrect results + +- [Aggregations (counts, sums, etc.) are wrong](/learn/grow-your-data-skills/learn-sql/debugging-sql/sql-logic#aggregated-results-counts-sums-etc-are-wrong). +- [Results have duplicated rows](/learn/grow-your-data-skills/learn-sql/debugging-sql/sql-logic-duplicated-data). +- [Results are missing rows](/learn/grow-your-data-skills/learn-sql/debugging-sql/sql-logic-missing-data). +- [Dates and times are wrong](./timezones). +- [Data isn't up to date](./sync-fingerprint-scan). + +## SQL variables and field filters + +- [Filter widget doesn't display a dropdown menu of values](../data-modeling/metadata-editing#changing-a-search-box-filter-to-a-dropdown-filter). +- [SQL query contains table aliases](../questions/native-editor/sql-parameters#field-filters-dont-work-with-table-aliases). +- [SQL syntax error: missing `FROM` clause](../questions/native-editor/sql-parameters#field-filters-must-be-connected-to-fields-included-in-the-query). +- [No option to display a filter widget](../questions/native-editor/sql-parameters#field-filter-compatible-types). +- [I don't know the SQL variable type](/learn/grow-your-data-skills/learn-sql/working-with-sql/sql-variables). + +## SQL syntax errors + +For some common error messages, see [error messages](./error-message). + +## Working with JSON in SQL + +Using the `?` operator for working with JSON in SQL may cause queries to fail. On PostgreSQL, you can use `??` instead. + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). +- Hire a [Metabase Expert](/partners/){:target="\_blank"}. diff --git a/_docs/doc-update-detection/troubleshooting-guide/sync-fingerprint-scan.md b/_docs/doc-update-detection/troubleshooting-guide/sync-fingerprint-scan.md new file mode 100644 index 000000000..2ea4e8554 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/sync-fingerprint-scan.md @@ -0,0 +1,178 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting syncs, scans, and fingerprinting' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/sync-fingerprint-scan.md' +--- + +# Troubleshooting syncs, scans, and fingerprinting + +First, check if your data is outdated because of browser caching: + +1. Clear your browser cache. +2. Refresh your Metabase page. +3. Open your Metabase page in an incognito window. + +Once you've confirmed that you're looking at a non-cached view of your tables and columns, tag your database admin for help with troubleshooting: + +- **Syncs**, if your tables or columns are missing, or your column data types are wrong. +- **Scans**, if your column _values_ are missing or wrong (for example, in your filter dropdown menus). +- **Fingerprinting**, if you've triggered a manual scan, but the changes aren't taking effect. + +## Syncing + +1. Make sure your database driver is up to date. +2. Go to **Admin** > **Troubleshooting** > **Logs** to check the status of the sync. +3. Run a query against your database from the Metabase SQL editor to check for database connection or database privilege errors that aren't listed in the logs: + + ```sql + SELECT + * + FROM + "your_schema"."your_table_or_view" + LIMIT 1 + ``` + +4. [Manually re-sync](../databases/sync-scan#manually-syncing-tables-and-columns) the table or view if needed. + +### Special cases + +If you've just set up a new database in Metabase, the initial sync query needs some time to kick off. If the sync hasn't started at all, try [Troubleshooting database connections](./db-connection). + +**Explanation** + +A sync query should show up like this in your database's query execution table (using the [privileges](../databases/users-roles-privileges) for the database user in the database connection details): + +```sql +SELECT + TRUE +FROM + "your_schema"."your_table_or_view" +WHERE + 1 <> 1 +LIMIT 0 +``` + +To run the sync query, Metabase must: + +- successfully connect to your database, and +- be [granted privileges](../databases/users-roles-privileges) to query that database. + +If the [connection is failing](./db-connection) or the database privileges are wrong, the sync query won't be able to run. If Metabase can't sync with your database after you first set it up, then the initial scan and fingerprinting queries won't run either. + +## Unfolding JSON columns with Object records + +1. Go to **Admin** > **Databases** > **your database** > **Show advanced options**. +2. Click **Disable "JSON unfolding"** +3. Click **Save changes**. +4. Click **Sync database schema**. + +**Explanation** + +Metabase will try to unfold JSON and JSONB records during the sync process, which can take up a decent chunk of query execution time. If you have a lot of JSON records, try disabling the automatic unfolding option to pull the sync out of slow-motion. Remember that you can follow the status of the sync from **Admin** > **Troubleshooting** > **Logs**. + +## Scanning + +1. Go to **Admin** > **Table Metadata**. +2. Select the database and table. +3. Go to the column you want to update, and click the **gear** icon. +4. Click **Discard cached field values**. +5. Click **Re-scan this field**. +6. Go to **Admin** > **Troubleshooting** > **Logs** to follow the status of the scan and debug errors from there. + +### Special cases + +If you're waiting for the initial scan to run after connecting a database, make sure the initial sync has completed first (remember you can check the status from **Admin** > **Troubleshooting** > **Logs**). + +**Explanation** + +Scan queries are run against your database to sample column values from the first 1,000 rows in a table or view: + +```sql +SELECT + "your_table_or_view"."column" AS "column" +FROM + "your_schema"."your_table_or_view" +GROUP BY + "your_table_or_view"."column" +ORDER BY + "your_table_or_view"."column" ASC +LIMIT 1000 +``` + +A failed scan is caused by a failed scan query---you can look at the logs to debug the query similar to other queries you'd run directly against your database. + +Note that when you [change a search box filter to a dropdown filter](../data-modeling/metadata-editing#changing-a-search-box-filter-to-a-dropdown-filter) from the Table Metadata, you'll trigger a scan query for that field. If you have a dropdown filter that isn't picking up all the values in a field, remember that Metabase only samples the first 1,000 unique values per field, and stores a maximum of 100 kilobytes of text. If you've got more than 1,000 unique values in a column, or a lot of text-heavy data (like long URLs or survey responses), you can: + +- Use a search box filter for that field. +- Clean up the data further in your [ETL or ELT](/learn/grow-your-data-skills/data-landscape/etl-landscape) process. + +## Fingerprinting + +To manually re-trigger a fingerprinting query for a given column: + +1. Go to **Admin** > **Databases** > **your database** > **Show advanced options**. +2. Toggle ON **Periodically refingerprint tables** and click **Save changes**. +3. Go to **Admin** > **Table Metadata**. +4. Select your database and table. +5. Change the visibility of the table to "Hidden". +6. Change the visibility back to "Queryable". +7. Wait 10 seconds. +8. Go to your column and change the **Type** from "Entity Key" to "No semantic type", and back to "Entity Key". + +### Special cases + +If you're waiting for the initial fingerprinting query to run after connecting a database, make sure the initial sync has completed first (remember you can check the status from **Admin** > **Troubleshooting** > **Logs**). + +If you're using MongoDB, Metabase fingerprints the first 10,000 documents per collection. If you're not seeing all of your fields, it's because those fields might not exist in those first 10,000 documents. For more info, see our [MongoDB reference doc](../databases/connections/mongodb#i-added-fields-to-my-database-but-dont-see-them-in-metabase). + +**Explanation** + +The initial fingerprinting query looks at the first 10,000 rows from a given table or view in your database: + +```sql +SELECT + * +FROM + "your_schema"."your_table_or_view" +LIMIT 10000 +``` + +If the first 10,000 rows aren't representative of the data in a table (for example, if you've got sparse data with a lot of blanks or nulls), you could see issues such as: + +- Incorrect [filter types](../questions/query-builder/filters#filter-types), such as a category when you want a calendar. +- Histogram visualizations that don't work (since Metabase needs a min and max value to generate the bins). + +Metabase doesn't have a built-in option to trigger manual fingerprinting queries. You can "reset" a field's settings using the steps above to try and force a fingerprinting query, but it's not guaranteed to work on all versions of Metabase. + +## Syncing or scanning is taking a long time + +To speed up **syncs**: + +- Restrict the privileges used to connect to the database so that Metabase only syncs a limited subset of schemas or tables. +- [Reduce the frequency of sync queries](../databases/sync-scan#database-syncing). + +To speed up **scans**: + +- [Reduce the frequency of scans, or disable scans entirely](../databases/sync-scan#scanning-for-filter-values). +- Reduce the number of columns being scanned by going to **Admin** > **Table Metadata** and setting **Filtering on this field** to **Search box** or **Plain input box**. + +**Explanation** + +Syncs and scans are ultimately just two kinds of queries that are run against your database, so the speed of execution is limited by the number of queries that are run, the frequency of execution, the size of your data, and the amount of resources you've allocated to your database. Metabase gives you options to adjust the number and frequency of sync and scan queries, since unfortunately, we can't imbue your database with more power... (yet?) + +## Related topics + +- [Troubleshooting database connections](./db-connection). +- [Troubleshooting filters](./filters). +- [How syncs and scans work](../databases/sync-scan#how-database-syncs-work). + +## Are you still stuck? + +If you can't solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). diff --git a/_docs/doc-update-detection/troubleshooting-guide/timeout.md b/_docs/doc-update-detection/troubleshooting-guide/timeout.md new file mode 100644 index 000000000..06d930f56 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/timeout.md @@ -0,0 +1,42 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting connection timeouts' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/timeout.md' +--- + +# Troubleshooting connection timeouts + +If your queries are hanging or timing out, the problem could be coming from your: + +- [Database connection](./db-connection) +- Load balancer +- Reverse proxy server (e.g., Nginx) +- Jetty +- Cloud service + +## Resources for common deployments + +Fixes for timeout problems will depend on your specific setup. These resources may help: + +- [Jetty connectors][configuring-jetty] +- [EC2 Troubleshooting][ec2-troubleshooting] +- [Elastic Load Balancing Connection Timeout Management][elb-timeout] +- [App Engine: Dealing with DeadlineExceededErrors][app-engine-timeout] + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community][discourse]. +- Search for [known bugs or limitations][known-issues]. + +[app-engine-timeout]: https://cloud.google.com/appengine/articles/deadlineexceedederrors +[configuring-jetty]: https://jetty.org/docs/jetty/12/operations-guide/protocols/index.html +[discourse]: https://discourse.metabase.com/ +[ec2-troubleshooting]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/TroubleshootingInstancesConnecting.html +[elb-timeout]: https://aws.amazon.com/blogs/aws/elb-idle-timeout-control/ +[known-issues]: ./known-issues diff --git a/_docs/doc-update-detection/troubleshooting-guide/timezones.md b/_docs/doc-update-detection/troubleshooting-guide/timezones.md new file mode 100644 index 000000000..017e4dcad --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/timezones.md @@ -0,0 +1,88 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'The dates and times in my questions and charts are wrong' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/timezones.md' +--- + +# The dates and times in my questions and charts are wrong + +You are doing calculations with dates and times, or displaying them in charts, but: + +- the values appear to be wrong, or +- summary values are wrong. + +## Is the problem due to time zones? + +**Root cause:** Dates and times are stored using different time zones, but some or all of those time zones aren't taken into account when doing calculations (i.e., the problem is inconsistent data). + +**Steps to take:** + +To fix this problem you'll need answers to these questions: + +1. What is the correct time zone of the data you think is being displayed improperly (i.e., what's the right answer)? +2. Is there an explicit time zone setting on every timestamp, or are some or all timestamps being stored without a time zone? For example, `Dec 1, 2019 00:00:00Z00` includes the time zone (shown after the `Z`), but `Dec 1, 2019` doesn't. +3. What time zone is the database server using? +4. What time zone is Metabase using? + +Once you have these answers, look for cases like these: + +1. Your question or chart is comparing or sorting values with inconsistent or missing time zones. For example, if a flight's departure and arrival times are reported in local time, it can appear to arrive before it has left. +2. Your question is aggregating timetsamps with different time zones: for example, the "daily" totals for your website's traffic include more than 24 hours worth of data because you are using the local dates from East Asia, Europe, and the Americas. + +Once you think you have identified a problem, drill down to understand exactly what time zone conversion is causing the underlying problem. For example, suppose you're looking at a time series with daily values; if your error is happening with weekly totals, you can: + +1. Pick a specific day where you know the number is incorrect. +2. Click on the data point in a chart, or a cell in a result table, and select "See these X." +3. Open this question in two other tabs in your browser. Change the date filters so that one tab has the rows in the underlying table from the _previous_ day, and the other table has the rows in the underlying table from the _next_ day. +4. Check that the date field being used to group the result in the underlying display is correct. If it is different from what you have stored in the database, or what you have in another tool, then the timestamp is being transformed incorrectly across the board. This often happens when you use a date or time lacking an explicit time zone. +5. If the underlying timestamps are correct (which they should if they have explicit time zones), the individual times are probably being grouped into days in a different time zone than the one you want. +6. To find out which time zone they are being transformed to, tweak the times on the date filters on the question you are looking at by moving the start time and start date backwards by an hour until you either get the correct number or you have gone back by 12 hours. (If any of your time zones include India, Newfoundland, or another jurisdiction with a half-step time zone, you may need to do this in half-hour increments.) +7. If that doesn't work, try moving the start and end times forward by an hour until you either get the correct number of you've gone forward by 12 hours. +8. If by this point you have the correct value, it means your time zone was converted by the number of hours forward or backwards you manually set the filter. If that's the case, check whether the offset you've come up with matches either the time zone of the data warehouse or the timezone of Metabase itself. + +## Is the Report Time Zone set incorrectly? + +**Root cause:** Wrong numbers in questions or charts can be caused by a mis-match in the time zone being used by Metabase and the time zone being used by the data warehouse. + +**Steps to take:** + +1. Check the [report timezone setting](../configuring-metabase/localization#report-timezone) from **Admin settings** > **Settings** > **Localization**. +2. If you're using a database that doesn't support the report timezone setting, ensure that Metabase's time zone matches that of the database. Metabase's time zone is the Java Virtual Machine's time zone, typically set via a `-Duser.timezone<..>` parameter or the `JAVA_TIMEZONE` environment variable; exactly how it is set will depend on how you launch Metabase. Note that Metabase's time zone doesn't impact any databases that use a Report Time Zone. + +## Are SQL queries not respecting the Reporting Time Zone setting? + +**Root cause:** We don't currently apply a reporting time zone to the results of SQL queries. + +**Steps to take:** + +Set a reporting time zone explicitly in your SQL query. + +For example, you can write something like this with PostgreSQL: + +```sql +SELECT column::TIMESTAMP AT TIME ZONE 'EST' AS column_est +``` + +This statement casts the column to a `timestamp` data type first, then converts the `timestamp` into a `timestamptz` data type, with time zone 'EST'. + +## Are dates without an explicit time zone being converted to another day? + +**Root cause:** You are grouping by a date (rather than by a time) that lacks a time zone. + +**Steps to take:** + +1. Look at every time field your question uses in the [Data Model Reference](../exploration-and-organization/data-model-reference) and see if any of them are simply a "Date" field. +2. If so, make sure the server time zone reflects the reporting time zone, because when a query is run on Metabase, the server applies the configured time zone to that date. + +## Are you mixing explicit and implicit time zones? + +**Root cause:** You're comparing or doing arithmetic on two dates where one has an explicit time zone and one doesn't. + +**Steps to take:** + +1. This typically happens with a question that uses multiple fields: for example, you're filtering on one timestamp and grouping by another. Check the time zones of each of the dates or times you are using in your question. +2. You'll need to explicitly set the time zone for any value that lacks an explicit time zone. This will need to be done either in a SQL query or by transforming the data in your database to ensure both timestamps have time zones. diff --git a/_docs/doc-update-detection/troubleshooting-guide/visualization.md b/_docs/doc-update-detection/troubleshooting-guide/visualization.md new file mode 100644 index 000000000..b46be2815 --- /dev/null +++ b/_docs/doc-update-detection/troubleshooting-guide/visualization.md @@ -0,0 +1,54 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Troubleshooting Guide' +title: 'Troubleshooting question and dashboard visualizations' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/troubleshooting-guide/visualization.md' +--- + +# Troubleshooting question and dashboard visualizations + +To start, check if your current browser settings are compatible with Metabase: + +1. Clear your browser cache, and refresh your page. +2. Disable all extensions and plugins. Load the page again. +3. Give it one last shot---try opening your page in a private/incognito session, or a different browser. + +## Formatting dashboard cards + +1. Make sure that you're making and saving changes from the [card's settings](../dashboards/introduction#changing-a-cards-visualization-settings) (_not_ the original question's settings). +2. [Reset your card's visualization settings](../dashboards/introduction#resetting-a-cards-visualization-settings). + +**Explanation** + +The visualization settings on a card are independent of the settings on the original question. When you first create a question, your selected visualization type is saved along with the query. When you add that question to a dashboard, the dashboard will display the same visualization as the original question by default. You can override the original visualization type by using the [card's visualization settings](../dashboards/introduction#changing-a-cards-visualization-settings). + +## Visualizing SQL questions + +Go to your SQL question and [change the visualization type](../questions/visualizations/visualizing-results) to a table. Then, check if any of the following situations apply to the raw query results: + +- [Aggregations (counts, sums, etc.) are wrong](/learn/grow-your-data-skills/learn-sql/debugging-sql/sql-logic#aggregated-results-counts-sums-etc-are-wrong). +- [Results have duplicated rows](/learn/grow-your-data-skills/learn-sql/debugging-sql/sql-logic-duplicated-data). +- [Results are missing rows](/learn/grow-your-data-skills/learn-sql/debugging-sql/sql-logic-missing-data). + +**Explanation** + +If your question or dashboard card is powered by a handwritten [SQL query](../questions/native-editor/writing-sql) rather than the [query builder](../questions/query-builder/editor), your visualization is going to be more sensitive to changes in the underlying data (for example, renamed fields, or the sudden appearance of a wild null value). To learn more, read about [Common reasons for unexpected query results](/learn/grow-your-data-skills/learn-sql/debugging-sql/sql-logic#common-reasons-for-unexpected-query-results). + +If you're having problems with things like SQL syntax errors or [SQL variables](/glossary/variable#example-variable-in-metabase), see [Troubleshooting SQL questions](./sql) for more help. + +## Related problems + +- [My dates and times are wrong](./timezones). +- [My dashboard is slow or failing to load](./my-dashboard-is-slow). +- [I can't view or edit my question or dashboard](./cant-view-or-edit). +- [I can't see my tables](./cant-see-tables). + +## Are you still stuck? + +If you can’t solve your problem using the troubleshooting guides: + +- Search or ask the [Metabase community](https://discourse.metabase.com/). +- Search for [known bugs or limitations](./known-issues). diff --git a/_docs/doc-update-detection/usage-and-performance-tools/audit.md b/_docs/doc-update-detection/usage-and-performance-tools/audit.md new file mode 100644 index 000000000..753be9bdf --- /dev/null +++ b/_docs/doc-update-detection/usage-and-performance-tools/audit.md @@ -0,0 +1,120 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Usage and Performance Tools' +title: 'Auditing tools' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/usage-and-performance-tools/audit.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/audit +--- + +# Auditing tools + +> Auditing tools are deprecated. Instead, check out the (much better) [Usage analytics](./usage-analytics). + +{% include plans-blockquote.html feature="Audit logs" %} + +As an administrator of Metabase, you already know the importance of using data to understand how people interact with your products or services. With the Audit tool, you can use Metabase to understand how people in your organization use Metabase. It's, well, meta! + +To view the audit logs, go to the top right of the screen and click on the **gear** icon > **Admin settings** > **Audit**. There's a lot of data available, not only about your people, but also about your questions, dashboards, databases and more! We'll walk you through each of the sections below. + +## People + +### Team members + +Use the **People** section to gain a better understanding of how people are interacting with Metabase. You'll want to pay attention to the **Overview** tab, especially when you first launch Metabase at your organization — it will give you data around how many active and newly created accounts you have each day. Further down the page, you'll see charts showing you which people are most engaged. + +![Team Members](./images/audit-team.png) + +The **Team Members** panel has a view of other options for viewing your team's usage data. The **All Members** tab will give you a list of your team members, and stats about their activity, such as when they were last active. + +The **Audit Log** tab will display, in chronological order, each query, who viewed it, and when. Note that if the person didn't save their query, its name will be listed as `Ad-hoc`. Each query name can be clicked to view more details about the person's interactions with it, including a full revision history. You'll also be able to view the query in Metabase. Note that this link will always show the latest version of the query - use the revision history to see changes over time. + +Throughout the People section, names can be clicked to access the profile of a specific person’s activity. This profile includes: + +- Dashboard views +- Query views +- Downloads +- Subscriptions and Alerts + +![Team Members](./images/audit-teammember.png) + +## Data + +The Data section focuses on your databases, schemas and tables, and is divided into corresponding sections. Look here if you're trying to uncover queries and schemas that need optimization. Each section provides visualizations around the use and speed of querying against your databases, schemas or tables. You will also be able to view lists of stats about all of your databases, schemas and tables. + +![Data](./images/audit-data.png) + +## Items + +The **Items** section focuses on questions, dashboards, downloads, and Subscriptions and Alerts. + +### Questions + +The Questions section will show you your most popular queries, as well as your slowest queries. If queries you think are important aren't appearing on your most popular queries list, you may want to make sure your team is focusing on the right things. + +If important queries are appearing on the list of slowest queries, you will want to look at optimizing them. One option is to adjust your [caching settings](../configuring-metabase/caching), but there are plenty of other options as well. To help you determine if your optimization efforts are heading in the right direction, use the `Query views and speed per day` visualization at the bottom of the page. + +![Items](./images/audit-questions.png) + +A list of all of your questions is available as well, and you can see various data points about each question at a glance: + +- Query Runs +- Average Runtime +- Cache Duration +- Total Runtime +- Database +- Table +- Collection +- Public Link + +You can also click on any question to drill into a more detailed profile showing: + +- View activity +- Revision History +- A full audit log of who viewed the question, and when + +### Dashboards + +The **Dashboards** section helps you understand what dashboards people are looking at, and to make sure they're having a smooth experience. If you notice that a popular dashboard has a high average question loading time, you can investigate further using the Questions section outlined above. + +![Items](./images/audit-dashboards.png) + +A list of all of your dashboards is available as well, and you can see various data points about each dashboard at a glance, such as: + +- Number of views +- Average question execution time(ms) +- Number of cards +- Saved by +- Cache duration +- Public link +- Saved on +- Last edited on + +### Downloads + +Use the **Downloads** section to understand which people are downloading (or exporting) data, and the size (number of rows) of the downloads they're performing. This section contains some visualizations, as well as a list of all downloads. + +### Subscriptions and Alerts + +Here admins can get an overview of all of the [dashboard subscriptions][dashboard-subscriptions] and [alerts][alerts] that are currently active for that Metabase. + +- Dashboard name (or Question name for Alerts) +- Recipients +- Type (e.g., email or Slack) +- Collection +- Frequency +- Created By +- Created At +- Filters + +Admins can add and remove people from a subscription or alert by clicking on the item's **Recipients** number. Admins can also delete the subscription or alert entirely by clicking on the **X** on the relevant line. + +Everyone can view all of their subscriptions and alerts by clicking on the **gear** icon in the upper right and navigating to **Account settings** > **Notifications**. + +For more, see [how permissions work with alerts and subscriptions](../permissions/notifications). + +[alerts]: ../questions/alerts +[dashboard-subscriptions]: ../dashboards/subscriptions diff --git a/_docs/doc-update-detection/usage-and-performance-tools/images/audit-dashboards.png b/_docs/doc-update-detection/usage-and-performance-tools/images/audit-dashboards.png new file mode 100644 index 000000000..7e6a69d61 Binary files /dev/null and b/_docs/doc-update-detection/usage-and-performance-tools/images/audit-dashboards.png differ diff --git a/_docs/doc-update-detection/usage-and-performance-tools/images/audit-data.png b/_docs/doc-update-detection/usage-and-performance-tools/images/audit-data.png new file mode 100644 index 000000000..b1bab9d66 Binary files /dev/null and b/_docs/doc-update-detection/usage-and-performance-tools/images/audit-data.png differ diff --git a/_docs/doc-update-detection/usage-and-performance-tools/images/audit-questions.png b/_docs/doc-update-detection/usage-and-performance-tools/images/audit-questions.png new file mode 100644 index 000000000..01d7faa1e Binary files /dev/null and b/_docs/doc-update-detection/usage-and-performance-tools/images/audit-questions.png differ diff --git a/_docs/doc-update-detection/usage-and-performance-tools/images/audit-team.png b/_docs/doc-update-detection/usage-and-performance-tools/images/audit-team.png new file mode 100644 index 000000000..a1bb5ce67 Binary files /dev/null and b/_docs/doc-update-detection/usage-and-performance-tools/images/audit-team.png differ diff --git a/_docs/doc-update-detection/usage-and-performance-tools/images/audit-teammember.png b/_docs/doc-update-detection/usage-and-performance-tools/images/audit-teammember.png new file mode 100644 index 000000000..fcf9e5ca3 Binary files /dev/null and b/_docs/doc-update-detection/usage-and-performance-tools/images/audit-teammember.png differ diff --git a/_docs/doc-update-detection/usage-and-performance-tools/images/metabase-analytics.png b/_docs/doc-update-detection/usage-and-performance-tools/images/metabase-analytics.png new file mode 100644 index 000000000..29aa97282 Binary files /dev/null and b/_docs/doc-update-detection/usage-and-performance-tools/images/metabase-analytics.png differ diff --git a/_docs/doc-update-detection/usage-and-performance-tools/start.md b/_docs/doc-update-detection/usage-and-performance-tools/start.md new file mode 100644 index 000000000..9f88359b4 --- /dev/null +++ b/_docs/doc-update-detection/usage-and-performance-tools/start.md @@ -0,0 +1,21 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: false +category: 'Usage and Performance Tools' +title: 'Tools overview' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/usage-and-performance-tools/start.md' +--- + +# Tools overview + +Administration tools for managing your Metabase. + +## [Usage analytics](./usage-analytics) + +See how people are using your Metabase. + +## [Admin tools](./tools) + +View question error and model caching logs. diff --git a/_docs/doc-update-detection/usage-and-performance-tools/tools.md b/_docs/doc-update-detection/usage-and-performance-tools/tools.md new file mode 100644 index 000000000..59f3010c6 --- /dev/null +++ b/_docs/doc-update-detection/usage-and-performance-tools/tools.md @@ -0,0 +1,38 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Usage and Performance Tools' +title: 'Admin tools' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/usage-and-performance-tools/tools.md' +redirect_from: + - /docs/doc-update-detection/enterprise-guide/tools +--- + +# Admin tools + +The Admin **Tools** tab contains features for troubleshooting. To get to the Admin tools sections, go to the top right of the screen and click on the **gear** icon > **Admin settings** > **Tools**. + +## Question error logs + +{% include plans-blockquote.html feature="Question error logs" %} + +Metabase will list the questions that returned errors when last run, including the: + +- Error message, +- Database that returned the error, +- Collection that houses the question that errored. + +You can select and rerun multiple questions at a time while you troubleshoot to see whether you've resolved their errors. + +## Model caching logs + +Here you can view the: + +- [Models](../data-modeling/models) being persisted +- The status of the last model query refresh +- When the model was last refreshed +- And who created the persisted model + +You can also click the refresh icon to rerun the model's query to update its results. diff --git a/_docs/doc-update-detection/usage-and-performance-tools/usage-analytics.md b/_docs/doc-update-detection/usage-and-performance-tools/usage-analytics.md new file mode 100644 index 000000000..78ef14c9b --- /dev/null +++ b/_docs/doc-update-detection/usage-and-performance-tools/usage-analytics.md @@ -0,0 +1,421 @@ +--- +version: doc-update-detection +has_magic_breadcrumbs: true +show_category_breadcrumb: true +show_title_breadcrumb: true +category: 'Usage and Performance Tools' +title: 'Usage analytics' +source_url: 'https://github.com/metabase/metabase/blob/master/docs/usage-and-performance-tools/usage-analytics.md' +--- + +# Usage analytics + +{% include plans-blockquote.html feature="Usage analytics" %} + +The **Usage analytics** collection is a special collection that contains view-only questions, dashboards, and models that help you understand how people are using your Metabase. + +![Usage analytics collection](./images/metabase-analytics.png) + +You can find the **Usage analytics** collection under **collections** in the left navigation sidebar. You can also create custom reports. + +These resources are useful for: + +- **Understanding Usage**: Understand how people use your Metabase (e.g., new questions, most active people and groups, and so on). +- **Auditing activity**: Know who viewed or did what and when, including tracking dashboard and question views, queries, downloads, and other activity like changing settings or inviting people to your Metabase. +- **Improving operations**: Know the slowest dashboards and questions, how your database's are performing, who's consuming the most resources, and so on. + +> Metabase creates some default user accounts that you might see in your usage analytics, like `internal@metabase.com`. See [Default accounts](../people-and-groups/managing#default-user-accounts). + +## Access to Usage analytics + +You can find the **Usage analytics** collection under **collections** in the navigation sidebar. By default, only admins can see the Usage analytics collection, but admins can grant other groups view access to it. You can manage permissions for the collection in **Admin settings** > **Permissions** > **Collections**. + +There are only two access types for the Usage analytics collection: **View** and **No access**. Even admins can't curate Usage analytics. + +Additionally, this Usage analytics collection has a default sub-collection called "Custom reports" which you can use to save duplicated/modified questions, dashboards, and models. This sub-collection inherits the same permissions, but it's not view-only; admins have curate access by default, and can grant other groups view access. + +> If you're upgrading from a version older than 48, people in groups with monitoring access will also get access to the Usage analytics collection. But after that initial grandfathering in, the monitoring access privilege is unrelated to the Usage analytics collection; you'll need to specifically grant groups access to the Usage analytics collection. + +## Viewing usage insights for a question, dashboard, or model + +> Only people in groups with view access to the Usage analytics collection will see this Usage insights option. + +To view usage analytics for a question, dashboard, or model: + +- Visit the item. +- Click on the info button in the upper right. +- Click **Insights**. + +Metabase will take you to the relevant usage dashboard and plug in the item's ID. + +## How long Metabase keeps usage data + +By default, Metabase will keep the data about [activity](#activity-log-model), [views](#view-log-model), and [query execution](#query-log-model) for **720 days**. Twice a day, Metabase will delete rows older than this threshold. You can change this limit by adjusting the environment variable [`MB_AUDIT_MAX_RETENTION_DAYS`](../configuring-metabase/environment-variables#mb_audit_max_retention_days). + +Metabase Open Source edition, which is also used on the [Metabase Cloud Starter plan](/pricing/), doesn't collect [Activity](#activity-log-model) and [View](#view-log-model) data. If you upgrade from the Open Source/Starter to a Pro or Enterprise plan, you'll only see View and Activity data in Usage Analytics _starting from the time when you upgraded_. + +## Creating custom reports + +You can duplicate any of the questions, dashboards and models in the Usage analytics collection and tweak them to your liking, but you'll need to save them to a different collection. + +### Custom reports collection + +While you _can_ save custom questions, models, and dashboards wherever you like (except for the Usage analytics collection), we recommend that you save your custom Usage analytics reports in the conveniently named "Custom reports" sub-collection. That way these items inherit the same permissions as the parent Usage analytics collection. + +There is one thing to know about the Custom reports collection: its metadata resets whenever Metabase restarts. While you are able to temporarily rename the Custom reports collection, or give it a description or an Official badge, Metabase will drop this collection's metadata when it restarts. But rest assured that Metabase will preserve any questions, models, events, or dashboards that you add to the Custom reports collection. + +## Dashboards + +The Usage analytics collection includes a set of read-only dashboards. + +### Metabase metrics dashboard + +General information about people viewing and creating dashboards, questions, subscriptions, and alerts. Cards include: + +- Active users last week +- Question views last week +- Questions created last week +- Dashboards created last week +- Alerts and subscriptions created last week +- Weekly active users +- Question views per week +- Most active users +- Most active creators +- Most viewed dashboards +- Most viewed cards + +### Most viewed content dashboard + +View the most relevant content in your Metabase. Cards include: + +- Most viewed dashboards +- Most viewed questions +- Most viewed tables + +### Person overview dashboard + +See what someone's been up to in your Metabase. Cards include: + +- Member of +- Active alerts +- Questions created per month +- Question views per month +- Most viewed dashboards +- Most viewed questions +- Last viewed dashboards +- Last viewed questions +- Last viewed tables +- Recent activity +- Last queries + +### Dashboard overview dashboard + +Information about dashboards, questions, models, and tables. Cards include: + +- Dashboard metadata +- Dashboard views per month +- Question performance +- Most active people on this dashboard +- Questions in this dashboard +- Most active people on this dashboard +- Questions in this dashboard +- Recent activity on dashboard +- Subscriptions on this dashboard + +### Question overview dashboard + +Views, performance, activity, and other data for a particular question. Cards include: + +- Question metadata +- Question views per month +- Question performance +- Most active people on this question +- Dashboards with this question +- Last activity on this question +- Alerts on this question + +### Performance overview dashboard + +Question, dashboard and database performance. Cards include: + +- Slowest dashboards +- Dashboards consuming most resources +- Slowest questions +- Questions consuming the most resources +- Dashboards with more questions in the same tab +- Users consuming the most resources + +> If you're using MySQL or MariaDB as your application database, the Performance overview dashboard won't display results for the cards displaying the 50th and 90th percentile query running times, because MySQL and MariaDB don't support the [Percentile aggregation](../questions/query-builder/expressions-list#percentile). We recommend using PostgreSQL as your application database. + +### Content with cobwebs dashboard + +Dashboards and questions that you could consider archiving. Cards include: + +- Dashboards without recent reviews +- Questions without recent reviews +- Questions that don't belong to a dashboard + +## Models + +The Usage analytics collection includes a bunch of useful models based on Metabase's application database. + +## Activity log model + +Each row of this model describes one event of a particular topic. Fields include: + +- ID +- Topic +- Timestamp +- End Timestamp +- User ID +- Model +- Model ID +- Details + +The topics include: + +- alert-create +- alert-delete +- card-create +- card-delete +- card-update +- dashboard-add-cards +- dashboard-create +- dashboard-delete +- dashboard-remove-cards +- install +- metric-create +- metric-delete +- metric-update +- segment-create +- segment-delete +- segment-update +- setting-update +- subscription-create +- subscription-delete +- user-joined + +## View log model + +Tracks views cards (which includes models), dashboards, and tables. Fields include: + +- ID +- Timestamp +- User ID +- Entity Type (card, dashboard, or table) +- Entity ID +- Entity Qualified ID + +## Query log model + +Information about all queries Metabase ran across all dashboards. Fields include: + +- Entity ID +- Started At +- Running Time Seconds +- Result Rows +- Is Native +- Query Source +- Error +- User ID +- Card ID +- Card Qualified ID +- Dashboard ID +- Dashboard Qualified ID +- Pulse ID +- Database ID +- Database Qualified ID +- Cache Hit +- Action ID + +Query sources include: + +- action +- ad-hoc +- collection +- csv-download +- dashboard +- embedded-dashboard +- embedded-csv-download +- embedded-json-download +- embedded-question +- embedded-xlsx-download +- json-download +- map-tiles +- metabot (experimental) +- public-dashboard +- public-question +- pulse (which includes dashboard subscriptions and alerts) +- question +- xlsx-download + +## Alerts model + +All alerts, both active and archived. + +- Entity ID +- Entity Qualified ID +- Created At +- Updated At +- Creator ID +- Card ID +- Card Qualified ID +- Alert Condition +- Schedule Type +- Schedule Day +- Schedule Hour +- Archived +- Recipient Type +- Recipients +- Recipient External + +### Content model + +Questions, dashboards, models, events, and collections. + +- Entity ID +- Entity Qualified ID +- Entity Type +- Created At +- Updated At +- Creator ID +- Name +- Description +- Collection ID +- Made Public By User +- Is Embedding Enabled +- Archived +- Action Type +- Action Model ID +- Collection Is Official +- Collection Is Personal +- Question Viz Type +- Question Database ID +- Question Is Native +- Event Timestamp + +Entity types include: + +- action +- collection +- dashboard +- event +- model +- question + +## People model + +Everyone in your Metabase, including deactivated accounts. Fields include: + +- User ID +- Email +- First Name +- Last Name +- Full Name +- Date Joined +- Last Login +- Updated At +- Is Admin +- Is Active +- SSO Source +- Locale + +## Dashboard subscriptions model + +Which subscriptions are active, who created them, who's subscribed to them, when they're sent, and more. + +- Entity ID +- Entity Qualified ID +- Created At +- Updated At +- Creator ID +- Archived +- Dashboard Qualified ID +- Schedule Type +- Schedule Day +- Schedule Hour +- Recipient Type +- Recipients +- Recipient External +- Parameters + +## Dashboard cards model + +Each row is a dashboard card: either a question card or a text card. Fields include: + +- ID +- Dashboard ID +- Dashboardtab ID +- Question ID +- Created At +- Updated At +- Size X +- Size Y +- Visualization Settings +- Parameter Mappings + +## Databases model + +Information about your connected data sources. Fields include: + +- Entity ID +- Entity Qualified ID +- Created At +- Updated At +- Name +- Description +- Database Type +- Metadata Sync Schedule +- Cache Field Values Schedule +- Timezone +- Is On Demand +- Auto Run Queries +- Cache Ttl +- Creator ID +- Db Version + +## Tables model + +List of all tables across all connected data sources. Fields include: + +- Entity ID +- Entity Qualified ID +- Created At +- Updated At +- Name +- Display Name +- Description +- Active +- Database ID +- Schema +- Is Upload + +## Fields model + +All fields from all connected data sources. Fields include: + +- Entity ID +- Entity Qualified ID +- Created At +- Updated At +- Name +- Display Name +- Description +- Base Type +- Visibility Type +- Fk Target Field ID +- Has Field Values +- Active +- Table ID + +## System tasks model + +Describes the last 14 days of Metabase internal processes tasks. + +- ID +- Task +- Database Qualified ID +- Started At +- Ended At +- Duration Seconds +- Details diff --git a/_site/docs/TRC.html b/_site/docs/TRC.html new file mode 100644 index 000000000..2ecce8d42 --- /dev/null +++ b/_site/docs/TRC.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+
Click here if you are not redirected. + diff --git a/_site/docs/all.html b/_site/docs/all.html new file mode 100644 index 000000000..e451046bf --- /dev/null +++ b/_site/docs/all.html @@ -0,0 +1,5921 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Available Versions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ +
+ + +

Available docs versions

+ +

We version our docs for every major release, with docs for each major release covering each point release. E.g., docs for v0.XX cover v0.XX.1, v0.XX.2, and so on.

+ +

For product releases, see the list of Metabase releases.

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/data-sources.md b/_site/docs/data-sources.md new file mode 100644 index 000000000..c08edb67d --- /dev/null +++ b/_site/docs/data-sources.md @@ -0,0 +1,325 @@ +# Creating Data Sources + +Data Sources pages use components where we add all the content, and templated contents where all the text is already set, except certain variables. Typically, these variables will be database names. + +## Basic checklist + +1. Add a file to directory `_data-sources`, like `_data-sources/some-name.md`. +2. Add a `data: some-name` frontmatter entry to the file created in 1. +3. Add a `layout: data-sources-new` frontmatter entry to the file created in 1. +4. Add a `website: name.ext` frontmatter entry to the file created in 1. +5. Add a file to `_data/data-sources` like `_data/data-sources/some-name.yml`. +6. Make sure you use the same name in all places marked `some-name` above. +7. Fill out the `yml` file using some of the components listed below, and their APIs. + +At the bottom of this document you can find a [simulated page](#simulated-page) with all the components filled out. + +### Hiding a link on index page + +If you want to hide a link on the index page, add `hide: true` to the frontmatter of the file in `_data-sources/some-name.md`. + +### Regular components (you add all the content) + +### Intro Component + + + +This is the left-hand block on the page. + +This is the only component whose contents are not in the `.yml` file. + +Place its contents as frontmatter in `_data-sources/some-name.md`. + +- `title`: Druid +- `data_source`: Druid +- `summary`: a short phrase, no period at the end +- `image`: /images/datasources/some-name.png +- `logo_image`: /images/datasources/circle/some-name.png +- `full_logo_image`: /images/datasources/some-name.png +- `connector`: Official Connector or Partner Connector, or Community Connector +- `doc_link`: typically /docs/latest/databases/connections/some-name +- `website`: the website URL, like https://www.metabase.com + +### Yaml Components + +Use the components below in `_data/data-sources/some-name.yml`. + +#### Title, text and checkmarked list + + + +- `component`: title-text-and-checks +- `headline`: + - `text`: the text + - `is_large`: optional, set to `true` to make the heading larger +- `subheading`: one paragraph +- `list-items`: a list of strings + +
+ +#### Two Checklists + + + +- `- component`: two-checklists +- `top-checklist`, with entries + - `headline`: the headline + - `list-items`: a list of strings +- `bottom-checklist`, with entries + - `are-list-items-available`: `true`, `false`, or ommitted. If `true`, list item icons will be a checkmark. If `false` or ommitted, they will be an ×. + - `headline`: the headline + - `icon`: the prefix for an icon in the `_includes/svg-icons` directory + - `list-items`: a list of strings + - `tooltip`: a string + +
+ +#### Two Checklists with Features for All Data Sources + + + +- `- component`: two-checklists-with-features-for-all-data-sources +- `bottom-checklist`, with entries + - `are-list-items-available`: `true`, `false`, or ommitted. If `true`, list item icons will be a checkmark. If `false` or ommitted, they will be an ×. + - `icon`: the prefix for an icon in the `_includes/svg-icons` directory + - `tooltip`: a string + - `list-items`: a list of strings + +
+ +#### Carousel + + + +- `component`: carousel +- `items`: list of one of two types + - `type`: youtube + - `id`: only the id of the video, like: OK-eq5obu3o + - `type`: image + - `src`: path and filename + - `alt`: alt text + +
+ +#### FAQ + + + +- `component`: faq +- `items`: a list of + - `question`: Text or HTML + - `answer`: Please wrap each paragraph with a `

` tag. +- `contact-box`: + - `icon`: the prefix for an icon in the `svg-icons` directory + - `text`: a short phrase or two. + - `link`: + - `text`: the text in the link + - `href`: the URL in the link + +


+ +#### Try Metabase Footer + +![image](/images/docs/shared/try-metabase-footer.png) + +- `component`: try-metabase-footer +- `headline`: the headline +- `subheading`: typically a phrase +- `link` + - `text`: the text in the link + - `href`: the URL in the link + +### Templated components (you only add the database name or other variables) + +#### Keep everything in your own cluster + +- `component`: keep-everything-in-your-cluster + `db`: the database name + +It will render as (content only): + +```html +

Keep everything in your own cluster

+

Self-host Metabase and {{ component.db }} to keep everything on your terms. Get your token and go. Both are open source, with optional cloud-hosting.

+``` + +#### Easy-to-use data exploration tools + +- `component`: easy-to-use-data-exploration-tools + `db`: the database name + `list-items`: a list of strings + +It will render as (content only): + +```html +

Easy-to-use data exploration tools for people of all levels

+

Get business intelligence tool with friendly UX that lets everyone make sense of your data in {{ component.db }}.

+ +
    +
  • Interactive dashboards that load as fast as {{ component.db }} does with click-to-explore functionality. +
  • Click to drill through on interactive charts and dashboards, zoom in on timelines or areas of interest, and break out for.
  • +
  • Ask questions with nothing more than clicks in the Query Builder - no SQL required. (or use the SQL editor if that’s more your style).
  • +
  • Set up models and metrics to give less technical team mates metadata rich starting points, with trickier stuff like joins taken care of.
  • +
+``` + +#### In-warehouse Analytics + +- `component`: in-warehouse-analytics + `db`: the database name + +It will render as (content only): + +```html +

In-warehouse {{ component.db }} analytics without extracting data

+

Metabase runs direct queries in {{ component.db }} without extracts, so your reports are always up-to-date with your {{ component.db }} data and don’t require moving large data sets.

+``` + +#### Share data with your team or your customers + +- `component`: share-data-with-your-team + +It will render as (content only): + +```html +

Share data with your team or your customers, easily

+

Put dashboards and charts in front of people with as much interactivity and room to pull threads (or as little) as you want.

+ +
    +
  • Customer-facing analytics is just a snippet away. Embed all of Metabase in your app, or just a dashboard.
  • +
  • Export charts and dashboards to PDF, CSV, or share via a public link.
  • +
  • Set up subscriptions for regularly scheduled updates. Even to people without a Metabase login.
  • +
  • Get alerts when things change unexpectedly.
  • +
+``` + +#### Give data access with granularity< + +- `component`: give-data-access-with-granularity + `db`: the database name + +It will render as (content only): + +```html +

Give data access with granularity

+

For people of all levels to make sense of your data in MongoDB

+ +
    +
  • Granular permissions for viewing and querying data, so people can see (and do) what they need to and nothing else.
  • +
  • Manage people and permissions with SSO to map permissions to user groups and attributes.
  • +
  • Detailed usage analytics lets you see who did what when, for compliance, performance.
  • +
+``` + +### Simulated Page + +The yml below has several components. + +You can use it as a starting point or reference for your page. + +```yml +- component: title-text-and-checks + headline: + text: Analyze data in your MongoDB + is_large: true + subheading: If you’re using MongoDB, you’re probably working with large, diverse - and possibly distributed - data sets. Metabase lets your whole team visualize and explore your data in Mongo. Run MongoDB native queries and analyze non-tabular data. With in-built schema inference and native syntax support, you can plug into MongoDB with no custom connectors required. + list-items: + - "Analyze vast amounts of data with a querying layer that sits on top of your data warehouse so your reports run as quick as Mongo." + - "Metabase lets everyone in your team visualize, query, and run reports without technical skills or needing to ask your data team for help." + +- component: carousel + items: + - type: youtube + id: OK-eq5obu3o + - type: image + src: /images/stats-dashboard.svg + alt: Metabase MongoDB analytics + - type: youtube + id: LgPiQdkV4g8 + - type: image + src: https://placehold.co/1600x900 + alt: Metabase MongoDB analytics + - type: image + src: /images/stats-dashboard.svg + alt: Metabase MongoDB analytics + +- component: title-text-and-checks + headline: + text: Easy-to-use data exploration tools for people of all levels + subheading: For people of all levels to make sense of your data in MongoDB + list-items: + - "Interactive dashboards that load as fast as Mongo does with click-to-explore functionality." + - "Metabase detects the shape of your data in MongoDB to anticipate visualization needs and drill throughs for things like time-series data." + - "Set up models and metrics to let your team ask questions and learn from your data in MongoDB without SQL or unique syntax." + +- component: title-text-and-checks + headline: + text: Give data access with granularity + subheading: For people of all levels to make sense of your data in MongoDB + list-items: + - "Granular permissions for viewing and querying data, so people can see (and do) what they need to and nothing else." + - "Manage people and permissions with SSO to map permissions to user groups and attributes." + - "Detailed usage analytics lets you see who did what when, for compliance, performance." + +- component: title-text-and-checks + headline: + text: Share data with your team or your customers, easily + subheading: For people of all levels to make sense of your data in MongoDB + list-items: + - "Customer-facing analytics is just a snippet away. Embed all of Metabase in your app, or just a dashboard." + - "Export charts and dashboards to PDF, CSV, or share via a public link." + - "Set up subscriptions for regularly scheduled updates. Even to people without a Metabase login." + - "Get alerts when things change unexpectedly." + +- component: title-text-and-checks + headline: + text: MongoDB analytics without extracting data + is_large: true + subheading: Metabase runs direct queries in your MongoDB without extracts, so your reports are always up-to-date with your MongoDB data. + +- component: two-checklists + top-checklist: + headline: Metabase features with MongoDB + list-items: + - Unlimited queries, charts, and dashboards + - Static embedding powered by Metabase + - Send dashboards and reports via email and Slack + - Connect to multiple data sources and integrations + - Single sign on via SAML, LDAP, or JWT + - Interactive embedding with white label customization + bottom-checklist: + list-heading: Not available with MongoDB + tooltip: As a NoSQL database, some Metabase features, like pivot tables, data sandboxing, and saved questions as data sources aren’t available with MongoDB. You can access these features with any other SQL databases. + are-list-items-available: false + list-items: + - Pivot tables + - Data sandboxing + - Saved questions as data sources + +- component: title-text-and-checks + headline: + text: Keep everything in your own cluster + subheading: Self-host Metabase and ClickHouse to keep everything on your terms. Get your token and go. Both are open source, with optional cloud hosting. + +- component: faq + items: + - question: What’s the best business intelligence tool to connect to MongoDB? + answer:

Metabase is best suited for businesses that need a straightforward way for everyone in the team to self-serve analytics without having to rely too heavily on your data team. It's BI that your team will actually enjoy using, at the right price for your scale.

+ - question: How does Metabase connect to MongoDB? + answer:

Credit where it’s due - Domo can be a good fit for larger enterprises or orgs with more extensive data analysis needs, deep pockets, and a lower need for everyone in the org to be able to jump in and run their own reports. It’s got a lot of bells and whistles - and depending on the maturity of your org, your use case and needs, it may be more than you need.

+ - question: Can I use permissions from the MongoDB database in Metabase? + answer:

Metabase is trusted by over 60,000 companies with their analytics, from startups who need their first business intelligence tool through to Enterprises. Metabase open source is the go-to choice for founders and solo-developers to let their teams get answers from data on their own so they’re not running the same reports once a month. Metabase Pro and Enterprise is generally chosen by CTOs, CPOs, Heads of Data who have been there, done that with every other BI tool on the market and need a way to make self-service analytics actually happen.

+ - question: How can you visualize tables in MongoDB? + answer:

Both Metabase and Domo cater to internal analytics, as well as interactive embedded analytics for customers.

Metabase is ideal for quick, intuitive data exploration that lets people in your company click around in interactive dashboard and visualizations to learn from data, or create queries with or without SQL.

Domo may be better suited for complex data analysis and putting detailed visualizations in front of customers.

+ - question: How can you query data in MongoDB? + answer:

Metabase is open source with affordable plans available for additional security and governance features, cloud deployment, and fast, unlimited technical help from engineers.

Domo's pricing is generally higher with user and consumption-based billing and various pricing tiers depending on the use case.

+ - question: How to create dashboards using MongoDB? + answer:

Metabase and Domo both let data analysts work in SQL; and less technically savvy people ask questions without SQL. Metabase's intuitive Query Builder lets non-technical or data savvy people put together analyses with clicks - no SQL necessary. Analysts and data people who prefer to write SQL can fill their boots in the SQL editor.

+ +- component: try-metabase-footer + headline: Try Metabase Starter 14 days free + subheading: Connect to your MongoDB to Metabase, set up in 5 minutes, and start uncovering insights from your data straight out of the box. + link: + href: https://store.metabase.com/checkout + text: Get started +``` diff --git a/_site/docs/doc-update-detection/CONTRIBUTING.html b/_site/docs/doc-update-detection/CONTRIBUTING.html new file mode 100644 index 000000000..92d985c3d --- /dev/null +++ b/_site/docs/doc-update-detection/CONTRIBUTING.html @@ -0,0 +1,3142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Contributing to Metabase | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Contributing to Metabase

+ +

Thank you

+ +

First off, thanks for your interest in Metabase and for wanting to contribute!

+ +

In this guide, we’ll discuss how Metabase is built. This should give you a good sense of our process and where you might want to fit in.

+ +

In general, we like to have an open issue for every pull request as a place to discuss the nature of any bug or proposed improvement. Each pull request should address a single issue, and contain both the fix as well as a description of the pull request and tests that validate that the PR fixes the issue in question.

+ +

For bug fixes, please submit the pull request to target the master branch. From time to time, our team will backport selected critical bug fixes to the stable/release branch.

+ +

For significant feature additions, it is expected that discussion will have taken place in the attached issue. Any feature that requires a major decision to be reached will need to have an explicit design document written. The goals of this document are to make explicit the assumptions, constraints and tradeoffs any given feature implementation will contain. The point is not to generate documentation but to allow discussion to reference a specific proposed design and to allow others to consider the implications of a given design.

+ +

Contributor License Agreement

+ +

We don’t like getting sued, so before merging any pull request, we’ll need each person contributing code to sign a Contributor License Agreement.

+ +

What we’re trying to build

+ +

Metabase is all about letting non-technical users get access to their organization’s data. We’re trying to maximize the amount of power that can be comfortably used by someone who understands their business, is quantitatively bent, but probably only comfortable with Excel.

+ +

It’s important to keep in mind these goals of the Metabase project. Many times +proposals will be marked “Out of Scope” or otherwise deprioritized. This doesn’t mean the proposal isn’t useful, or that we wouldn’t be interested in seeing it done as a side project or as an experimental branch. However, it does mean that we won’t point the core team or contributors to it in the near term. Issues that are slightly out of scope will be kept open in case there is community support (and ideally contributions).

+ +

To get a sense for the end goals, make sure to read the Zen of Metabase.

+ +

Our product process:

+ +

The core team runs a pretty well defined product process. It is actively being tweaked, but the below is a pretty faithful description of it at the time of writing. You should have a clear idea of how we work before jumping in with a PR.

+ +

A) Identify product needs from the community

+ +

We actively look for new feature ideas from our community, user base and our own use of Metabase internally. We concentrate on the underlying problem or need as opposed to requests for specific features. While sometimes suggested features are built as requested, often we find that they involve changes to existing features, and perhaps an entirely different solution to the underlying problem. These will typically be collected in a number of issues, and tagged Proposal

+ +

B) Synthesize these needs into a concrete feature

+ +

We typically will collect a group of issues or suggestions into a new topline feature concept. Typically we’ll create a working document that collects all “Open Questions” regarding to what the feature is meant to do, and more importantly not do. We’ll chat with our users, maybe do in depth interviews and generally try to tightly define the feature. If a feature seems like it will need time to be discussed and scoped, it will be tagged Proposal/Being Discussed to signify that it is still actively under discussion.

+ +

C) Design the feature

+ +

Once a feature has been defined, typically it will be taken on by a product designer. Here, they will produce low fi mocks, get feedback from our users and community, and iterate.

+ +

Once the main UX flows have been dialed in, there will be a hi-fidelity visual design.

+ +

Features that are ready for design are tagged Design Needed. Once a feature has had a reasonably complete visual design it should be tagged Help Wanted.

+ +

D) Build the feature

+ +

Once a feature is tagged Help Wanted, it is considered ready to be built. A core team member (or you, awesomely helpful person that you are) can start working on it.

+ +

If you’re building something that users will see in Metabase, please refer to the Style Guide (found at https://storybook.metabase.com) to learn how and when to use various Metabase UI elements.

+ +

Once one or more people have started to work on a feature, it should be marked In Progress. Once there is a branch+some code, a pull request is opened, linked to the feature + any issues that were pulled together to inform the feature.

+ +

E) Verification and merging

+ +

All PRs that involve more than an insignificant change should be reviewed. See our Code Review Process.

+ +

If all goes well, the feature gets coded up, verified and then the pull request gets merged! High-fives all around.

+ +

If there are tests missing, code style concerns or specific architectural issues in the pull request, they should be fixed before merging. We have a very high bar on both code and product quality and it’s important that this be maintained going forward, so please be patient with us here.

+ +

Ways to help

+ +

The starting point would be to get familiar with Metabase the product, and know your way around. If you’re using it at work, that’s great! If not, download Metabase and play around with it. Read the docs and generally get a feel for the flow of the product.

+ +

Here are some ways you can help, in order of increasing coordination + interaction with us:

+ +

Help with identifying needs and problems Metabase can solve

+ +

If you want to help, try out Metabase. Use it at your company, and report back the things you like, dislike and any problems you run into. Help us understand your data model, required metrics and common usage patterns as much as you can. This information directly affects the quality of the product. The more you tell us about the kinds of problems you’re facing, the better we’ll be able to address them.

+ +

Help us triage and support other users

+ +

Spend time on discourse.metabase.com and on new issues and try to reproduce the bugs reported. For people having trouble with their databases where you have significant knowledge, help them out. Who knows, maybe they’ll end up helping you with something in the future.

+ +

It is helpful if you understand our prioritization framework when responding.

+ +

Tell your friends

+ +

Let your friends know about Metabase. Start a user group in your area. Tweet about us. Blog about how you’re using Metabase, and share what you’ve learned.

+ +

Fix bugs

+ +

By our definition, “Bugs” are situations where the program doesn’t do what it was expected to according to the design or specification. These are typically scoped to issues where there is a clearly defined correct behavior. It’s usually safe to grab one of these, fix it, and submit a PR (with tests!). These will be merged without too much drama unless the PR touches a lot of code. Don’t be offended if we ask you to make small modifications or add more tests. We’re a bit OCD on code coverage and coding style.

+ +

Help with Documentation

+ +

There are a lot of docs, which means keeping them up to date is hard. If you notice inconsistencies, errors, or outdated information, please help us keep them current!

+ +

Note that we cannot accept translations for documentation at this time. We support in-app translations, and only support languages that have 100% coverage. But 1) the in-app text is orders of magnitude shorter than our docs, 2) it changes at a slower pace, and 3) we have a lot of people help out. We may consider supporting docs in multiple languages in the future, but for now we need to focus our resources on improving our existing documentation (and expanding it to include all of the new features we’re adding).

+ +

Working on features

+ +

Some features, eg Database drivers, don’t have any user facing pixels. These are a great place to start off contributing as they don’t require as much communication, discussions about tradeoffs and process in general.

+ +

In situations where a design has already been done, we can always use some help. Chime in on a pull request or an issue and offer to help.

+ +

Generally speaking, any issue in Help Wanted is fair game.

+ +

#YOLO JUST SUBMIT A PR

+ +

If you come up with something really cool, and want to share it with us, just submit a PR. If it hasn’t gone through the above process, we probably won’t merge it as is, but if it’s compelling, we’re more than willing to help you via code review, design review and generally OCD nitpicking so that it fits into the rest of our codebase.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/accessibility.html b/_site/docs/doc-update-detection/accessibility.html new file mode 100644 index 000000000..8bd147d9d --- /dev/null +++ b/_site/docs/doc-update-detection/accessibility.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/actions/basic.html b/_site/docs/doc-update-detection/actions/basic.html new file mode 100644 index 000000000..b546dad46 --- /dev/null +++ b/_site/docs/doc-update-detection/actions/basic.html @@ -0,0 +1,3117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Basic actions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Basic actions

+ +

Basic actions are “implicit” actions that do things that people typically want to do when interacting with a database: Create, Update, Delete. Basic actions auto-track the schema of the source table backing the model. By auto-track the schema, we mean that Metabase will create action forms for people to fill out that include all of the fields from the primary source table that underlies that model.

+ +

If you only want to give people the option to update a subset of columns, or update columns in multiple tables, you can write a custom action.

+ +

Creating basic actions

+ +

Once actions are enabled, you can create basic actions on a new or existing model that only wraps a single database table.

+ +
    +
  1. Select a model and click on the info button, then click on Model detail.
  2. +
  3. On the model detail page, click on the Actions tab.
  4. +
  5. Click on the next to the New Action and select Create basic actions.
  6. +
+ +

Basic action limitations

+ +

Basic actions are only available for “basic” models:

+ +
    +
  • Models built using the graphical query builder. Basic actions are unavailable for models created with native queries (SQL).
  • +
  • The model must “wrap” a single raw table in a database. The query should simply select that table in the data step of the notebook editor, and nothing more: no joins, no custom columns, no filters or summarization, no sorting.
  • +
  • The underlying table can only have one primary (entity) key.
  • +
+ +

Basic action types

+ +

Basic actions

+ +

Basic actions include:

+ + + +

Update

+ +

The update action will present people with a form with editable fields for each column in the primary source table.

+ +

When setting up an Update action on a dashboard, you must pass an entity key (like an ID) to the action from a dashboard filter. For other values, you can either prompt the person to fill in a value for each field, or have a field automatically filled in via parameters (such as values set in dashboard filters).

+ +

Delete

+ +

The Delete action will create a form that prompts people for an entity key, and will delete the record (row) corresponding to that ID in the underlying table that backs the model.

+ +

Create

+ +

The Create action is the INSERT INTO action. The Create action will present a form with editable fields for each column in the primary source table backing the model. Once filled out, the action will insert the record into the primary table that underlies the model.

+ +

Basic actions on dashboards

+ +

When setting up actions on a dashboard, you can either prompt the person to fill in a value for each field, or have a field automatically filled in via parameters (such as values set in dashboard filters).

+ +

The Update basic action requires you to pass a value for the entity key.

+ +

See Actions in dashboards.

+ +

Archiving basic actions

+ +

Because basic actions are made of magic, you cannot archive them. You can just toggle them on or off. From the model detail page, next to the New action button, click on the menu and click Disable basic actions.

+ +

Basic actions from object detail view

+ +

If you have basic actions enabled for a model, you can click on an individual record to view its object detail. From that object detail model, you can click on the ellipses () and select update or delete to modify that specific record.

+ +

Update record from object detail view

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/actions/custom.html b/_site/docs/doc-update-detection/actions/custom.html new file mode 100644 index 000000000..63ad3f010 --- /dev/null +++ b/_site/docs/doc-update-detection/actions/custom.html @@ -0,0 +1,3203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Custom actions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Custom actions

+ +

Write SQL to update records in your databases.

+ +

Custom action

+ +

Creating a custom action

+ +
+

You must be in a group with Native query editing access to create an action

+
+ +

There are two ways to create a custom action:

+ +
    +
  1. Click the + New > Action. When you save your action, you’ll be prompted to associate that action with a model. (NOTE: the Action option will only show up in the + New menu if you’ve first created, or have access to, a model in Metabase.)
  2. +
  3. Via the model detail page: from a model, click on the info button in the upper right. In the upper right of the sidebar, click Model detail > Actions > New action.
  4. +
+ +

In the action editor, you can write your own code to create an action, like writing an action that would only update a subset of the columns in a table. See Example actions.

+ +

Field types for action variables

+ +

For each {{ variable }} that you set in an action, you’ll need to set the field type.

+ +

Each of these variable field types present different options. Click on the gear icon to change options.

+ +

If you don’t require a variable, you can optionally specify a default value for Metabase to use in cases where people don’t fill out the field. In the SQL code, remember to enclose any optional variables and commas in brackets, like [[, column = {{ optional_variable }}]] .

+ +

You can include placeholder text for all fields in the action form.

+ +

Text

+ +
    +
  • Text
  • +
  • Long text
  • +
  • Dropdown
  • +
  • Inline select
  • +
+ +

Number

+ +
    +
  • Number
  • +
  • Dropdown
  • +
  • Inline select
  • +
+ +

Date

+ +
    +
  • Date
  • +
  • Date + Time
  • +
+ +

For both Dropdown and Inline select, you can specify a list of options to present on the form, with each option on its own line.

+ +

Dropdown select

+ +

Appearance

+ +

The appearance tab in the action editor modal will display a preview of the variable’s form element. In the image below, we’ve clicked on the variable’s gear and set the variable to use a text > dropdown list. The appearance section gives a preview for what the form element would look like:

+ +

Appearance gives a preview of the form element

+ +

Action settings

+ +

From the model detail page, click on the three dot menu (…) next to the action. Once in the action editor, click on the gear icon to bring up the action settings.

+ +

Make public

+ +

Creates a publicly shareable link to the action form. Anyone with access to that link can fill out the form and run the action. Useful for creating surveys.

+ +

Public action form

+ +

Set a success message

+ +

Here you can edit the success message, which is the message Metabase will display in the toast that pops up after Metabase hears back from the database that everything went smoothly.

+ +

If something goes wrong, Metabase will display the error message it received from the database.

+ +

Example custom actions

+ +

Example UPDATE action

+ +

You could write an action that would update the plan column for a record in the invoices table in the Sample Database:

+ +

+UPDATE invoices
+SET plan = {{ plan }}
+   [[, payment = {{ payment }}]]
+WHERE
+   id = {{ id }}
+
+
+ +

The above code will create a form that prompts people to input updated values for the (required) plan field and optionally the payment field for a given record specified by ID.

+ +

The code in brackets [[ ]] makes the statement optional: the bracket-enclosed statement will only run if someone inserts a value in the payment field. Note the comma that separates the statements is inside the brackets.

+ +

Example action form

+ +

Example INSERT action

+ +

Insert statements are pretty straightforward:

+ +

+INSERT INTO invoices (
+  account_id
+  ,payment
+  ,expected_invoice
+  ,plan
+  ,date_received
+)
+VALUES (
+  {{ account_id }}
+  ,{{ payment }}
+  ,CAST ({{expected_invoice}} AS boolean)
+  ,{{plan}}
+  ,({{date_received}}
+);
+
+
+ +

Casting field values in actions

+ +

If you get a type error when you submit a form, you may need to CAST the data type in the query so it matches the data type of the target field in the database. Here we’re casting a value to a boolean:

+ +

+UPDATE invoices
+SET expected_invoice = CAST({{expected_invoice}} AS boolean)
+WHERE id = {{id}};
+
+
+ +

Referencing saved questions in actions

+ +

You can also reference saved questions in actions. Here we’re taking the results of a SELECT statement on a saved question (“Potential customers”) and inserting the results into a people_to_write table.

+ +

+WITH prospects AS {{#6-potential-customers}}
+
+INSERT INTO
+  people_to_write (
+  first_name
+  ,last_name
+  ,email
+  )
+SELECT
+  first_name
+  ,last_name
+  ,email
+FROM prospects;
+
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/actions/images/appearance.png b/_site/docs/doc-update-detection/actions/images/appearance.png new file mode 100644 index 000000000..3dcb976a2 Binary files /dev/null and b/_site/docs/doc-update-detection/actions/images/appearance.png differ diff --git a/_site/docs/doc-update-detection/actions/images/basic-actions.png b/_site/docs/doc-update-detection/actions/images/basic-actions.png new file mode 100644 index 000000000..5cd596444 Binary files /dev/null and b/_site/docs/doc-update-detection/actions/images/basic-actions.png differ diff --git a/_site/docs/doc-update-detection/actions/images/custom-action.png b/_site/docs/doc-update-detection/actions/images/custom-action.png new file mode 100644 index 000000000..94ba1f879 Binary files /dev/null and b/_site/docs/doc-update-detection/actions/images/custom-action.png differ diff --git a/_site/docs/doc-update-detection/actions/images/dashboard-action.gif b/_site/docs/doc-update-detection/actions/images/dashboard-action.gif new file mode 100644 index 000000000..dd962a5ed Binary files /dev/null and b/_site/docs/doc-update-detection/actions/images/dashboard-action.gif differ diff --git a/_site/docs/doc-update-detection/actions/images/dropdown.png b/_site/docs/doc-update-detection/actions/images/dropdown.png new file mode 100644 index 000000000..14094b665 Binary files /dev/null and b/_site/docs/doc-update-detection/actions/images/dropdown.png differ diff --git a/_site/docs/doc-update-detection/actions/images/example-action.png b/_site/docs/doc-update-detection/actions/images/example-action.png new file mode 100644 index 000000000..c713cb9cd Binary files /dev/null and b/_site/docs/doc-update-detection/actions/images/example-action.png differ diff --git a/_site/docs/doc-update-detection/actions/images/form.png b/_site/docs/doc-update-detection/actions/images/form.png new file mode 100644 index 000000000..b1dc59318 Binary files /dev/null and b/_site/docs/doc-update-detection/actions/images/form.png differ diff --git a/_site/docs/doc-update-detection/actions/images/public-form.png b/_site/docs/doc-update-detection/actions/images/public-form.png new file mode 100644 index 000000000..ebc378de8 Binary files /dev/null and b/_site/docs/doc-update-detection/actions/images/public-form.png differ diff --git a/_site/docs/doc-update-detection/actions/images/update-record.png b/_site/docs/doc-update-detection/actions/images/update-record.png new file mode 100644 index 000000000..d15fe6bd8 Binary files /dev/null and b/_site/docs/doc-update-detection/actions/images/update-record.png differ diff --git a/_site/docs/doc-update-detection/actions/introduction.html b/_site/docs/doc-update-detection/actions/introduction.html new file mode 100644 index 000000000..416266875 --- /dev/null +++ b/_site/docs/doc-update-detection/actions/introduction.html @@ -0,0 +1,3123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Introduction to actions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Introduction to actions

+ +
+

For now, actions are only available for PostgreSQL and MySQL.

+
+ +

Example action

+ +

What are actions?

+ +

Actions are entities in Metabase that let you build custom forms and business logic.

+ +

Actions let you write parameterized SQL that writes back to your database. Actions can be attached to buttons on dashboards to create custom workflows. You can even publicly share the parameterized forms that actions generate to collect data.

+ +

Here are a few ideas for what you can do with actions:

+ +
    +
  • Mark the customer you’re viewing in a dashboard as a VIP.
  • +
  • Let team members remove redundant data.
  • +
  • Create a customer feedback form and embed it on your website.
  • +
+ +

Actions must be added to a model, but actions only run on the raw tables that back those models (so actions will never edit your model definition).

+ +

Enabling actions for a database

+ +

For actions to work, you’ll first need to do the following two things:

+ +
    +
  1. Enable model actions for the database connection. To enable actions for a database connection, admins should click on the gear icon in the upper right and navigate to Admin settings > Databases, then click on the database you want to create actions for. On the right side of the connection settings form, toggle the Model actions option. For actions to work, the database user account (the account you’re using to connect to the database) must have write permissions. And for now, actions are only supported on PostgreSQL and MySQL databases.
  2. +
  3. Create at least one model from that database. Actions are associated with models, so you’ll need to have created (or have access to) at least one model before you can start creating actions.
  4. +
+ +

Who can use actions

+ +
    +
  • To create or edit an action, a person must be in a group with Native query editing privileges for the relevant database.
  • +
  • To run an action, all you need is view access to the action’s model or dashboard (or a link to a public action).
  • +
+ +

Types of actions

+ +

There are two types of actions:

+ + + +

Running actions

+ +

There are multiple ways to run actions:

+ + + +

Actions change data in tables, which affect models

+ +

Just something to clarify here: actions, even though they are added to models, make their changes to the underlying table that a model queries. Which means that anyone who has access to the underlying table, or to questions or other models based on that table, will be able to see the effects of an action. Tools other than Metabase that are connected to that database will also pick up these changes.

+ +

In this sense, models are containers for actions; models are a way to organize actions. In fact, you could (in theory) add a custom action to a model that performs some update unrelated to its model’s data. For example, you could write a custom action that updates the Accounts table, and add that action to a model that only queries an unrelated table (e.g., the Orders table). But, you know, maybe don’t do that (unless you have a really good reason). Basic actions, however, are only be available for models that wrap a single raw table.

+ +

Before using actions in production, consider playing around with actions on some sample data (like the Sample Database included with Metabase) to get a feel for how they work.

+ +

Action gotchas

+ +
    +
  • If caching is enabled for the relevant table or model, you may not see the effects of an action in Metabase until Metabase refreshes the data (though you can always manually refresh the data).
  • +
  • When creating records on a table that lacks an automatically generated primary key, you’ll need to input an available ID (i.e., an ID not already in use by another record).
  • +
  • You can’t “undo” actions. You can, however, create and run an action to recreate a deleted record, or change an updated record back to its original values (provided you know the original values).
  • +
  • Actions are unavailable for public dashboards, and dashboards in static embeds.
  • +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/actions/start.html b/_site/docs/doc-update-detection/actions/start.html new file mode 100644 index 000000000..56ef30a14 --- /dev/null +++ b/_site/docs/doc-update-detection/actions/start.html @@ -0,0 +1,3061 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Actions overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Actions overview

+ +

An action updating a plan on a dashboard

+ +

Actions let you write parameterized SQL that can then be attached to buttons, clicks, or even added on the page as form elements.

+ +

Introduction to actions

+ +

Use actions to update your data based on user input or values on the page.

+ +

Basic actions

+ +

Metabase will create basic actions that auto-track a model’s schema.

+ +

Custom actions

+ +

Write SQL to create new actions.

+ +

Actions on dashboards

+ +

Add actions on dashboards as buttons that you can pass filter values to.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/administration-guide.html b/_site/docs/doc-update-detection/administration-guide.html new file mode 100644 index 000000000..9664adb8b --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/01-managing-databases.html b/_site/docs/doc-update-detection/administration-guide/01-managing-databases.html new file mode 100644 index 000000000..69161b4c0 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/01-managing-databases.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/02-setting-up-email.html b/_site/docs/doc-update-detection/administration-guide/02-setting-up-email.html new file mode 100644 index 000000000..18cf4025b --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/02-setting-up-email.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/03-metadata-editing.html b/_site/docs/doc-update-detection/administration-guide/03-metadata-editing.html new file mode 100644 index 000000000..9058568fb --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/03-metadata-editing.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/04-managing-users.html b/_site/docs/doc-update-detection/administration-guide/04-managing-users.html new file mode 100644 index 000000000..c04a6c96c --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/04-managing-users.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/05-setting-permissions.html b/_site/docs/doc-update-detection/administration-guide/05-setting-permissions.html new file mode 100644 index 000000000..1a27f99dc --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/05-setting-permissions.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/06-collections.html b/_site/docs/doc-update-detection/administration-guide/06-collections.html new file mode 100644 index 000000000..7cf353186 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/06-collections.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/07-segments-and-metrics.html b/_site/docs/doc-update-detection/administration-guide/07-segments-and-metrics.html new file mode 100644 index 000000000..10f36aa6c --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/07-segments-and-metrics.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/08-configuration-settings.html b/_site/docs/doc-update-detection/administration-guide/08-configuration-settings.html new file mode 100644 index 000000000..1312f0a39 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/08-configuration-settings.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/09-setting-up-slack.html b/_site/docs/doc-update-detection/administration-guide/09-setting-up-slack.html new file mode 100644 index 000000000..d4000c92b --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/09-setting-up-slack.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/10-single-sign-on.html b/_site/docs/doc-update-detection/administration-guide/10-single-sign-on.html new file mode 100644 index 000000000..ee00d0443 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/10-single-sign-on.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/12-public-links.html b/_site/docs/doc-update-detection/administration-guide/12-public-links.html new file mode 100644 index 000000000..99f219b77 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/12-public-links.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/13-embedding.html b/_site/docs/doc-update-detection/administration-guide/13-embedding.html new file mode 100644 index 000000000..818582373 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/13-embedding.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/14-caching.html b/_site/docs/doc-update-detection/administration-guide/14-caching.html new file mode 100644 index 000000000..33a9961db --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/14-caching.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/19-formatting-settings.html b/_site/docs/doc-update-detection/administration-guide/19-formatting-settings.html new file mode 100644 index 000000000..f93eb694e --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/19-formatting-settings.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/20-custom-maps.html b/_site/docs/doc-update-detection/administration-guide/20-custom-maps.html new file mode 100644 index 000000000..da0229446 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/20-custom-maps.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/application-permissions.html b/_site/docs/doc-update-detection/administration-guide/application-permissions.html new file mode 100644 index 000000000..569d7500c --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/application-permissions.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/data-permissions.html b/_site/docs/doc-update-detection/administration-guide/data-permissions.html new file mode 100644 index 000000000..4d5670fd1 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/data-permissions.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/databases/aws-rds.html b/_site/docs/doc-update-detection/administration-guide/databases/aws-rds.html new file mode 100644 index 000000000..460c6f7ad --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/databases/aws-rds.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/databases/bigquery.html b/_site/docs/doc-update-detection/administration-guide/databases/bigquery.html new file mode 100644 index 000000000..df057d4a4 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/databases/bigquery.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/databases/h2.html b/_site/docs/doc-update-detection/administration-guide/databases/h2.html new file mode 100644 index 000000000..69161b4c0 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/databases/h2.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/databases/mongodb.html b/_site/docs/doc-update-detection/administration-guide/databases/mongodb.html new file mode 100644 index 000000000..698d972b9 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/databases/mongodb.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/databases/mysql.html b/_site/docs/doc-update-detection/administration-guide/databases/mysql.html new file mode 100644 index 000000000..618ef7163 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/databases/mysql.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/databases/oracle.html b/_site/docs/doc-update-detection/administration-guide/databases/oracle.html new file mode 100644 index 000000000..95c819031 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/databases/oracle.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/databases/postgresql.html b/_site/docs/doc-update-detection/administration-guide/databases/postgresql.html new file mode 100644 index 000000000..9489760a6 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/databases/postgresql.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/databases/redshift.html b/_site/docs/doc-update-detection/administration-guide/databases/redshift.html new file mode 100644 index 000000000..21614bbe2 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/databases/redshift.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/databases/snowflake.html b/_site/docs/doc-update-detection/administration-guide/databases/snowflake.html new file mode 100644 index 000000000..5dc6b258f --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/databases/snowflake.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/databases/vertica.html b/_site/docs/doc-update-detection/administration-guide/databases/vertica.html new file mode 100644 index 000000000..d1c56fd33 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/databases/vertica.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/localization.html b/_site/docs/doc-update-detection/administration-guide/localization.html new file mode 100644 index 000000000..369a16941 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/localization.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/secure-database-connections-with-ssl-certificates.html b/_site/docs/doc-update-detection/administration-guide/secure-database-connections-with-ssl-certificates.html new file mode 100644 index 000000000..bcb3a6ad5 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/secure-database-connections-with-ssl-certificates.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/ssh-tunnel-for-database-connections.html b/_site/docs/doc-update-detection/administration-guide/ssh-tunnel-for-database-connections.html new file mode 100644 index 000000000..91a35e37f --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/ssh-tunnel-for-database-connections.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/sso.html b/_site/docs/doc-update-detection/administration-guide/sso.html new file mode 100644 index 000000000..d4b0d3687 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/sso.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/supported-browsers.html b/_site/docs/doc-update-detection/administration-guide/supported-browsers.html new file mode 100644 index 000000000..c195f8cca --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/supported-browsers.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/administration-guide/whitelabeling.html b/_site/docs/doc-update-detection/administration-guide/whitelabeling.html new file mode 100644 index 000000000..f05bdac44 --- /dev/null +++ b/_site/docs/doc-update-detection/administration-guide/whitelabeling.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api-documentation.html b/_site/docs/doc-update-detection/api-documentation.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api-documentation.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api.html b/_site/docs/doc-update-detection/api.html new file mode 100644 index 000000000..8b3201265 --- /dev/null +++ b/_site/docs/doc-update-detection/api.html @@ -0,0 +1,12972 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Metabase API documentation | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/api/action.html b/_site/docs/doc-update-detection/api/action.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/action.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/activity.html b/_site/docs/doc-update-detection/api/activity.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/activity.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/alert.html b/_site/docs/doc-update-detection/api/alert.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/alert.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/api-key.html b/_site/docs/doc-update-detection/api/api-key.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/api-key.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/automagic-dashboards.html b/_site/docs/doc-update-detection/api/automagic-dashboards.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/automagic-dashboards.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/bookmark.html b/_site/docs/doc-update-detection/api/bookmark.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/bookmark.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/cache.html b/_site/docs/doc-update-detection/api/cache.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/cache.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/card.html b/_site/docs/doc-update-detection/api/card.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/card.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/channel.html b/_site/docs/doc-update-detection/api/channel.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/channel.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/cloud-migration.html b/_site/docs/doc-update-detection/api/cloud-migration.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/cloud-migration.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/collection.html b/_site/docs/doc-update-detection/api/collection.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/collection.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/dashboard.html b/_site/docs/doc-update-detection/api/dashboard.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/dashboard.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/database.html b/_site/docs/doc-update-detection/api/database.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/database.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/dataset.html b/_site/docs/doc-update-detection/api/dataset.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/dataset.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/ee/advanced-config-logs.html b/_site/docs/doc-update-detection/api/ee/advanced-config-logs.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/ee/advanced-config-logs.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/ee/advanced-permissions-application.html b/_site/docs/doc-update-detection/api/ee/advanced-permissions-application.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/ee/advanced-permissions-application.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/ee/advanced-permissions-impersonation.html b/_site/docs/doc-update-detection/api/ee/advanced-permissions-impersonation.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/ee/advanced-permissions-impersonation.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/ee/audit-app-user.html b/_site/docs/doc-update-detection/api/ee/audit-app-user.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/ee/audit-app-user.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/ee/content-verification-review.html b/_site/docs/doc-update-detection/api/ee/content-verification-review.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/ee/content-verification-review.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/ee/query-reference-validation.html b/_site/docs/doc-update-detection/api/ee/query-reference-validation.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/ee/query-reference-validation.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/ee/sandbox-gtap.html b/_site/docs/doc-update-detection/api/ee/sandbox-gtap.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/ee/sandbox-gtap.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/ee/sandbox-table.html b/_site/docs/doc-update-detection/api/ee/sandbox-table.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/ee/sandbox-table.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/ee/sandbox-user.html b/_site/docs/doc-update-detection/api/ee/sandbox-user.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/ee/sandbox-user.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/ee/sso.html b/_site/docs/doc-update-detection/api/ee/sso.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/ee/sso.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/email.html b/_site/docs/doc-update-detection/api/email.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/email.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/embed.html b/_site/docs/doc-update-detection/api/embed.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/embed.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/field.html b/_site/docs/doc-update-detection/api/field.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/field.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/geojson.html b/_site/docs/doc-update-detection/api/geojson.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/geojson.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/google.html b/_site/docs/doc-update-detection/api/google.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/google.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/ldap.html b/_site/docs/doc-update-detection/api/ldap.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/ldap.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/llm.html b/_site/docs/doc-update-detection/api/llm.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/llm.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/login-history.html b/_site/docs/doc-update-detection/api/login-history.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/login-history.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/metabot.html b/_site/docs/doc-update-detection/api/metabot.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/metabot.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/model-index.html b/_site/docs/doc-update-detection/api/model-index.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/model-index.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/native-query-snippet.html b/_site/docs/doc-update-detection/api/native-query-snippet.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/native-query-snippet.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/notify.html b/_site/docs/doc-update-detection/api/notify.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/notify.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/permissions.html b/_site/docs/doc-update-detection/api/permissions.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/permissions.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/persist.html b/_site/docs/doc-update-detection/api/persist.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/persist.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/premium-features.html b/_site/docs/doc-update-detection/api/premium-features.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/premium-features.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/preview-embed.html b/_site/docs/doc-update-detection/api/preview-embed.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/preview-embed.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/public.html b/_site/docs/doc-update-detection/api/public.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/public.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/pulse.html b/_site/docs/doc-update-detection/api/pulse.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/pulse.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/revision.html b/_site/docs/doc-update-detection/api/revision.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/revision.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/routes.html b/_site/docs/doc-update-detection/api/routes.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/routes.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/scim.html b/_site/docs/doc-update-detection/api/scim.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/scim.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/search.html b/_site/docs/doc-update-detection/api/search.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/search.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/segment.html b/_site/docs/doc-update-detection/api/segment.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/segment.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/serialization.html b/_site/docs/doc-update-detection/api/serialization.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/serialization.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/sso-saml.html b/_site/docs/doc-update-detection/api/sso-saml.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/sso-saml.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/stale.html b/_site/docs/doc-update-detection/api/stale.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/stale.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/table.html b/_site/docs/doc-update-detection/api/table.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/table.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/task.html b/_site/docs/doc-update-detection/api/task.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/task.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/tiles.html b/_site/docs/doc-update-detection/api/tiles.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/tiles.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/timeline-event.html b/_site/docs/doc-update-detection/api/timeline-event.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/timeline-event.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/timeline.html b/_site/docs/doc-update-detection/api/timeline.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/timeline.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/user.html b/_site/docs/doc-update-detection/api/user.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/user.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/api/util.html b/_site/docs/doc-update-detection/api/util.html new file mode 100644 index 000000000..7136bd724 --- /dev/null +++ b/_site/docs/doc-update-detection/api/util.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/code-reviews.html b/_site/docs/doc-update-detection/code-reviews.html new file mode 100644 index 000000000..18a9ddab1 --- /dev/null +++ b/_site/docs/doc-update-detection/code-reviews.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/configuring-metabase/appearance.html b/_site/docs/doc-update-detection/configuring-metabase/appearance.html new file mode 100644 index 000000000..1d1c5271c --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/appearance.html @@ -0,0 +1,3239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Appearance | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Appearance

+ +
+
+ + + + + + + +

Custom appearance is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Appearance settings give admins the option to whitelabel Metabase to match your company’s branding.

+ +

If you’re looking for date, time, number, or currency formatting, see Formatting defaults.

+ +

Changing Metabase’s appearance

+ +

Hit cmd/ctrl + k to bring up the command palette and search for “Appearance” and click on Settings -> Appearance.

+ +

You can also click on the gear icon at the bottom of the navigation sidebar and click through Admin settings > Settings > Appearance.

+ +

Appearance settings are split across different tabs:

+ + + +

Branding

+ +

In the Branding tab, you can configure your Metabase to match your brand visuals and voice.

+ + + +

Color palette

+ +

You can customize colors in both the application UI and in the Metabase charts.

+ +

User interface colors

+ +

User interface colors

+ +

You can customize the colors that Metabase uses throughout the app:

+ +
    +
  • First color: The main color used throughout the app for buttons, links, and the default chart color.
  • +
  • Second color: The color of aggregations and breakouts in the graphical query builder.
  • +
  • Third color: Color of filters in the query builder, buttons and links in filter widgets.
  • +
+ +

Chart colors

+ +

Chart colors

+ +

You can choose up to 24 hex values. If you choose fewer than 24 colors, Metabase will auto-generate colors to fill in the rest of the values. And don’t bother ordering the colors here, as their order doesn’t apply to the order of colors for series on charts. When building a chart, Metabase will select colors to make each series easy to distinguish.

+ +

Custom colors are unavailable for:

+ + + + + +

You can replace Metabase’s familiar, tasteful, inspired-yet-not-threateningly-avant-garde dotted M logo with your very own logo. For things to work best, the logo you upload should be an SVG file that looks good when it’s around 60px tall. (In other words, ask the nearest designer for help.)

+ +

Font

+ +

This is the primary font used in charts and throughout the Metabase application (your “instance font”). See Fonts.

+ +

Loading message

+ +

This message is the text Metabase presents when it’s loading a query. Options include:

+ +
    +
  • “Doing science…” (the default)
  • +
  • “Running query…”
  • +
  • “Loading results…”
  • +
+ +

Favicon

+ +

The URL or image that you want to use as the favicon (the logo visible in browser tabs, address bars, bookmark lists, and other places).

+ +

If you use a relative path, that path isn’t relative to the Metabase JAR, but to the webserver. So unless you’re using a reverse-proxy, the path will be relative to the frontend resources available to the JAR.

+ +

Conceal Metabase

+ +

Hide or customize pieces of the Metabase product to tailor the experience to your brand and needs.

+ + + +

Application name

+ +

You can change every place in the app that says “Metabase” to something like “Acme Analytics,” or whatever you want to call your Metabase app.

+ +

Documentation and references

+ +

Control the visibility of links to official Metabase documentation and other references to Metabase in your instance.

+ +

This setting affects all links in the product experience that point to Metabase.com URLs (with the exception of links and references in the Admin settings).

+ + + +

The Settings menu (the “gear” menu in the upper right of your Metabase) includes a Help option that links to a Metabase help page by default. You can change this menu Help item by selecting one of the following options:

+ +
    +
  • Link to Metabase help (default)
  • +
  • Hide it (the Settings menu won’t display the Help option at all).
  • +
  • Go to a custom destination. Enter a URL that the Settings menu’s Help option should link to. Valid URLs include http, https, and mailto URLs.
  • +
+ +

Metabase illustrations

+ +

Lighthouse illustration

+ +

Customize each of the illustrations in Metabase.

+ +

Metabot greeting

+ +

Turn this guy on or off:

+ +

Metabot greeting

+ +

Login and unsubscribe pages

+ +

Login page

+ +

What people see when Metabase prompts them to log in.

+ +
    +
  • Lighthouse
  • +
  • No illustration
  • +
  • Custom
  • +
+ +

Landing page

+ +

The landing page is what people will see whenever they login. You can set the URL to a collection, question, dashboard or whatever, just make sure that everyone has access to that URL.

+ +
    +
  • Lighthouse
  • +
  • No illustration
  • +
  • Custom
  • +
+ +

When calculations return no results

+ +

Sailboat

+ +

Metabase will display this illustration when questions or dashboard cards contain no results.

+ +
    +
  • Sailboat
  • +
  • No illustration
  • +
  • Custom
  • +
+ +

When no objects can be found

+ +

Metabase will display this illustration when searches don’t return any results.

+ +
    +
  • Sailboat
  • +
  • No illustration
  • +
  • Custom
  • +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/caching.html b/_site/docs/doc-update-detection/configuring-metabase/caching.html new file mode 100644 index 000000000..ce7e8227f --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/caching.html @@ -0,0 +1,3306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Caching query results | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Caching query results

+ +

If your question results don’t change frequently, you may want to store the results so that the next time anyone visits the question, Metabase can retrieve the cached results rather than query the database again.

+ +

For example, if your data only updates once a day, there’s no point in querying the database more than once a day, as the data won’t have changed. Returning cached results can be significantly faster, as your database won’t have to recompute the results to load your question.

+ +

You can set caching invalidation policies for questions, dashboards, and databases.

+ +

How caching works in Metabase

+ +

Let’s say you set a caching policy for a particular question. You set a duration policy that says to invalidate the results (and clear the cache) after one hour.

+ +

When you view the question for the first time, Metabase will check for stored results. When it doesn’t find any, it will query your database, return the results, and store (cache) the results. Those results will remain valid for the next hour (according to the hour-long duration policy you set).

+ +

If you run the question half an hour later, Metabase will return those stored results.

+ +

If you run the question over an hour after that initial run, Metabase will notice that the stored results are older than your caching policy allows. Metabase will delete the stored results, run the query against your database, return the results, and store them for the future queries. This cache will remain valid for the next hour, according to the duration policy you set. To always refresh the cache when results expire, see Refresh cache automatically.

+ +

See how different caching policies interact.

+ +

Cache invalidation policies

+ +

These policies determine how long cached results will remain valid.

+ + + +

Duration caching policy

+ +
+
+ + + + + + + +

Duration caching policy is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Invalidate and clear the cache after a certain number of hours. When someone runs a query, Metabase will first check whether it has cached the results, and whether those results are still valid. If not, Metabase runs the query against the database and caches the results. These cached results will remain valid for the duration you’ve set.

+ +

Schedule caching policy

+ +
+
+ + + + + + + +

Schedule caching policy is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Pick when to regularly invalidate the cache. Metabase will only store results when people run a query, and it will clear the cached results according to the schedule you set here.

+ +

You can schedule the cache to invalidate:

+ +
    +
  • Hourly
  • +
  • Daily
  • +
  • Weekly
  • +
  • Monthly
  • +
+ +

We do not yet support lunar cycles.

+ +

Adaptive caching policy

+ +

Use a query’s average execution time to determine how long to cache the query’s results.

+ +
    +
  • Minimum query duration: Metabase will cache this question if it has an average query execution time greater than this many seconds.
  • +
  • Multiplier: To determine how long each cached result should stick around, we take that query’s average execution time and multiply that by what you input here. The result is how many seconds the cache should remain valid for. For example, if a question takes on average 10 seconds to return results, and you set a multiplier of 100, Metabase will store the cache for 10 x 100 seconds: 1,000 seconds (~16 minutes).
  • +
+ +

Metabase will recalculate a query’s average execution time whenever it runs the query against the database to refresh the cached results. So if the first time Metabase runs the query against the database, it takes 5 minutes to return results, the average execution time will be 5 minutes. If the next query against the database takes 7 minutes to return, Metabase will update the average to 6 minutes (the average of 5 and 7 is 6).

+ +

On Pro and Enterprise plans, you can view querying and caching stats in the Usage analytics collection.

+ +

Don’t cache results

+ +

If you select “Don’t cache results” for a question, dashboard, or database, Metabase won’t cache its results; it’ll always run the query against the database to refresh results.

+ +

Refresh cache automatically

+ +
+
+ + + + + + + +

Refresh cache automatically is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +
+

Refreshing the cache automatically doesn’t apply when data sandboxing or connection impersonation permissions are in effect. In those permissions setups, Metabase ignores the automatically generated cache and runs a fresh query (which it will then cache). So caching still works for sandboxing and impersonation, it’s just that this preemptive, automatic caching doesn’t apply in these cases, as those permissions setups filter data specific to each viewer.

+
+ +

If you turn on refresh cache automatically for a question or dashboard, Metabase will rerun the query/queries as soon as the cache is invalidated by whichever caching policy you’ve set. Normally, Metabase only refreshes the cache when someone views the item after its cache has expired. So, normally, when the cache has expired, the next person to view the question will be stuck waiting for the query to run and refresh the cache. But by automatically refreshing results to update the cache, the loading times will always be as fast as possible, and people will always get valid, cached results.

+ +

How Metabase handles parameter values when automatically refreshing the cache

+ +

When automatically refreshing results, Metabase will apply the default parameter values (if any). Metabase will also cache results of up to ten of the most frequently applied parameter values that were applied during the last caching period (as defined by your caching policy). If your question or dashboard has multiple parameters, Metabase will cache up to ten of the most frequently applied combinations of parameter values.

+ +

For example, let’s say you have a dashboard with a category filter (default value: Doohickey) that’s set to cache results every 24 hours. During the last 24 hours, people who viewed that dashboard applied the following values to the category filter: Widget, Gizmo. When Metabase next refreshes the cache, it will cache three sets of results, each set with one of those parameters applied: Doohickey (the default value), Widget, and Gizmo. If, however, no one runs the query in that last 24 hours, Metabase will only refresh the cache for the results with the default parameter’s value applied.

+ +

Automatic caching logs

+ +

To view the queries Metabase ran to automatically refresh the cache, check out the query log and filter the Query source by cache-refresh.

+ +

Set caching policies for dashboards, questions, and databases

+ +

You can set caching policies for different entities.

+ + + +

* Denotes Pro and Enterprise features.

+ +

Default caching policy

+ +

To set a default caching policy for your Metabase: Hit Cmd/Ctrl + k to bring up the command palette and search for Performance. Or, click through Gear settings icon > Admin settings > Performance > Database caching.

+ +

Click on the button next to Default policy, and select a cache invalidation policy.

+ +

Database caching policy

+ +
+
+ + + + + + + +

Database caching is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Database caching settings in the Admin settings under the Performance tab

+ +

Same as the default caching policy, though you can set a caching policy for specific databases.

+ +

If you have databases connected to Metabase that are set to Use default policy, Metabase will update the display to reflect whatever the default policy is set to. For example, if you set the default policy to be “Adaptive”, Metabase will display “Adaptive” as the current policy for those databases set to “Use default”.

+ +

Dashboard caching policy

+ +
+
+ + + + + + + +

Dashboard caching is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

To set a caching policy for a dashboard, you must have curate access to the dashboard’s collection.

+ +
    +
  1. Go to your dashboard.
  2. +
  3. Click on the info icon.
  4. +
  5. Click Caching policy.
  6. +
  7. Select the caching invalidation policy.
  8. +
  9. Optional: turn on refresh cache automatically.
  10. +
  11. Save your changes.
  12. +
+ +

Question caching policy

+ +
+
+ + + + + + + +

Question caching is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

To set a caching policy for a question, you must have curate access to the question’s collection.

+ +
    +
  1. Go to your question.
  2. +
  3. Click on the three-dot menu and select Edit settings.
  4. +
  5. Under Caching, select the caching invalidation policy.
  6. +
  7. Optional: if you select a Duration or Schedule policy, you’ll have the option to refresh cache automatically.
  8. +
  9. Save your changes.
  10. +
+ +

How dashboard, question, database, and default caching policies interact

+ +

If multiple caching policies affect the same question, Metabase will use the first available policy, in this order:

+ +
    +
  1. Question
  2. +
  3. Dashboard
  4. +
  5. Database
  6. +
  7. Default (site-wide)
  8. +
+ +

A question policy overrides a dashboard policy, which overrides a database policy, which overrides a default policy.

+ +

Clearing the cache

+ +

To clear the cache and refresh the results:

+ +
    +
  • Questions and dashboards: Visit the item and click through the Info > Caching policy > Clear cache (the “Clear cache” button is at the bottom of the sidebar).
  • +
  • Database: Click the Gear icon and click through Admin settings > Performance > Database caching. Select your database and click the Clear cache button (at the bottom of the page).
  • +
+ +

Caching location

+ +

If you’re self-hosting Metabase, cached question results will be saved to your application database.

+ +

If you’re using Metabase Cloud, cached question results will be saved to Metabase’s servers in the United States (as our Cloud service manages your application database for you.)

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/config-file.html b/_site/docs/doc-update-detection/configuring-metabase/config-file.html new file mode 100644 index 000000000..7b9da26ff --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/config-file.html @@ -0,0 +1,3328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Configuration file | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Configuration file

+ +
+
+ + + + + + + +

Loading from a configuration file is only available on Pro and Enterprise plans + + (only on self-hosted plans). +

+
+
+ +

On self-hosted Pro and Enterprise plans, Metabase supports initialization on launch from a config file named config.yml. The config file should be located at:

+ +
    +
  • The current directory (the directory where the running Metabase JAR is located).
  • +
  • The path specified by the MB_CONFIG_FILE_PATH environment variable.
  • +
+ +

The settings in the config file work the same as if you’d set the settings in the Admin Settings in your Metabase. Settings defined in this configuration file will update any existing settings. If, for example, a database already exists (that is, you’d already added it via the initial set up or Admin settings > Databases, Metabase will update the database entry based on the data in the config file). Which means: if you define a setting in the config file, and then later change that setting in your Metabase application, keep in mind that the config file will overwrite that change whenever Metabase restarts. Let’s reiterate that in a blockquote:

+ +
+

Whenever Metabase restarts and loads your config file, the settings in the config file will overwrite any changes to those settings made in the Metabase UI.

+
+ +

The config file settings are NOT treated as a hardcoded source of truth (like environment variables are). Settings set by environment variables cannot be changed, even in the Admin settings in the application itself.

+ +

Example config template

+ +

See Config template.

+ +

Config setup

+ +

The config file is split up into sections: version and config. Under config, you can specify:

+ + + +

Like so:

+ +
version: 1
+config:
+  settings:
+    - ...
+  users:
+    - ...
+  databases:
+    - ...
+
+ +

The config file must also include a version key, which is just a convenience field for you to help you keep track of your config file versions.

+ +

Users

+ +

The first user created in a Metabase instance is an Admin. The first user listed in the config file may be designated an admin, but not necessarily. If someone has already spun up and logged into that Metabase for the first time, Metabase will make that first user an admin. Additionally, you can specify a user account as an admin by using the is_superuser: true key.

+ +

In the following example, assuming that the Metabase hasn’t already been set up (which creates the first user) both users first@example.com and admin@example.com will be admins: first@example.com because it’s the first user account on the list, and admin@example.com because that user has the is_superuser flag set to true.

+ +
version: 1
+config:
+  users:
+    - first_name: First
+      last_name: Person
+      password: metabot1
+      email: first@example.com
+    - first_name: Normal
+      last_name: Person
+      password: metabot1
+      email: normal@example.com
+    - first_name: Admin
+      last_name: Person
+      password: metabot1
+      is_superuser: true
+      email: admin@example.com
+
+ +

If the Metabase has already been set up, then first@example.com will be loaded as a normal user.

+ +

Databases

+ +

On a new Metabase, the example below sets up an admin user account and one database connection.

+ +

+version: 1
+config:
+  users:
+    - first_name: Cam
+      last_name: Era
+      password: 2cans3cans4cans
+      email: cam@example.com
+  databases:
+    - name: test-data (Postgres)
+      engine: postgres
+      details:
+        host: localhost
+        port: 5432
+        user: dbuser
+        password: "{{ env POSTGRES_TEST_DATA_PASSWORD }}"
+        dbname: test-data
+
+
+ +

To determine which keys you can specify for a database, check out the fields available in Metabase itself for the database that you want to add.

+ +

Setting up uploads on a database

+ +

You can also configure uploads in the config file with the following settings:

+ +
    +
  • uploads_enabled: Boolean
  • +
  • uploads_schema_name: String
  • +
  • uploads_table_prefix: String
  • +
+ +

Here’s an example:

+ +

+version: 1
+config:
+  users:
+    - first_name: Cam
+      last_name: Era
+      password: 2cans3cans4cans
+      email: cam@example.com
+  databases:
+    - name: test-data (Postgres)
+      engine: postgres
+      details:
+        host: localhost
+        port: 5432
+        user: dbuser
+        password: "{{ env POSTGRES_TEST_DATA_PASSWORD }}"
+        dbname: test-data
+      uploads_enabled: true
+      uploads_schema_name: uploads
+      uploads_table_prefix: uploads_
+
+
+ +

See Uploads.

+ +

API keys

+ +

You can use the config file to create API keys, which is useful for automated deployments and keeping API keys stable across environments.

+ +

You can add API keys like so:

+ +

+version: 1
+config:
+  users:
+    - first_name: Cam
+      last_name: Era
+      password: 2cans3cans4cans
+      email: cam@example.com
+  api-keys:
+    - name: "Admin API key"
+      group: admin
+      creator: cam@example.com
+      key: mb_firsttestapikey
+    - name: "All Users API key"
+      group: all-users
+      creator: cam@example.com
+      key: mb_secondtestapikey
+
+
+ +

You can also use an environment variable to supply an API key, like so:

+ +

+api-keys:
+  - name: "ENV API Key"
+    key: "{{env API_KEY_FROM_ENV}}"
+    creator: "admin@example.com"
+    group: "admin"
+
+
+ +

See below for more on env vars in the config file.

+ +

API keys that you create (the value of the key) must have the format mb_ followed by a Base64 string (if you’re wearing formal attire, you’d say a tetrasexagesimal string). So, mb_ followed by letters and numbers, minimum: 12 characters, maximum: 254 characters. Concretely, the API key you create must satisfy the following regular expression: mb_[A-Za-z0-9+/=]+.

+ +

You can generate a handsome API key using the openssl rand command:

+ +
echo "mb_$(openssl rand -base64 32)"
+
+ +

Which would generate something like:

+ +
mb_aDqk1Tc4ZotWb2TyjHY71glALKlB+g75dLgmSufWGLc=
+
+ +

Some other things to note about API keys in the config file:

+ +
    +
  • The creator of an API key must be an admin. This means either a) your Metabase must already have at least one admin account, or b) you need to add an admin account in the users section of the config file.
  • +
  • The keys themselves can be assigned to one of two groups: admin or all-users. The config file restricts group assignment to these groups because they’re the only ones that Metabase always initializes.
  • +
  • The permissions for the key correspond to the permissions granted to its group (not its creator).
  • +
  • If Metabase finds an existing API key with the same name as a key in the config file, it will preserve the existing key (i.e., it won’t overwrite the existing key with the key in the config file). For example, if you initially set up an API key, then later regenerate the key in the Metabase user interface, loading Metabase with the config file won’t overwrite that regenerated key (which means the key in the config file will no longer work).
  • +
  • If you do want to overwrite the existing key from the config file, you’ll need to first delete the existing key. If you want to keep both keys, you’ll need to rename the key in the config file.
  • +
+ +
+

The config file also contains an api-key key in the settings section of the config file. This setting doesn’t create API keys; it’s used for string-matching in the header for authenticating requests to the /notify endpoint.

+
+ +

Referring to environment variables in the config.yml

+ +

As shown in the Databases examples above, environment variables can be specified with {{ template-tags }} like {{ env POSTGRES_TEST_DATA_PASSWORD }} or [[options {{template-tags}}]].

+ +

Metabase doesn’t support recursive expansion, so if one of your environment variables references another environment variable, you’re going to have a bad time.

+ +

Values with special characters in the config.yml

+ +

If a value contains double braces (}} or {{), you must use triple backticks to tell the config parser to use the literal value. For example, if your password was MetaPa$$123{{>, you’d need to wrap the value in triple braces, like so:

+ +

+password: {{{ MetaPa$$123{{> }}}
+
+
+ +

Disable initial database sync

+ +

When loading a data model from a serialized export, you want to disable the scheduler so that the Metabase doesn’t try to sync.

+ +

To disable the initial database sync, you can add config-from-file-sync-database to the settings list and set the value to false. The setting config-from-file-sync-database must come before the databases list, like so:

+ +
version: 1
+config:
+  settings:
+    config-from-file-sync-databases: false
+  databases:
+    - name: my-database
+      engine: postgres
+      details: ...
+
+ +

Settings

+ +

In this config file, you can specify any Admin setting.

+ +

In general, the settings you can set in the settings section of this config file map to the environment variables, so check them out to see which settings you can use in your config file. The actual key that you include in the config file differs slightly from the format used for environment variables. For environment variables, the form is in screaming snake case, prefixed by an MB:

+ +
MB_NAME_OF_VARIABLE
+
+ +

Whereas in the config file, you’d translate that to:

+ +
name-of-variable
+
+ +

So for example, if you wanted to specify the MB_EMAIL_FROM_NAME in the config.yml file:

+ +
version: 1
+config:
+  settings:
+    config-from-file-sync-databases: false
+    email-from-name: Stampy von Mails-a-lot
+  databases:
+    - name: my-database
+      engine: h2
+      details: ...
+
+ +

But you can set any of the Admin settings with the config file (for a list of settings, check out the config file template). You can also browse the list of environment variable to see what you can configure (though note that not all environment variables can be set via the config file.)

+ +

Loading a new Metabase from a config file

+ +

Since loading from a config file is a Pro/Enterprise feature: for new installations, you’ll need to supply Metabase with a token using the MB_PREMIUM_EMBEDDING_TOKEN environment variable.

+ +
MB_PREMIUM_EMBEDDING_TOKEN="[your token]" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/config-template.html b/_site/docs/doc-update-detection/configuring-metabase/config-template.html new file mode 100644 index 000000000..13b97a15e --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/config-template.html @@ -0,0 +1,3293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Metabase config file template | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Metabase config file template

+ +

You can generate the following config file template by changing into the top-level Metabase directory and running:

+ +
clojure -M:doc:ee config-template
+
+ +

The template lists example database, user, and settings sections for the config file.

+ +
# A config file template for Metabase.
+# You'll need to update (or remove) the `users` and `databases` sections.
+# The settings in `settings` include default values. We recommend removing
+# or commenting out settings that you don't set.
+# For more on the configuration file, see:
+# https://www.metabase.com/docs/latest/configuring-metabase/config-file
+# For more on what each setting does, check out:
+# https://www.metabase.com/docs/latest/configuring-metabase/environment-variables
+version: 1
+config:
+  users:
+  - first_name: First
+    last_name: Person
+    password: metabot1
+    email: first@example.com
+  - first_name: Normal
+    last_name: Person
+    password: metabot1
+    email: normal@example.com
+  - first_name: Admin
+    last_name: Person
+    password: metabot1
+    is_superuser: true
+    email: admin@example.com
+  databases:
+  - name: Sample PostgreSQL
+    engine: postgres
+    details:
+      host: postgres-data
+      port: 5432
+      user: metabase
+      password: metasample123
+      dbname: sample
+  - name: Sample MySQL
+    engine: mysql
+    details:
+      host: mysql-data
+      port: 3306
+      user: metabase
+      password: metasample123
+      dbname: sample
+  api-keys:
+  - name: Admin API key
+    group: admin
+    creator: first@example.com
+    key: mb_firsttestapikey123
+  - name: All Users API key
+    group: all-users
+    creator: first@example.com
+    key: mb_secondtestapikey456
+  settings:
+    admin-email: null
+    aggregated-query-row-limit: null
+    allowed-iframe-hosts: |-
+      youtube.com,
+      youtu.be,
+      loom.com,
+      vimeo.com,
+      docs.google.com,
+      calendar.google.com,
+      airtable.com,
+      typeform.com,
+      canva.com,
+      codepen.io,
+      figma.com,
+      grafana.com,
+      miro.com,
+      excalidraw.com,
+      notion.com,
+      atlassian.com,
+      trello.com,
+      asana.com,
+      gist.github.com,
+      linkedin.com,
+      twitter.com,
+      x.com
+    anon-tracking-enabled: true
+    api-key: null
+    application-colors: {}
+    application-favicon-url: app/assets/img/favicon.ico
+    application-font: Lato
+    application-font-files: null
+    application-logo-url: app/assets/img/logo.svg
+    application-name: Metabase
+    attachment-row-limit: null
+    attachment-table-row-limit: 20
+    backfill-entity-ids-repeat-ms: 2000
+    bcc-enabled: true
+    breakout-bin-width: 10.0
+    breakout-bins-num: 8
+    check-for-updates: true
+    config-from-file-sync-databases: true
+    custom-formatting: {}
+    custom-geojson: null
+    custom-geojson-enabled: true
+    custom-homepage: false
+    custom-homepage-dashboard: null
+    db-connection-timeout-ms: 10000
+    db-query-timeout-minutes: 20
+    default-maps-enabled: true
+    download-row-limit: null
+    ee-ai-features-enabled: false
+    ee-openai-api-key: null
+    ee-openai-model: gpt-4-turbo-preview
+    email-from-address: notifications@metabase.com
+    email-from-name: null
+    email-max-recipients-per-second: null
+    email-reply-to: null
+    email-smtp-host: null
+    email-smtp-password: null
+    email-smtp-port: null
+    email-smtp-security: none
+    email-smtp-username: null
+    embedding-app-origins-interactive: null
+    embedding-app-origins-sdk: localhost:*
+    embedding-homepage: hidden
+    embedding-secret-key: null
+    enable-embedding-interactive: false
+    enable-embedding-sdk: false
+    enable-embedding-static: false
+    enable-field-usage-analysis: false
+    enable-password-login: true
+    enable-pivoted-exports: true
+    enable-public-sharing: true
+    enable-query-caching: true
+    enable-xrays: true
+    follow-up-email-sent: false
+    google-auth-auto-create-accounts-domain: null
+    google-auth-client-id: null
+    google-auth-enabled: null
+    gsheets: null
+    health-check-logging-enabled: true
+    help-link: metabase
+    help-link-custom-destination: https://www.metabase.com/help/premium
+    humanization-strategy: simple
+    jdbc-data-warehouse-max-connection-pool-size: 15
+    jwt-attribute-email: email
+    jwt-attribute-firstname: first_name
+    jwt-attribute-groups: groups
+    jwt-attribute-lastname: last_name
+    jwt-enabled: false
+    jwt-group-mappings: {}
+    jwt-group-sync: false
+    jwt-identity-provider-uri: null
+    jwt-shared-secret: null
+    jwt-user-provisioning-enabled: true
+    landing-page: ''
+    landing-page-illustration: default
+    landing-page-illustration-custom: null
+    ldap-attribute-email: mail
+    ldap-attribute-firstname: givenName
+    ldap-attribute-lastname: sn
+    ldap-bind-dn: null
+    ldap-enabled: false
+    ldap-group-base: null
+    ldap-group-mappings: {}
+    ldap-group-membership-filter: (member={dn})
+    ldap-group-sync: false
+    ldap-host: null
+    ldap-password: null
+    ldap-port: 389
+    ldap-security: none
+    ldap-sync-user-attributes: true
+    ldap-sync-user-attributes-blacklist: userPassword,dn,distinguishedName
+    ldap-user-base: null
+    ldap-user-filter: (&(objectClass=inetOrgPerson)(|(uid={login})(mail={login})))
+    ldap-user-provisioning-enabled: true
+    loading-message: doing-science
+    login-page-illustration: default
+    login-page-illustration-custom: null
+    map-tile-server-url: https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png
+    native-query-autocomplete-match-style: substring
+    nested-field-columns-value-length-limit: 50000
+    no-data-illustration: default
+    no-data-illustration-custom: null
+    no-object-illustration: default
+    no-object-illustration-custom: null
+    not-behind-proxy: false
+    notification-link-base-url: null
+    notification-thread-pool-size: 3
+    persisted-model-refresh-cron-schedule: 0 0 0/6 * * ? *
+    persisted-models-enabled: false
+    premium-embedding-token: null
+    query-analysis-enabled: false
+    query-caching-max-kb: 2000
+    query-caching-max-ttl: 3024000.0
+    redirect-all-requests-to-https: false
+    report-timezone: null
+    reset-token-ttl-hours: 48
+    retry-initial-interval: 500
+    retry-max-attempts: 7
+    retry-max-interval-millis: 30000
+    retry-multiplier: 2.0
+    retry-randomization-factor: 0.1
+    saml-application-name: Metabase
+    saml-attribute-email: null
+    saml-attribute-firstname: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
+    saml-attribute-group: member_of
+    saml-attribute-lastname: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
+    saml-enabled: false
+    saml-group-mappings: {}
+    saml-group-sync: false
+    saml-identity-provider-certificate: null
+    saml-identity-provider-issuer: null
+    saml-identity-provider-slo-uri: null
+    saml-identity-provider-uri: null
+    saml-keystore-alias: metabase
+    saml-keystore-password: changeit
+    saml-keystore-path: null
+    saml-slo-enabled: false
+    saml-user-provisioning-enabled: true
+    scim-enabled: null
+    search-engine: in-place
+    search-typeahead-enabled: true
+    send-new-sso-user-admin-email: null
+    session-cookie-samesite: lax
+    session-cookies: null
+    session-timeout: null
+    setup-embedding-autoenabled: false
+    setup-license-active-at-setup: false
+    show-database-syncing-modal: null
+    show-homepage-data: true
+    show-homepage-xrays: true
+    show-metabase-links: true
+    show-metabot: true
+    show-static-embed-terms: true
+    site-locale: en
+    site-name: Metabase
+    site-url: null
+    slack-app-token: null
+    slack-bug-report-channel: metabase-bugs
+    source-address-header: X-Forwarded-For
+    sql-jdbc-fetch-size: 500
+    sql-parsing-enabled: true
+    ssh-heartbeat-interval-sec: 180
+    start-of-week: sunday
+    subscription-allowed-domains: null
+    surveys-enabled: true
+    synchronous-batch-updates: false
+    unaggregated-query-row-limit: null
+    update-channel: latest
+    uploads-settings: null
+    user-visibility: all
+
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/custom-maps.html b/_site/docs/doc-update-detection/configuring-metabase/custom-maps.html new file mode 100644 index 000000000..2e5b14737 --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/custom-maps.html @@ -0,0 +1,3100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Custom maps | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Custom maps

+ +

By default, Metabase uses OpenStreetMaps for map visualizations, but there are a few customization options.

+ +

Map settings

+ +

To find the map settings:

+ +
    +
  1. At the top right of the screen, click gear icon > Admin settings > Settings.
  2. +
  3. Select Maps from the navigation on the left.
  4. +
+ +

Map Settings

+ +

Map tile server

+ +

By default, Metabase uses the OpenStreetMaps tile server for pin and grid maps. If your organization requires a different +look or level of detail in your map visualizations, you can change the map tile server by adding the map tile server path to the first field on the page.

+ +

The path must either be a URL that starts with http:// or https:// or a relative path to a local file in the JVM’s classpath.

+ +

Currently, Metabase uses a single tile server per instance. You can’t specify different tiles for different maps.

+ +

Custom region maps

+ +

Metabase comes with two built-in region maps: world map with countries and United States map with states.

+ +

If you need a map of other regions - like EU countries or NYC neighborhoods - you can specify a GeoJSON file containing region information. You can often find GeoJSON maps by searching online for “[Your region] + geojson”, like “NYC neighborhoods GeoJSON.” Many community members and government organizations have already developed map files for common regions. You can also create your own GeoJSON with a tool like MapShaper or GeoJSON.io.

+ +

Your GeoJSON file should:

+ +
    +
  • Be less than 5 MB in size.
  • +
  • Contain polygon features defining regions (not just points or coordinates)
  • +
  • Use geographic coordinates (latitude and longitude) to define region polygons. Metabase doesn’t support projected coordinates, so you’ll need to convert projected coordinates to geographic coordinates.
  • +
  • Accessible by a public URL. Currently, you can’t upload a GeoJSON to Metabase.
  • +
+ +

To add a custom map:

+ +
    +
  1. Go to Admin Settings > Maps > Custom Maps.
  2. +
  3. Click Add a Map.
  4. +
  5. Enter a name for your map.
  6. +
  7. Provide the URL to your GeoJSON file.
  8. +
  9. Specify the JSON properties that should serve as region identifier and region name.
  10. +
+ +

Uploading a custom GeoJSON

+ +
    +
  • Name of the map will be displayed in the region selector for custom region maps
  • +
  • Region’s identifier is a GeoJSON field that identifies your region. The values in this field should match how the regions are referenced in your data. The field does not need to match the display name .
  • +
  • Region’s display name is a GeoJSON field that specifies how your region name will be displayed on a map. This field can be different from region’s identifier.
  • +
+ +

To pre-load one or more region maps when Metabase starts, you can use the environment variable MB_CUSTOM_GEOJSON or a config file option custom-geojson .

+ +

To disable the creation of custom maps, use the MB_CUSTOM_GEOJSON_ENABLED or a config file option custom-geojson-enabled.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/customizing-jetty-webserver.html b/_site/docs/doc-update-detection/configuring-metabase/customizing-jetty-webserver.html new file mode 100644 index 000000000..64e3c1816 --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/customizing-jetty-webserver.html @@ -0,0 +1,3076 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Customizing the Metabase Jetty webserver | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Customizing the Metabase Jetty webserver

+ +

In most cases there will be no reason to modify any of the settings around how Metabase runs its embedded Jetty webserver to host the application, but if you wish to run HTTPS directly with your Metabase server or if you need to run on another port, that’s all configurable.

+ +

Running Metabase on another port

+ +

By default Metabase will launch on port 3000, but if you prefer to run the application on another port you can do so by setting the following environment variable:

+ +
export MB_JETTY_PORT=12345
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

In this example once the application starts up you will access it on port 12345 instead of the default port of 3000.

+ +

Listening on a specific network interface

+ +

By default, Metabase will be listening on localhost. In some production environments you may want to listen on a different interface, which can be done by using the MB_JETTY_HOST environment variable:

+ +
export MB_JETTY_HOST=0.0.0.0
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

Using HTTPS with Metabase

+ +

If you have an SSL certificate and would prefer to have Metabase run over HTTPS directly using its webserver, you can do so by using the following environment variables:

+ +
export MB_JETTY_SSL="true"
+export MB_JETTY_SSL_PORT="8443"
+export MB_JETTY_SSL_KEYSTORE="path/to/keystore.jks" # replace this value with your own
+export MB_JETTY_SSL_KEYSTORE_PASSWORD="storepass" # replace this value with your own
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

Be sure to replace path/to/keystore.jks and storepass with the correct path to and password for your Java KeyStore. With the above settings applied you will be running Metabase on port 8443 over HTTPS using the supplied certificate.

+ +

No idea how to generate a Java KeyStore yourself? This is sort of an advanced topic, but if you’re feeling froggy you can read more about how to configure SSL in Jetty in their own documentation. Otherwise, you’ll probably find it easiest to handle SSL termination outside of Metabase.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/email.html b/_site/docs/doc-update-detection/configuring-metabase/email.html new file mode 100644 index 000000000..4db0af484 --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/email.html @@ -0,0 +1,3221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Set up email | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Set up email

+ +

Once you connect your database to Metabase, you’ll want to configure an email account to send system notifications to your organization’s users. Metabase uses email to reset passwords, onboard new users, and notify you when something happens.

+ +

To edit email settings:

+ +
    +
  1. Click on the gear icon in the upper right.
  2. +
  3. Select Admin Settings.
  4. +
  5. From the default Settings tab, click on Notification channels in the left sidebar.
  6. +
  7. Select Email.
  8. +
+ +

Metabase Cloud

+ +

Metabase Cloud manages an email server for you, so you don’t need to set up email (and you won’t see SMTP settings in your Admin console).

+ +

If you like, you can still set up:

+ +
    +
  • A name for your Cloud email account (from name)
  • +
  • An email address to receive email replies (reply-to address)
  • +
+ +

Configuring your email account

+ +

For Metabase to send messages to your organization’s users, you’ll need to set up an email account to send emails via SMTP (simple mail transfer protocol), which is an email standard that secures emails with SSL security protection.

+ +

To start, go to the Admin Panel from the dropdown menu in the top right of Metabase, then from the Settings page, click on Email in the left menu.

+ +

You should see this form:

+ +

Email Credentials

+ +

Here you’ll set:

+ +
    +
  • SMTP HOST: The address of the SMTP server that handles your emails.
  • +
  • SMTP PORT: The port your SMTP server uses for outgoing emails.
  • +
  • SMTP SECURITY: +
      +
    • None
    • +
    • SSL
    • +
    • TLS
    • +
    • STARTTLS
    • +
    +
  • +
  • SMTP Username.
  • +
  • SMTP Password.
  • +
+ +

You’ll also need to specify your:

+ +
    +
  • From address: The email address you want to use for the sender of emails.
  • +
  • Reply-to address: The email address you want the replies to go to, if different from the from address.
  • +
+ +

Add recipients as CC or BCC

+ +

By default, Metabase will hide email recipients by including them in the BCC list (Blind Carbon Copy) of the email. But if you’re having issues with your email provider blocking emails with BCC recipients, and you don’t mind having people see who else has been copied on the email Metabase sends them, you can tell Metabase to CC (Carbon Copy) recipients instead.

+ + + +
    +
  • SSL is strongly recommended because it’s more secure and gives your account extra protection from threats.
  • +
  • If your email service has a whitelist of email addresses that are allowed to send email, be sure to whitelist the email address that you put in the From Address field to ensure you and your teammates receive all emails from Metabase.
  • +
+ +

Notes for common email services

+ + + +

Google Apps

+ +
    +
  1. In the SMTP host field, enter smtp.gmail.com
  2. +
  3. Fill in 465 for the SMTP port field
  4. +
  5. For the SMTP Security field, enter SSL
  6. +
  7. In the SMTP username field, enter your Google Apps email address (e.g. hello@yourdomain.com)
  8. +
  9. Enter your Google Apps password in the SMTP password field
  10. +
  11. Enter the email address you would like to be used as the sender of system notifications in the *From Address field.
  12. +
+ +

Amazon SES

+ +
    +
  1. Log on to https://console.aws.amazon.com/ses.
  2. +
  3. Click SMTP Settings from the navigation pane.
  4. +
  5. Select Create My SMTP Credentials in the content pane.
  6. +
  7. Create a user in the Create User for SMTP dialog box and then click Create.
  8. +
  9. Next, select Show User SMTP Credentials to view the user’s SMTP credentials.
  10. +
  11. Go back to the Metabase Admin Panel form and enter the info there.
  12. +
+ +

Check if email quotas apply to your Amazon SES server. You may want to manage your email recipients using groups instead.

+ +

Mandrill

+ +
    +
  1. Log in to your Mandrill account and locate your credentials from the SMTP & API Info page there.
  2. +
  3. Your SMTP password is any active API key for your account — not your Mandrill password.
  4. +
  5. Although Mandrill lists port 587, any port supported by Mandrill will work for SMTP email.
  6. +
  7. Now you can go back to the Metabase Admin Panel form and enter the info there.
  8. +
+ +

Approved domains for notifications

+ +
+
+ + + + + + + +

Approved domains for notifications is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Allowed email address domain(s) for new dashboard subscriptions and alerts.

+ +

Adding approved domains allows you to restrict which email addresses people can send alerts and subscriptions to. This restriction only applies to sending email to people who lack an account with that Metabase. People with accounts in a Metabase who aren’t sandboxed will be able to email any other person with an account in that same Metabase.

+ +

To allow all domains, leave the field empty (allowing all domains is the default).

+ +

To specify multiple domains, separate each domain with a comma, with no space in between (e.g., “domain1,domain2”).

+ +

You can also set this property using the environment variable MB_SUBSCRIPTION_ALLOWED_DOMAINS.

+ +
+

This setting doesn’t affect existing subscriptions and alerts.

+
+ +

Suggest recipients on dashboard subscriptions and alerts

+ +
+
+ + + + + + + +

Configuring suggested recipients is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Control which recipients people can see when they create a new dashboard subscription or alert. For example, you may want to restrict people to viewing potential recipients that belong to the same groups they are a member of.

+ +

Options include:

+ +
    +
  • Suggest all users
  • +
  • Only suggest users in the same groups
  • +
  • Don’t show suggestions
  • +
+ +

People who are sandboxed won’t see suggestions.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/environment-variables.html b/_site/docs/doc-update-detection/configuring-metabase/environment-variables.html new file mode 100644 index 000000000..990900156 --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/environment-variables.html @@ -0,0 +1,5763 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Environment variables | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Environment variables

+ +

This documentation was generated from source by running:

+ +
clojure -M:ee:doc environment-variables-documentation
+
+ +

Many settings in Metabase can be viewed and modified in the Admin Panel, or set via environment variables. The environment variables always take precedence. Note that, unlike settings configured in the Admin settings of your Metabase, the environment variables won’t get written into the application database.

+ +

How to set environment variables

+ +

Setting environment variables can be done in various ways depending on how you’re running Metabase.

+ +

JAR file:

+ +
# Mac, Linux and other Unix-based systems
+export MB_SITE_NAME="Awesome Company"
+# Windows Powershell
+$env:MB_SITE_NAME="Awesome Company"
+# Windows batch/cmd
+set MB_SITE_NAME="Awesome Company"
+
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

Or set it as Java property, which works the same across all systems:

+ +
java -DMB_SITE_NAME="Awesome Company" -jar metabase.jar
+
+ +

Docker:

+ +
docker run -d -p 3000:3000 -e MB_SITE_NAME="Awesome Company" --name metabase metabase/metabase
+
+ +

Environment variables on Metabase Cloud

+ +

If you’re running Metabase Cloud, you can contact support to adjust environment variables for your Metabase.

+ +
+ +

List of environment variables

+ +

MB_ADMIN_EMAIL

+ + + +

The email address users should be referred to if they encounter a problem.

+ +

MB_AGGREGATED_QUERY_ROW_LIMIT

+ + + +

Maximum number of rows to return for aggregated queries via the API.

+ +

Must be less than 1048575. See also MB_UNAGGREGATED_QUERY_ROW_LIMIT.

+ +

MB_ALLOWED_IFRAME_HOSTS

+ +
    +
  • Type: string
  • +
  • Default: youtube.com, +youtu.be, +loom.com, +vimeo.com, +docs.google.com, +calendar.google.com, +airtable.com, +typeform.com, +canva.com, +codepen.io, +figma.com, +grafana.com, +miro.com, +excalidraw.com, +notion.com, +atlassian.com, +trello.com, +asana.com, +gist.github.com, +linkedin.com, +twitter.com, +x.com
  • +
  • Exported as: allowed-iframe-hosts.
  • +
  • Configuration file name: allowed-iframe-hosts
  • +
+ +

Allowed iframe hosts.

+ +

MB_ANON_TRACKING_ENABLED

+ + + +

Enable the collection of anonymous usage data in order to help Metabase improve.

+ +

MB_API_KEY

+ +
    +
  • Type: string
  • +
  • Default: null
  • +
+ +

When set, this key is required for calls to /notify/ endpoints.

+ +

Middleware that enforces validation of the client via the request header X-Metabase-Apikey for /notify endpoints. + If the header is available, then it’s validated against MB_API_KEY. + When it matches, the request continues; otherwise it’s blocked with a 403 Forbidden response. + MB_API_KEY is used only for /notify endpoints and isn’t the same as Metabase API keys + used for authenticating other API requests. MP_API_KEY can be an arbitrary string.

+ +

MB_APPLICATION_COLORS

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Choose the colors used in the user interface throughout Metabase and others specifically for the charts. You need to refresh your browser to see your changes take effect.

+ +

To change the user interface colors:

+ +
{
+ "brand":"#ff003b",
+ "filter":"#FF003B",
+ "summarize":"#FF003B"
+}
+
+ +

To change the chart colors:

+ +
{
+ "accent0":"#FF0005",
+ "accent1":"#E6C367",
+ "accent2":"#B9E68A",
+ "accent3":"#8AE69F",
+ "accent4":"#8AE6E4",
+ "accent5":"#8AA2E6",
+ "accent6":"#B68AE6",
+ "accent7":"#E68AD0"
+}
+
+ +

MB_APPLICATION_FAVICON_URL

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Upload a file to use as the favicon.

+ +

MB_APPLICATION_FONT

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Replace “Lato” as the font family.

+ +

MB_APPLICATION_FONT_FILES

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Tell us where to find the file for each font weight. You don’t need to include all of them, but it’ll look better if you do.

+ +

Example value:

+ +
[
+  {
+    "src": "https://example.com/resources/font-400",
+    "fontFormat": "ttf",
+    "fontWeight": 400
+  },
+  {
+    "src": "https://example.com/resources/font-700",
+    "fontFormat": "woff",
+    "fontWeight": 700
+  }
+]
+
+ +

See fonts.

+ +

MB_APPLICATION_LOGO_URL

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Upload a file to replace the Metabase logo on the top bar.

+ +

Inline styling and inline scripts are not supported.

+ +

MB_APPLICATION_NAME

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Replace the word “Metabase” wherever it appears.

+ +

MB_ATTACHMENT_ROW_LIMIT

+ +
    +
  • Type: positive-integer
  • +
  • Default: null
  • +
  • Exported as: attachment-row-limit.
  • +
+ +

Row limit in file attachments excluding the header.

+ +

MB_ATTACHMENT_TABLE_ROW_LIMIT

+ +
    +
  • Type: positive-integer
  • +
  • Default: 20
  • +
+ +

Maximum number of rows to render in an alert or subscription image.

+ +

Range: 1-100. To limit the total number of rows included in the file attachment + for an email dashboard subscription, use MB_UNAGGREGATED_QUERY_ROW_LIMIT.

+ +

MB_BACKFILL_ENTITY_IDS_REPEAT_MS

+ +
    +
  • Type: integer
  • +
  • Default: 2000
  • +
  • Exported as: backfill-entity-ids-repeat-ms.
  • +
+ +

Frequency for running backfill entity ids job in ms. Minimum value is 1000, and any value at or below 0 will disable the job entirely.

+ +

MB_BCC_ENABLED

+ + + +

Whether or not bcc emails are enabled, default behavior is that it is.

+ +

MB_BREAKOUT_BIN_WIDTH

+ + + +

When using the default binning strategy for a field of type Coordinate (such as Latitude and Longitude), this number will be used as the default bin width (in degrees).

+ +

MB_BREAKOUT_BINS_NUM

+ + + +

When using the default binning strategy and a number of bins is not provided, this number will be used as the default.

+ +

MB_CHECK_FOR_UPDATES

+ + + +

Identify when new versions of Metabase are available.

+ +

MB_CONFIG_FROM_FILE_SYNC_DATABASES

+ +
    +
  • Type: boolean
  • +
  • Default: true
  • +
+ +

Whether to (asynchronously) sync newly created Databases during config-from-file initialization. By default, true, but you can disable + this behavior if you want to sync it manually or use SerDes to populate its data model.

+ +

MB_CUSTOM_FORMATTING

+ + + +

Object keyed by type, containing formatting settings.

+ +

MB_CUSTOM_GEOJSON

+ + + +

JSON containing information about custom GeoJSON files for use in map visualizations instead of the default US State or World GeoJSON.

+ +

MB_CUSTOM_GEOJSON_ENABLED

+ + + +

Whether or not the use of custom GeoJSON is enabled.

+ +

MB_CUSTOM_HOMEPAGE

+ + + +

Pick one of your dashboards to serve as homepage. Users without dashboard access will be directed to the default homepage.

+ +

MB_CUSTOM_HOMEPAGE_DASHBOARD

+ + + +

ID of dashboard to use as a homepage.

+ +

MB_DB_CONNECTION_TIMEOUT_MS

+ +
    +
  • Type: integer
  • +
  • Default: 10000
  • +
+ +

Consider metabase.driver/can-connect? / can-connect-with-details? to have failed if they were not able to + successfully connect after this many milliseconds. By default, this is 10 seconds.

+ +

Timeout in milliseconds for connecting to databases, both Metabase application database and data connections. + In case you’re connecting via an SSH tunnel and run into a timeout, you might consider increasing this value + as the connections via tunnels have more overhead than connections without.

+ +

MB_DB_QUERY_TIMEOUT_MINUTES

+ +
    +
  • Type: integer
  • +
  • Default: 20
  • +
+ +

By default, this is 20 minutes.

+ +

Timeout in minutes for databases query execution, both Metabase application database and data connections. + If you have long-running queries, you might consider increasing this value. + Adjusting the timeout does not impact Metabase’s frontend. + Please be aware that other services (like Nginx) may still drop long-running queries.

+ +

MB_DEFAULT_MAPS_ENABLED

+ + + +

Whether or not the default GeoJSON maps are enabled.

+ +

MB_DOWNLOAD_ROW_LIMIT

+ +
    +
  • Type: positive-integer
  • +
  • Default: null
  • +
  • Exported as: download-row-limit.
  • +
+ +

Row limit in file exports excluding the header. Enforces 1048575 excluding header as minimum. xlsx downloads are inherently limited to 1048575 rows even if this limit is higher.

+ +

MB_EE_AI_FEATURES_ENABLED

+ + + +

Enable AI features.

+ +

This feature is experimental.

+ +

MB_EE_OPENAI_API_KEY

+ + + +

The OpenAI API Key used in Metabase Enterprise.

+ +

This feature is experimental.

+ +

MB_EE_OPENAI_MODEL

+ + + +

The OpenAI Model (e.g. ‘gpt-4’, ‘gpt-3.5-turbo’).

+ +

This feature is experimental.

+ +

MB_EMAIL_FROM_ADDRESS

+ + + +

The email address you want to use for the sender of emails.

+ +

MB_EMAIL_FROM_NAME

+ + + +

The name you want to use for the sender of emails.

+ +

MB_EMAIL_MAX_RECIPIENTS_PER_SECOND

+ + + +

The maximum number of recipients, summed across emails, that can be sent per second. + Note that the final email sent before reaching the limit is able to exceed it, if it has multiple recipients.

+ +

MB_EMAIL_REPLY_TO

+ + + +

The email address you want the replies to go to, if different from the from address.

+ +

MB_EMAIL_SMTP_HOST

+ + + +

The address of the SMTP server that handles your emails.

+ +

MB_EMAIL_SMTP_PASSWORD

+ + + +

SMTP password.

+ +

MB_EMAIL_SMTP_PORT

+ + + +

The port your SMTP server uses for outgoing emails.

+ +

MB_EMAIL_SMTP_SECURITY

+ + + +

SMTP secure connection protocol. (tls, ssl, starttls, or none).

+ +

MB_EMAIL_SMTP_USERNAME

+ + + +

SMTP username.

+ +

MB_EMBEDDING_APP_ORIGIN [DEPRECATED]

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ +
+

DEPRECATED: 0.51.0

+
+ + + +

Allow this origin to embed the full Metabase application.

+ +

MB_EMBEDDING_APP_ORIGINS_INTERACTIVE

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Allow these space delimited origins to embed Metabase interactive.

+ +

MB_EMBEDDING_APP_ORIGINS_SDK

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Allow Metabase SDK access to these space delimited origins.

+ +

MB_EMBEDDING_HOMEPAGE

+ + + +

Embedding homepage status, indicating if it’s visible, hidden or has been dismissed.

+ +

MB_EMBEDDING_SECRET_KEY

+ + + +

Secret key used to sign JSON Web Tokens for requests to /api/embed endpoints.

+ +

MB_ENABLE_EMBEDDING [DEPRECATED]

+ +
+

DEPRECATED: 0.51.0

+
+ + + +

Allow admins to securely embed questions and dashboards within other applications?

+ +

MB_ENABLE_EMBEDDING_INTERACTIVE

+ + + +

Allow admins to embed Metabase via interactive embedding?

+ +

MB_ENABLE_EMBEDDING_SDK

+ + + +

Allow admins to embed Metabase via the SDK?

+ +

MB_ENABLE_EMBEDDING_STATIC

+ + + +

Allow admins to embed Metabase via static embedding?

+ +

MB_ENABLE_FIELD_USAGE_ANALYSIS

+ + + +

Enable field usage analysis for queries. This will analyze the fields used in queries and store them in the + application database.

+ +
Turn off by default since we haven't had an user-facing feature that uses this data yet.
+
+ +

MB_ENABLE_PASSWORD_LOGIN

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Allow logging in by email and password.

+ +

MB_ENABLE_PIVOTED_EXPORTS

+ + + +

Enable pivoted exports and pivoted subscriptions.

+ +

MB_ENABLE_PUBLIC_SHARING

+ + + +

Enable admins to create publicly viewable links (and embeddable iframes) for Questions and Dashboards?

+ +

MB_ENABLE_QUERY_CACHING

+ + + +

Allow caching results of queries that take a long time to run.

+ +

MB_ENABLE_XRAYS

+ + + +

Allow users to explore data using X-rays.

+ +

MB_FOLLOW_UP_EMAIL_SENT

+ +
    +
  • Type: boolean
  • +
  • Default: false
  • +
+ +

Have we sent a follow up email to the instance admin?

+ +

MB_GOOGLE_AUTH_AUTO_CREATE_ACCOUNTS_DOMAIN

+ + + +

When set, allow users to sign up on their own if their Google account email address is from this domain.

+ +

MB_GOOGLE_AUTH_CLIENT_ID

+ + + +

Client ID for Google Sign-In.

+ +

MB_GOOGLE_AUTH_ENABLED

+ + + +

Is Google Sign-in currently enabled?

+ +

MB_GSHEETS

+ + + +

Information about Google Sheets Integration.

+ +

MB_HEALTH_CHECK_LOGGING_ENABLED

+ +
    +
  • Type: boolean
  • +
  • Default: true
  • +
+ +

Whether to log health check requests from session middleware.

+ + + +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Keyword setting to control whitelabeling of the help link. Valid values are :metabase, :hidden, and :custom. If :custom is set, the help link will use the URL specified in the help-link-custom-destination, or be hidden if it is not set.

+ + + +
+

Only available on Metabase Pro and Enterprise plans.

+
+ +
    +
  • Type: string
  • +
  • Default: https://www.metabase.com/help/premium
  • +
  • Configuration file name: help-link-custom-destination
  • +
+ +

Custom URL for the help link.

+ +

MB_HUMANIZATION_STRATEGY

+ + + +

To make table and field names more human-friendly, Metabase will replace dashes and underscores in them with spaces. We’ll capitalize each word while at it, so ‘last_visited_at’ will become ‘Last Visited At’.

+ +

MB_JDBC_DATA_WAREHOUSE_MAX_CONNECTION_POOL_SIZE

+ +
    +
  • Type: integer
  • +
  • Default: 15
  • +
+ +

Maximum size of the c3p0 connection pool.

+ +

Change this to a higher value if you notice that regular usage consumes all or close to all connections.

+ +

When all connections are in use then Metabase will be slower to return results for queries, since it would have to wait for an available connection before processing the next query in the queue.

+ +

For setting the maximum, see MB_APPLICATION_DB_MAX_CONNECTION_POOL_SIZE.

+ +

MB_JWT_ATTRIBUTE_EMAIL

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Key to retrieve the JWT user’s email address.

+ +

MB_JWT_ATTRIBUTE_FIRSTNAME

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Key to retrieve the JWT user’s first name.

+ +

MB_JWT_ATTRIBUTE_GROUPS

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Key to retrieve the JWT user’s groups.

+ +

MB_JWT_ATTRIBUTE_LASTNAME

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Key to retrieve the JWT user’s last name.

+ +

MB_JWT_ENABLED

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Is JWT authentication configured and enabled?

+ +

When set to true, will enable JWT authentication with the options configured in the MB_JWT_* variables. + This is for JWT SSO authentication, and has nothing to do with Static embedding, which is MB_EMBEDDING_SECRET_KEY.

+ +

MB_JWT_GROUP_MAPPINGS

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

JSON containing JWT to Metabase group mappings.

+ +

JSON object containing JWT to Metabase group mappings, where keys are JWT groups and values are lists of Metabase groups IDs.

+ +

MB_JWT_GROUP_SYNC

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Enable group membership synchronization with JWT.

+ +

MB_JWT_IDENTITY_PROVIDER_URI

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

URL for JWT-based login page. Optional if using JWT SSO only with the embedded analytics SDK.

+ +

MB_JWT_SHARED_SECRET

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

String used to seed the private key used to validate JWT messages. A hexadecimal-encoded 256-bit key (i.e., a 64-character string) is strongly recommended.

+ +

MB_JWT_USER_PROVISIONING_ENABLED

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

When we enable JWT user provisioning, we automatically create a Metabase account on JWT signin for users who +don’t have one.

+ +

MB_LANDING_PAGE

+ + + +

Enter a URL of the landing page to show the user. This overrides the custom homepage setting above.

+ +

MB_LANDING_PAGE_ILLUSTRATION

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Options for displaying the illustration on the landing page.

+ +

MB_LANDING_PAGE_ILLUSTRATION_CUSTOM

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

The custom illustration for the landing page.

+ +

MB_LDAP_ATTRIBUTE_EMAIL

+ + + +

Attribute to use for the user’s email. (usually ‘mail’, ‘email’ or ‘userPrincipalName’).

+ +

MB_LDAP_ATTRIBUTE_FIRSTNAME

+ + + +

Attribute to use for the user’s first name. (usually ‘givenName’).

+ +

MB_LDAP_ATTRIBUTE_LASTNAME

+ + + +

Attribute to use for the user’s last name. (usually ‘sn’).

+ +

MB_LDAP_BIND_DN

+ + + +

The Distinguished Name to bind as (if any), this user will be used to lookup information about other users.

+ +

MB_LDAP_ENABLED

+ + + +

Is LDAP currently enabled?

+ +

MB_LDAP_GROUP_BASE

+ + + +

Search base for groups. Not required for LDAP directories that provide a ‘memberOf’ overlay, such as Active Directory. (Will be searched recursively).

+ +

MB_LDAP_GROUP_MAPPINGS

+ + + +

JSON containing LDAP to Metabase group mappings.

+ +

MB_LDAP_GROUP_MEMBERSHIP_FILTER

+ + + +

Group membership lookup filter. The placeholders {dn} and {uid} will be replaced by the user’s Distinguished Name and UID, respectively.

+ +

MB_LDAP_GROUP_SYNC

+ + + +

Enable group membership synchronization with LDAP.

+ +

MB_LDAP_HOST

+ + + +

Server hostname.

+ +

MB_LDAP_PASSWORD

+ + + +

The password to bind with for the lookup user.

+ +

MB_LDAP_PORT

+ + + +

Server port, usually 389 or 636 if SSL is used.

+ +

MB_LDAP_SECURITY

+ + + +

Use SSL, TLS or plain text.

+ +

MB_LDAP_SYNC_USER_ATTRIBUTES

+ + + +

Should we sync user attributes when someone logs in via LDAP?

+ +

MB_LDAP_SYNC_USER_ATTRIBUTES_BLACKLIST

+ +
    +
  • Type: csv
  • +
  • Default: userPassword,dn,distinguishedName
  • +
  • Configuration file name: ldap-sync-user-attributes-blacklist
  • +
+ +

Comma-separated list of user attributes to skip syncing for LDAP users.

+ +

MB_LDAP_USER_BASE

+ + + +

Search base for users. (Will be searched recursively).

+ +

MB_LDAP_USER_FILTER

+ +
    +
  • Type: string
  • +
  • Default: (&(objectClass=inetOrgPerson)(|(uid={login})(mail={login})))
  • +
  • Configuration file name: ldap-user-filter
  • +
+ +

User lookup filter. The placeholder ‘{login}’ will be replaced by the user supplied login.

+ +

MB_LDAP_USER_PROVISIONING_ENABLED

+ + + +

When we enable LDAP user provisioning, we automatically create a Metabase account on LDAP signin for users who +don’t have one.

+ +

MB_LOADING_MESSAGE

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Choose the message to show while a query is running. Possible values are “doing-science”, “running-query”, or “loading-results”.

+ +

MB_LOGIN_PAGE_ILLUSTRATION

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Options for displaying the illustration on the login page.

+ +

MB_LOGIN_PAGE_ILLUSTRATION_CUSTOM

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

The custom illustration for the login page.

+ +

MB_MAP_TILE_SERVER_URL

+ +
    +
  • Type: string
  • +
  • Default: https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png
  • +
  • Configuration file name: map-tile-server-url
  • +
+ +

The map tile server URL template used in map visualizations, for example from OpenStreetMaps or MapBox.

+ +

MB_NATIVE_QUERY_AUTOCOMPLETE_MATCH_STYLE

+ + + +

Matching style for native query editor’s autocomplete. Can be “substring”, “prefix”, or “off”. Larger instances can have performance issues matching using substring, so can use prefix matching, or turn autocompletions off.

+ +

MB_NESTED_FIELD_COLUMNS_VALUE_LENGTH_LIMIT

+ +
    +
  • Type: integer
  • +
  • Default: 50000
  • +
  • Exported as: nested-field-columns-value-length-limit.
  • +
+ +

Maximum length of a JSON string before skipping it during sync for JSON unfolding. If this is set too high it could lead to slow syncs or out of memory errors.

+ +

MB_NO_DATA_ILLUSTRATION

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Options for displaying the illustration when there are no results after running a question.

+ +

MB_NO_DATA_ILLUSTRATION_CUSTOM

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

The custom illustration for when there are no results after running a question.

+ +

MB_NO_OBJECT_ILLUSTRATION

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Options for displaying the illustration when there are no results after searching.

+ +

MB_NO_OBJECT_ILLUSTRATION_CUSTOM

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

The custom illustration for when there are no results after searching.

+ +

MB_NOT_BEHIND_PROXY

+ +
    +
  • Type: boolean
  • +
  • Default: false
  • +
+ +

Indicates whether Metabase is running behind a proxy that sets the source-address-header for incoming requests.

+ + + +
+

Only available on Metabase Pro and Enterprise plans.

+
+ +
    +
  • Type: string
  • +
  • Default: null
  • +
+ +

By default “Site Url” is used in notification links, but can be overridden.

+ +

The base URL where dashboard notitification links will point to instead of the Metabase base URL. + Only applicable for users who utilize interactive embedding and subscriptions.

+ +

MB_NOTIFICATION_THREAD_POOL_SIZE

+ +
    +
  • Type: integer
  • +
  • Default: 3
  • +
+ +

The size of the thread pool used to send notifications.

+ +

MB_PERSISTED_MODEL_REFRESH_CRON_SCHEDULE

+ + + +

cron syntax string to schedule refreshing persisted models.

+ +

MB_PERSISTED_MODELS_ENABLED

+ + + +

Allow persisting models into the source database.

+ +

MB_PREMIUM_EMBEDDING_TOKEN

+ + + +

Token for premium features. Go to the MetaStore to get yours!

+ +

MB_QUERY_ANALYSIS_ENABLED

+ + + +

Whether or not we analyze any queries at all.

+ +

MB_QUERY_CACHING_MAX_KB

+ + + +

The maximum size of the cache, per saved question, in kilobytes.

+ +

MB_QUERY_CACHING_MAX_TTL

+ + + +

The absolute maximum time to keep any cached query results, in seconds.

+ +

MB_REDIRECT_ALL_REQUESTS_TO_HTTPS

+ + + +

Force all traffic to use HTTPS via a redirect, if the site URL is HTTPS.

+ +

MB_REPORT_TIMEZONE

+ + + +

Connection timezone to use when executing queries. Defaults to system timezone.

+ +

MB_RESET_TOKEN_TTL_HOURS

+ +
    +
  • Type: integer
  • +
  • Default: 48
  • +
+ +

Number of hours a password reset is considered valid.

+ +

MB_RETRY_INITIAL_INTERVAL

+ + + +

The initial retry delay in milliseconds.

+ +

MB_RETRY_MAX_ATTEMPTS

+ + + +

The maximum number of attempts for an event.

+ +

MB_RETRY_MAX_INTERVAL_MILLIS

+ + + +

The maximum delay between attempts.

+ +

MB_RETRY_MULTIPLIER

+ + + +

The delay multiplier between attempts.

+ +

MB_RETRY_RANDOMIZATION_FACTOR

+ + + +

The randomization factor of the retry delay.

+ +

MB_SAML_APPLICATION_NAME

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

This application name will be used for requests to the Identity Provider.

+ +

MB_SAML_ATTRIBUTE_EMAIL

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ +
    +
  • Type: string
  • +
  • Default: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
  • +
  • Configuration file name: saml-attribute-email
  • +
+ +

SAML attribute for the user’s email address.

+ +

MB_SAML_ATTRIBUTE_FIRSTNAME

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ +
    +
  • Type: string
  • +
  • Default: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
  • +
  • Configuration file name: saml-attribute-firstname
  • +
+ +

SAML attribute for the user’s first name.

+ +

MB_SAML_ATTRIBUTE_GROUP

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

SAML attribute for group syncing.

+ +

MB_SAML_ATTRIBUTE_LASTNAME

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ +
    +
  • Type: string
  • +
  • Default: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
  • +
  • Configuration file name: saml-attribute-lastname
  • +
+ +

SAML attribute for the user’s last name.

+ +

MB_SAML_ENABLED

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Is SAML authentication configured and enabled?

+ +

MB_SAML_GROUP_MAPPINGS

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

JSON containing SAML to Metabase group mappings.

+ +

MB_SAML_GROUP_SYNC

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Enable group membership synchronization with SAML.

+ +

MB_SAML_IDENTITY_PROVIDER_CERTIFICATE

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Encoded certificate for the identity provider. Depending on your IdP, you might need to download this, +open it in a text editor, then copy and paste the certificate’s contents here.

+ +

MB_SAML_IDENTITY_PROVIDER_ISSUER

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

This is a unique identifier for the IdP. Often referred to as Entity ID or simply ‘Issuer’. Depending +on your IdP, this usually looks something like http://www.example.com/141xkex604w0Q5PN724v.

+ +

MB_SAML_IDENTITY_PROVIDER_SLO_URI

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

This is the URL where your users go to logout of your identity provider. Depending on which IdP you’re +using, this usually looks like https://your-org-name.example.com or https://example.com/app/my_saml_app/abc123/sso/slo.

+ +

MB_SAML_IDENTITY_PROVIDER_URI

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

This is the URL where your users go to log in to your identity provider. Depending on which IdP you’re +using, this usually looks like https://your-org-name.example.com or https://example.com/app/my_saml_app/abc123/sso/saml.

+ +

MB_SAML_KEYSTORE_ALIAS

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Alias for the key that Metabase should use for signing SAML requests.

+ +

MB_SAML_KEYSTORE_PASSWORD

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Password for opening the keystore.

+ +

MB_SAML_KEYSTORE_PATH

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Absolute path to the Keystore file to use for signing SAML requests.

+ +

MB_SAML_SLO_ENABLED

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Is SAML Single Log Out enabled?

+ +

MB_SAML_USER_PROVISIONING_ENABLED

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

When we enable SAML user provisioning, we automatically create a Metabase account on SAML signin for users who +don’t have one.

+ +

MB_SCIM_ENABLED

+ + + +

Is SCIM currently enabled?

+ +

MB_SEARCH_ENGINE

+ +
    +
  • Type: keyword
  • +
  • Default: :appdb
  • +
+ +

Which engine to use when performing search. Supported values are :in-place and :appdb.

+ +

MB_SEARCH_TYPEAHEAD_ENABLED

+ + + +

Enable typeahead search in the Metabase navbar?

+ +

MB_SEND_NEW_SSO_USER_ADMIN_EMAIL

+ + + +

Should new email notifications be sent to admins, for all new SSO users?

+ + + + + +

Value for the session cookie’s SameSite directive.

+ +

See Embedding Metabase in a different domain. + Read more about interactive Embedding. + Learn more about SameSite cookies.

+ +

MB_SESSION_COOKIES

+ + + +

When set, enforces the use of session cookies for all users which expire when the browser is closed.

+ +

The user login session will always expire after the amount of time defined in MAX_SESSION_AGE (by default 2 weeks). + This overrides the “Remember me” checkbox when logging in. + Also see the Changing session expiration documentation page.

+ +

MB_SESSION_TIMEOUT

+ + + +

Time before inactive users are logged out. By default, sessions last indefinitely.

+ +

Has to be in the JSON format "{"amount":120,"unit":"minutes"}" where the unit is one of “seconds”, “minutes” or “hours”.

+ +

MB_SETUP_EMBEDDING_AUTOENABLED

+ + + +

Indicates if embedding has enabled automatically during the setup because the user was interested in embedding.

+ +

MB_SETUP_LICENSE_ACTIVE_AT_SETUP

+ + + +

Indicates if at the end of the setup a valid license was active.

+ +

MB_SHOW_DATABASE_SYNCING_MODAL

+ + + +

Whether an introductory modal should be shown after the next database connection is added. Defaults to false if any non-default database has already finished syncing for this instance.

+ +

MB_SHOW_HOMEPAGE_DATA

+ + + +

Whether or not to display data on the homepage. Admins might turn this off in order to direct users to better content than raw data.

+ +

MB_SHOW_HOMEPAGE_XRAYS

+ + + +

Whether or not to display x-ray suggestions on the homepage. They will also be hidden if any dashboards are pinned. Admins might hide this to direct users to better content than raw data.

+ + + +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Whether or not to display Metabase links outside admin settings.

+ +

MB_SHOW_METABOT

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Enables Metabot character on the home page.

+ +

MB_SHOW_STATIC_EMBED_TERMS

+ + + +

Check if the static embedding licensing should be hidden in the static embedding flow.

+ +

MB_SITE_LOCALE

+ + + +

The default language for all users across the Metabase UI, system emails, pulses, and alerts. Users can individually override this default language from their own account settings.

+ +

MB_SITE_NAME

+ + + +

The name used for this instance of Metabase.

+ +

MB_SITE_URL

+ + + +

This URL is used for things like creating links in emails, auth redirects, and in some embedding scenarios, so changing it could break functionality or get you locked out of this instance.

+ +

This URL is critical for things like SSO authentication, email links, embedding and more. + Even difference with http:// vs https:// can cause problems. + Make sure that the address defined is how Metabase is being accessed.

+ +

MB_SLACK_APP_TOKEN

+ + + +

Bot user OAuth token for connecting the Metabase Slack app. This should be used for all new Slack integrations starting in Metabase v0.42.0.

+ +

MB_SLACK_BUG_REPORT_CHANNEL

+ + + +

The name of the channel where bug reports should be posted.

+ +

MB_SLACK_FILES_CHANNEL [DEPRECATED]

+ +
+

DEPRECATED: 0.54.0

+
+ + + +

The name of the channel to which Metabase files should be initially uploaded.

+ +

MB_SOURCE_ADDRESS_HEADER

+ + + +

Identify the source of HTTP requests by this header’s value, instead of its remote address.

+ +

MB_SQL_JDBC_FETCH_SIZE

+ +
    +
  • Type: integer
  • +
  • Default: 500
  • +
+ +

Fetch size for result sets. We want to ensure that the jdbc ResultSet objects are not realizing the entire results + in memory.

+ +

MB_SQL_PARSING_ENABLED

+ +
    +
  • Type: boolean
  • +
  • Default: true
  • +
+ +

SQL Parsing is disabled.

+ +

MB_SSH_HEARTBEAT_INTERVAL_SEC

+ + + +

Controls how often the heartbeats are sent when an SSH tunnel is established (in seconds).

+ +

MB_START_OF_WEEK

+ + + +

This will affect things like grouping by week or filtering in GUI queries. It won’t affect most SQL queries, although it is used to set the WEEK_START session variable in Snowflake.

+ +

MB_SUBSCRIPTION_ALLOWED_DOMAINS

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Allowed email address domain(s) for new Dashboard Subscriptions and Alerts. To specify multiple domains, separate each domain with a comma, with no space in between. To allow all domains, leave the field empty. This setting doesn’t affect existing subscriptions.

+ +

MB_SURVEYS_ENABLED

+ +
    +
  • Type: boolean
  • +
  • Default: true
  • +
+ +

Enable or disable surveys.

+ +

MB_SYNCHRONOUS_BATCH_UPDATES

+ + + +

Process batches updates synchronously. If true, all submit! calls will be processed immediately. Default is false.

+ +

MB_UNAGGREGATED_QUERY_ROW_LIMIT

+ + + +

Maximum number of rows to return specifically on :rows type queries via the API.

+ +

Must be less than 1048575, and less than the number configured in MB_AGGREGATED_QUERY_ROW_LIMIT. See also MB_AGGREGATED_QUERY_ROW_LIMIT.

+ +

MB_UPDATE_CHANNEL

+ + + +

We’ll notify you here when there’s a new version of this type of release.

+ +

MB_UPLOADS_DATABASE_ID [DEPRECATED]

+ +
+

DEPRECATED: 0.50.0

+
+ +
    +
  • Type: integer
  • +
  • Default: null
  • +
+ +

Database ID for uploads.

+ +

MB_UPLOADS_ENABLED [DEPRECATED]

+ +
+

DEPRECATED: 0.50.0

+
+ +
    +
  • Type: boolean
  • +
  • Default: false
  • +
+ +

Whether or not uploads are enabled.

+ +

MB_UPLOADS_SCHEMA_NAME [DEPRECATED]

+ +
+

DEPRECATED: 0.50.0

+
+ +
    +
  • Type: string
  • +
  • Default: null
  • +
+ +

Schema name for uploads.

+ +

MB_UPLOADS_SETTINGS

+ + + +

Upload settings.

+ +

MB_UPLOADS_TABLE_PREFIX [DEPRECATED]

+ +
+

DEPRECATED: 0.50.0

+
+ +
    +
  • Type: string
  • +
  • Default: null
  • +
+ +

Prefix for upload table names.

+ +

MB_USER_VISIBILITY

+ +
+

Only available on Metabase Pro and Enterprise plans.

+
+ + + +

Note: Sandboxed users will never see suggestions.

+ +

Other environment variables

+ +

The following environment variables can only be set via the environment. They cannot be set by the configuration file.

+ +

MAX_SESSION_AGE

+ +

Type: integer
+Default: 20160

+ +

Session expiration, defined in minutes (default is 2 weeks), which will log out users after the defined period and require re-authentication.

+ +

Note: This setting is not an idle/inactivity timeout. If you set this to 15 minutes, your users have to login (or re-authenticate) again every 15 minutes. Use MB_SESSION_TIMEOUT to control timeout based on inactivity.

+ +

Use MB_SESSION_COOKIES to also expire sessions, when browser is closed.

+ +

Also see the Changing session expiration documentation page.

+ +

MB_APPLICATION_DB_MAX_CONNECTION_POOL_SIZE

+ +

Type: integer
+Default: 15
+Since: v35.0

+ +

Maximum number of connections to the Metabase application database.

+ +

Change this to a higher value if you notice that regular usage consumes all or close to all connections. When all connections are in use, Metabase might feel slow or unresponsive when clicking around the interface.

+ +

To see how many connections are being used, check the Metabase logs and look for lines that contains the following: … App DB connections: 12/15 …. In this example, 12 out of 15 available connections are being used.

+ +

See MB_JDBC_DATA_WAREHOUSE_MAX_CONNECTION_POOL_SIZE for setting maximum connections to the databases connected to Metabase.

+ +

MB_ASYNC_QUERY_THREAD_POOL_SIZE

+ +

Type: integer
+Default: 50
+Since: v35.0

+ +

Maximum number of async Jetty threads. If not set, then MB_JETTY_MAXTHREADS will be used, otherwise it will use the default.

+ +

MB_ATTACHMENT_TABLE_ROW_LIMIT

+ +

Type: integer
+Default: 20

+ +

Limits the number of rows Metabase will display in tables sent with dashboard subscriptions and alerts. Range: 1-100. To limit the total number of rows included in the file attachment for an email dashboard subscription, use MB_UNAGGREGATED_QUERY_ROW_LIMIT.

+ +

MB_AUDIT_MAX_RETENTION_DAYS

+ +

Only available on Metabase Pro and Enterprise plans.
+Type: integer
+Default: 720 (Metabase keeps all rows)

+ +

Sets the maximum number of days Metabase preserves rows for the following application database tables:

+ +
    +
  • query_execution
  • +
  • audit_log
  • +
  • view_log
  • +
+ +

Twice a day, Metabase will delete rows older than this threshold.

+ +

The minimum value is 30 days (Metabase will treat entered values of 1 to 29 the same as 30). If set to 0, Metabase will keep all rows.

+ +

MB_COLORIZE_LOGS

+ +

Type: boolean
+Default: true

+ +

Color log lines. When set to false it will disable log line colors. This is disabled on Windows. Related to MB_EMOJI_IN_LOGS.

+ +

MB_CONFIG_FILE_PATH

+ +

Type: string
+Default: config.yml

+ +

This feature requires the config-text-file feature flag on your token.

+ +

MB_DB_AUTOMIGRATE

+ +

Type: boolean
+Default: true

+ +

When set to false, Metabase will print migrations needed to be done in the application database and exit. Those migrations need to be applied manually. When true, Metabase will automatically make changes to the application database. This is not related to migrating away from H2.

+ +

MB_DB_CONNECTION_URI

+ +

Type: string
+Default: null

+ +

A JDBC-style connection URI that can be used instead of most of MB_DB_* like MB_DB_HOST. Also used when certain Connection String parameters are required for the connection. The connection type requirement is the same as MB_DB_TYPE.

+ +

Examples:

+ +
jdbc:postgresql://db.example.com:5432/mydb?user=dbuser&password=dbpassword
+
+jdbc:postgresql://db.example.com:5432/mydb?user=dbuser&password=dbpassword&ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory
+
+jdbc:mysql://db.example.com:3306/mydb?user=dbuser&password=dbpassword
+
+ +

MB_DB_DBNAME

+ +

Type: string
+Default: null

+ +

The database name of the application database used with MB_DB_HOST.

+ +

MB_DB_FILE

+ +

Type: string
+Default: "metabase.db"

+ +

Location of H2 database file. Should not include the .mv.db (or .h2.db) file extension. Used when MB_DB_TYPE is set to"h2".

+ +

Can also be used when migrating away from H2 to specify where the existing data should be read from.

+ +

MB_DB_HOST

+ +

Type: string
+Default: null

+ +

The host name or IP address of the application database. Used when MB_DB_TYPE is different than "h2".

+ +

MB_DB_IN_MEMORY

+ +

Type: boolean
+Default: null

+ +

Used for testing with MB_DB_FILE.

+ +

MB_DB_PASS

+ +

Type: string
+Default: null

+ +

The password for MB_DB_HOST.

+ +

MB_DB_PORT

+ +

Type: integer
+Default: null

+ +

The port for MB_DB_HOST.

+ +

MB_DB_TYPE

+ +

Type: string ("h2", "postgres", "mysql")
+Default: "h2"

+ +

When "h2", the application database is loaded from MB_DB_FILE, otherwise MB_DB_HOST will be used to define application database.

+ +

MB_DB_USER

+ +

Type: string
+Default: null

+ +

The username for MB_DB_HOST.

+ +

MB_DEV_ADDITIONAL_DRIVER_MANIFEST_PATHS

+ +

Type: string
+Default: null

+ +

Used during development of third-party drivers. Set the value to have that plugin manifest get loaded during startup. Specify multiple plugin manifests by comma-separating them.

+ +

MB_DISABLE_SCHEDULER

+ +

Type: boolean
+Default: false

+ +

When true, Metabase will turn off Metabase’s scheduled jobs, which include syncs, fingerprinting, and scanning, as well as dashboard subscriptions, alerts, and model caching.

+ +

Can be useful for testing, or when setting up a git-based workflow.

+ +

MB_DISABLE_SESSION_THROTTLE

+ +

Type: boolean
+Default: false

+ +

When true, this will disable session throttling. Warning: It is not recommended to disable throttling, since it is a protective measure against brute-force attacks.

+ +

Use MB_SOURCE_ADDRESS_HEADER to set the IP address of the remote client from e.g. a reverse-proxy.

+ +

MB_EMOJI_IN_LOGS

+ +

Type: boolean
+Default: true

+ +

Emojis on log lines. When set to false it will disable log line emojis. This is disabled on Windows. Related to MB_COLORIZE_LOGS.

+ +

MB_ENABLE_TEST_ENDPOINTS

+ +

Type: boolean
+Default: null

+ +

When true, this will enable /api/testing endpoint. Warning: This should never be enabled in production system.

+ +

MB_ENCRYPTION_SECRET_KEY

+ +

Type: string
+Default: null

+ +

When set, this will encrypt database credentials stored in the application database. Requirement: minimum 16 characters base64-encoded string.

+ +

Also see documentation page Encrypting database details at rest.

+ +

MB_JDBC_DATA_WAREHOUSE_UNRETURNED_CONNECTION_TIMEOUT_SECONDS

+ +

Type: integer
+Default: 1200
+Since: v47.4

+ +

Metabase’s query processor will normally kill connections when their queries time out, but in practice some connections can be severed and go undetected by Metabase, staying alive even after a query returns or times out. This environment variable tells Metabase how long to wait before killing connections if no response is received from the connection.

+ +

This variable affects connections that are severed and undetected by Metabase (that is, in situations where Metabase never receives a connection closed signal and is treating an inactive connection as active). You may want to adjust this variable’s value if your connection is unreliable or is a dynamic connections behind a SSH tunnel where the connection to the SSH tunnel host may stay active even after the connection from the SSH tunnel host to your database is severed.

+ +

Unless set otherwise, the default production value for metabase.query-processor.query-timeout-ms is used which is 1,200,000 ms (i.e. 1,200 seconds or 20 minutes).

+ +

MB_JDBC_DATA_WAREHOUSE_DEBUG_UNRETURNED_CONNECTION_STACK_TRACES

+ +

Type: boolean
+Default: false
+Since: v51.3

+ +

If true, log a stack trace for any connections killed due to exceeding the timeout specified in MB_JDBC_DATA_WAREHOUSE_UNRETURNED_CONNECTION_TIMEOUT_SECONDS.

+ +

In order to see the stack traces in the logs, you’ll also need to update the com.mchange log level to “INFO” or higher via a custom log4j configuration. For configuring log levels, see Metabase log configuration.

+ +

To set a timeout for how long Metabase should wait before it kills unreturned connections, see MB_JDBC_DATA_WAREHOUSE_UNRETURNED_CONNECTION_TIMEOUT_SECONDS.

+ +

MB_JETTY_ASYNC_RESPONSE_TIMEOUT

+ +

Type: integer
+Default: 600000
+Since: v35.0

+ +

Timeout of Jetty async threads, defined in milliseconds. The default is 10 minutes. Very few things might reach that timeout, since they return some type of data before, but things like CSV downloads might.

+ +

MB_JETTY_DAEMON

+ +

Type: boolean
+Default: false

+ +

Use daemon threads.

+ +

MB_JETTY_HOST

+ +

Type: string
+Default: localhost for JAR, 0.0.0.0 for Docker

+ +

Configure a host either as a host name or IP address to identify a specific network interface on which to listen. If set to "0.0.0.0", Metabase listens on all network interfaces. It will listen on the port specified in MB_JETTY_PORT.

+ +

MB_JETTY_JOIN

+ +

Type: boolean
+Default: true

+ +

Blocks the thread until server ends.

+ +

MB_JETTY_MAXIDLETIME

+ +

Type: integer
+Default: 200000

+ +

Maximum idle time for a connection, in milliseconds.

+ +

MB_JETTY_MAXTHREADS

+ +

Type: integer
+Default: 50

+ +

Maximum number of threads.

+ +

Change this to a higher value if you notice that regular usage consumes all or close to all threads. When all threads are in use Metabase might feel slow or unresponsive when clicking around the interface.

+ +

To see how many threads are being used, check the Metabase logs and look for lines that contain the following: … Jetty threads: 45/50 …, which in this case would indicate 45 out of 50 available threads are being used.

+ +

Related MB_ASYNC_QUERY_THREAD_POOL_SIZE.

+ +

MB_JETTY_MINTHREADS

+ +

Type: integer
+Default: 8

+ +

Minimum number of threads.

+ +

MB_JETTY_PORT

+ +

Type: integer
+Default: 3000

+ +

Configure which port to use for HTTP. It will listen on the interface specified in MB_JETTY_HOST.

+ +

MB_JETTY_REQUEST_HEADER_SIZE

+ +

Type: integer
+Default: 8192
+Since: v36.0

+ +

Maximum size of a request header, in bytes. Increase this value if you are experiencing errors like “Request Header Fields Too Large”.

+ +

MB_JETTY_SSL

+ +

Type: boolean
+Default: null

+ +

When set to true, will enable HTTPS with the options configured in the MB_JETTY_SSL_* variables.

+ +

Also see the Customizing Jetty web server documentation page.

+ +

MB_JETTY_SSL_CLIENT_AUTH

+ +

Type: boolean
+Default: null

+ +

Configure Java SSL client authentication. When set to true, client certificates are required and verified by the certificate authority in the TrustStore.

+ +

MB_JETTY_SSL_KEYSTORE

+ +

Type: string
+Default: null

+ +

Path to Java KeyStore file.

+ +

MB_JETTY_SSL_KEYSTORE_PASSWORD

+ +

Type: string
+Default: null

+ +

Password for Java KeyStore file.

+ +

MB_JETTY_SSL_PORT

+ +

Type: integer
+Default: null

+ +

Configure which port to use for HTTPS. It will listen on the interface specified in MB_JETTY_HOST.

+ +

MB_JETTY_SSL_TRUSTSTORE

+ +

Type: string
+Default: null

+ +

Path to Java TrustStore file.

+ +

MB_JETTY_SSL_TRUSTSTORE_PASSWORD

+ +

Type: string
+Default: null

+ +

Password for Java TrustStore file.

+ +

MB_LANDING_PAGE

+ +

Only available on Metabase Pro and Enterprise plans.
+Type: string
+Default: ""

+ +

Default page to show people when they log in.

+ +

MB_LOAD_ANALYTICS_CONTENT

+ +

Type: Boolean
+Default: True

+ +

If you want to exclude the Metabase analytics collection, you can set MB_LOAD_ANALYTICS_CONTENT=false. Setting this environment variable to false can also come in handy when migrating environments, as it can simplify the migration process.

+ +

MB_LOAD_SAMPLE_CONTENT

+ +

Type: Boolean
+Default: True

+ +

Whether to include the Sample Database in your Metabase. To exclude the Sample Database, set MB_LOAD_SAMPLE_CONTENT=false.

+ +

MB_NO_SURVEYS

+ +

Type: boolean
+Default: false

+ +

Metabase will send a sentiment survey to people who create a number of questions and dashboards to gauge how well the product is doing with respect to making things easy for creators.

+ +

Metabase will only send these emails to people who have in the past 2 months:

+ +
    +
  • Created at least 10 questions total
  • +
  • Created at least 2 SQL questions
  • +
  • Created at least 1 dashboard
  • +
+ +

If you’re whitelabeling Metabase, these survey emails will only be sent to admins for that instance who meet that criteria.

+ +

If you don’t want Metabase to send these emails, set MB_NO_SURVEYS=true.

+ +

MB_NS_TRACE

+ +

Type: string
+Default: ""

+ +

Comma-separated namespaces to trace. WARNING: Could log sensitive information like database passwords.

+ +

MB_PASSWORD_COMPLEXITY

+ +

Type: string ("weak", "normal", "strong")
+Default: "normal"

+ +

Enforce a password complexity rule to increase security for regular logins. This only applies to new users or users that are changing their password. Related MB_PASSWORD_LENGTH

+ +
    +
  • weak no character constraints
  • +
  • normal at least 1 digit
  • +
  • strong minimum 8 characters w/ 2 lowercase, 2 uppercase, 1 digit, and 1 special character
  • +
+ +

MB_PASSWORD_LENGTH

+ +

Type: integer
+Default: 6

+ +

Set a minimum password length to increase security for regular logins. This only applies to new users or users that are changing their password. Uses the length of MB_PASSWORD_COMPLEXITY if not set.

+ +

MB_PLUGINS_DIR

+ +

Type: string
+Default: "plugins"

+ +

Path of the “plugins” directory, which is used to store the Metabase database drivers. The user who is running Metabase should have permission to write to the directory. When running the JAR, the default directory is plugins, created in the same location as the JAR file. When running Docker, the default directory is /plugins.

+ +

The location is where custom third-party drivers should be added. Then Metabase will load the driver on startup, which can be verified in the log.

+ +

MB_PREMIUM_EMBEDDING_TOKEN

+ +

Type: string
+Default: null

+ +

The license token used for Pro and Enterprise to enable premium features on the Enterprise edition. It is also used for the deprecated “Premium Embedding” functionality on the OSS edition.

+ +

MB_QP_CACHE_BACKEND

+ +

Type: string
+Default: "db"

+ +

Current cache backend. Dynamically rebindable primarily for test purposes.

+ +

MB_SEARCH_TYPEAHEAD_ENABLED

+ +

Type: boolean
+Default: true
+Since: v39.0

+ +

Show auto-suggestions when using the global search in the top navigation bar.

+ +

MB_SEND_EMAIL_ON_FIRST_LOGIN_FROM_NEW_DEVICE

+ +

Type: boolean
+Default: true
+Since: v39.0

+ +

Send email notification to user, when they login from a new device. Set to false to stop sending “We’ve noticed a new login on your Metabase account” emails for all users.

+ +

Also, this variable controls the geocoding service that Metabase uses to know the location from where your users logged in. Setting this variable to false also disables this reverse geocoding functionality.

+ +

MB_SEND_NEW_SSO_USER_ADMIN_EMAIL

+ +

Only available on Metabase Pro and Enterprise plans.
+Type: boolean
+Default: true

+ +

Send email notifications to users in Admin group, when a new SSO users is created on Metabase.

+ +

MB_SETUP_TOKEN

+ +

Type: string
+Default: null

+ +

An UUID token used to signify that an instance has permissions to create the initial User. This is created upon the first launch of Metabase, by the first instance; once used, it is cleared out, never to be used again.

+ +

MB_SHOW_LIGHTHOUSE_ILLUSTRATION

+ +

Only available on Metabase Pro and Enterprise plans.
+Type: boolean
+Default: true
+Since: v44.0

+ +

Display the lighthouse illustration on the home and login pages.

+ +

MB_JETTY_SKIP_SNI

+ +

Type: string
+Default: "true"
+Since: v48.4

+ +

Setting MB_JETTY_SKIP_SNI=true (the default setting) turns off the Server Name Indication (SNI) checks in the Jetty web server. Normally you would leave this enabled. If, however, you’re terminating the Transport Layer Security (TLS) connection on Metabase itself, and you’re getting an error like HTTP ERROR 400 Invalid SNI, consider either setting MB_JETTY_SKIP_SNI=false, or use another SSL certificate that exactly matches the domain name of the server.

+ +

MB_SOURCE_ADDRESS_HEADER

+ +

Type: string
+Default: X-Forwarded-For

+ +

Identify the source of HTTP requests by this header’s value, instead of its remote address. Related to MB_DISABLE_SESSION_THROTTLE.

+ +

MB_SSL_CERTIFICATE_PUBLIC_KEY

+ +

Type: string
+Default: null

+ +

Base-64 encoded public key for this sites SSL certificate. Specify this to enable HTTP Public Key Pinning. Using HPKP is no longer recommended. See http://mzl.la/1EnfqBf for more information.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/fonts.html b/_site/docs/doc-update-detection/configuring-metabase/fonts.html new file mode 100644 index 000000000..cfb004974 --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/fonts.html @@ -0,0 +1,3183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Fonts | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Fonts

+ +
+
+ + + + + + + +

Customizable font is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

On Pro and Enterprise plans, you can customize the font Metabase uses (the default is Lato). You can choose from a curated set of Google Fonts that accommodate the regular, bold, and heavy font weights that Metabase relies on for its various UI elements.

+ +

Included fonts

+ +

To change your Metabase font, click on the gear icon in the upper right of the screen and select Admin settings > Settings > Appearance. Under Font, select from a list of included fonts.

+ + + +

Comic Sans is currently not included.

+ +

Custom fonts

+ +

To set a custom font, click on the gear icon in the upper right of the screen and select Admin settings > Settings > Appearance.

+ +

For Font, select Custom… and enter URLs to your font files.

+ +

Font style options

+ +

You can set three different font styles with three different URLs, one for each font style (size and weight) that Metabase will use in order to display its user interface properly. The font weights are:

+ +
    +
  • Regular 400
  • +
  • Bold 700
  • +
  • Heavy 900 (sometimes called Black 900)
  • +
+ +

You only need to set the first style (Regular 400); the browser will fill in the other styles.

+ +

For best results, set at least the 400 and 700 styles. If you have a single font file that contains multiple font styles within the same family, enter the URL in multiple fields to tell Metabase to prefer the weights in that font file. Metabase will use those styles to override the font styles set by the browser.

+ +

Supported font file formats

+ +

For custom fonts, Metabase supports woff, woff2, ttf files. If the URL you provide lacks a specific file extension, Metabase will assume it’s a woff2 file.

+ +

Google Font URLs

+ +

To get a URL for a Google Font, visit the Google Font page and select the style you want to use. Then make an HTTP request to get the URL of the tff file. For example, say we want to use Roboto Mono: here’s how we could get the font file URLs for both the 400 and 700 styles:

+ +

We’d paste the URL https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&display=swap into our browser’s address bar. This URL will return a response like:

+ +
* cyrillic-ext */
+@font-face {
+  font-family: 'Roboto Mono';
+  font-style: normal;
+  font-weight: 400;
+  font-display: swap;
+  src: url(https://fonts.gstatic.com/s/robotomono/v21/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSV0me8iUI0lkQ.woff2) format('woff2');
+  unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+}
+/* cyrillic */
+@font-face {
+  font-family: 'Roboto Mono';
+  font-style: normal;
+  font-weight: 400;
+  font-display: swap;
+  src: url(https://fonts.gstatic.com/s/robotomono/v21/L0xTDF4xlVMF-BfR8bXMIhJHg45mwgGEFl0_3vrtSM1J-gEPT5Ese6hmHSx0me8iUI0lkQ.woff2) format('woff2');
+  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
+}
+...
+
+ +

For latin text, we’d copy the relevant src URLs for each style, in this case:

+ + + +

And paste those URLS in the relevant input fields in Admin settings > Settings > Appearance > Font section where it says “Tell us where to find the file for each font weight. You don’t need to include all of them, but it’ll look better if you do.”

+ +

Hosting fonts on GitHub

+ +

If you host a font on GitHub, the font should be in a public repository, and you’ll need to link to the raw font file(s) served from the raw.githubusercontent.com domain.

+ +

For example, let’s say you want to use the Inter typeface. The font is hosted at:

+ +

https://github.com/rsms/inter/blob/master/docs/font-files/Inter-Regular.woff2

+ +

Then the link you’ll need is:

+ +

https://raw.githubusercontent.com/rsms/inter/master/docs/font-files/Inter-Regular.woff2

+ +

Which follows the pattern:

+ +
raw.githubusercontent.com/${user}/${repo}/${branch}/${path}
+
+ +

Note that in the raw link, there is no /blob/ directory in the URL.

+ +

Supporting multiple languages

+ +

To support multiple character sets, for example both Latin and Cyrillic, you’ll need to merge font files.

+ +

Customizing the font for individual embedded items

+ +

In addition to the included fonts, if you set a custom font for your Metabase, that font will be selectable from “Use instance font” in static embeds.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/AccountSetup.png b/_site/docs/doc-update-detection/configuring-metabase/images/AccountSetup.png new file mode 100644 index 000000000..1c693d756 Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/AccountSetup.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/AddDatabaseInfo.png b/_site/docs/doc-update-detection/configuring-metabase/images/AddDatabaseInfo.png new file mode 100644 index 000000000..e0df8533b Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/AddDatabaseInfo.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/EmailCredentials.png b/_site/docs/doc-update-detection/configuring-metabase/images/EmailCredentials.png new file mode 100644 index 000000000..78f461c2d Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/EmailCredentials.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/MapSettings.png b/_site/docs/doc-update-detection/configuring-metabase/images/MapSettings.png new file mode 100644 index 000000000..f97424ecd Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/MapSettings.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/NewsletterSignup.png b/_site/docs/doc-update-detection/configuring-metabase/images/NewsletterSignup.png new file mode 100644 index 000000000..f5e74b7f2 Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/NewsletterSignup.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/UsageData.png b/_site/docs/doc-update-detection/configuring-metabase/images/UsageData.png new file mode 100644 index 000000000..194506cf2 Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/UsageData.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/WelcomeScreen.png b/_site/docs/doc-update-detection/configuring-metabase/images/WelcomeScreen.png new file mode 100644 index 000000000..a269a92f9 Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/WelcomeScreen.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/chart-colors.png b/_site/docs/doc-update-detection/configuring-metabase/images/chart-colors.png new file mode 100644 index 000000000..bf7b6f6c0 Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/chart-colors.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/custom-geojson.png b/_site/docs/doc-update-detection/configuring-metabase/images/custom-geojson.png new file mode 100644 index 000000000..1472f75d6 Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/custom-geojson.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/data-caching-settings.png b/_site/docs/doc-update-detection/configuring-metabase/images/data-caching-settings.png new file mode 100644 index 000000000..a4ae2aecc Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/data-caching-settings.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/lighthouse-illustration.png b/_site/docs/doc-update-detection/configuring-metabase/images/lighthouse-illustration.png new file mode 100644 index 000000000..16e2e8ecb Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/lighthouse-illustration.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/login-page.png b/_site/docs/doc-update-detection/configuring-metabase/images/login-page.png new file mode 100644 index 000000000..116fe590b Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/login-page.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/metabot-greeting.png b/_site/docs/doc-update-detection/configuring-metabase/images/metabot-greeting.png new file mode 100644 index 000000000..d8834ac09 Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/metabot-greeting.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/payload-chart.png b/_site/docs/doc-update-detection/configuring-metabase/images/payload-chart.png new file mode 100644 index 000000000..3973a2ddb Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/payload-chart.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/sailboat.png b/_site/docs/doc-update-detection/configuring-metabase/images/sailboat.png new file mode 100644 index 000000000..55cb45969 Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/sailboat.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/table-view.png b/_site/docs/doc-update-detection/configuring-metabase/images/table-view.png new file mode 100644 index 000000000..29d8631b4 Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/table-view.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/user-interface-colors.png b/_site/docs/doc-update-detection/configuring-metabase/images/user-interface-colors.png new file mode 100644 index 000000000..f6dddca80 Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/user-interface-colors.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/images/what-will-you-use-metabase-for.png b/_site/docs/doc-update-detection/configuring-metabase/images/what-will-you-use-metabase-for.png new file mode 100644 index 000000000..a37d5ab86 Binary files /dev/null and b/_site/docs/doc-update-detection/configuring-metabase/images/what-will-you-use-metabase-for.png differ diff --git a/_site/docs/doc-update-detection/configuring-metabase/localization.html b/_site/docs/doc-update-detection/configuring-metabase/localization.html new file mode 100644 index 000000000..e81e73434 --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/localization.html @@ -0,0 +1,3303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Languages and localization | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Languages and localization

+ +

The Localization settings allow you to set global defaults for your Metabase instance. You can find Localization under Admin settings > Settings.

+ +

Default language

+ +

Here you can set the default language (also called the “instance language”) across your Metabase UI, system emails, dashboard subscriptions, and alerts. People can pick a different language from their own account settings.

+ +

Supported languages

+ +

Thanks to our amazing user community, Metabase has been translated into many different languages. Due to the way we collect translations, languages may be added or removed during major releases depending on translation coverage.

+ +

Supported languages include:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LanguageCode
Englishen
Albaniansq
Arabicar
Arabic (Saudi Arabia)ar-SA
Bulgarianbg
Catalanca
Chinese (Traditional)zh
Chinese (Taiwanese)zh-TW
Chinese (Hong Kong)zh-HK
Chinese (Simplified)zh-CN
Czechcs
Dutchnl
Farsi/Persianfa
Finnishfi
Frenchfr
Germande
Hebrewhe
Hungarianhu
Indonesianid
Malayms
Italianit
Japaneseja
Koreanko
Latvianlv
Norwegian Bokmålnb
Polishpl
Portuguese (Brazilian)pt-BR
Russianru
Serbiansr
Slovaksk
Spanishes
Swedishsv
Turkishtr
Ukrainianuk
Vietnamesevi
+ +

The locale codes are relevant for setting the language in static embeds.

+ +
+

While Metabase can support languages that read right to left, the Metabase UI is designed around languages that read left to right.

+
+ +

Translations

+ +

Our community contributes to Metabase translations on our Crowdin project. If you’d like to help make Metabase available in a language you’re fluent in, we’d love your help!

+ +

For a new language to be added to Metabase, it must reach 100%. Once it does, we add it in the next major or minor release of Metabase. All existing languages in Metabase must stay at 100% to continue being included in the next major version of Metabase. This rule ensures that no one encounters a confusing mishmash of English and another language when using Metabase.

+ +

We understand that this is a high bar, so we commit to making sure that before each major release, any additions or changes to text in the product are completed at least 10 calendar days before the release ships, at which point we notify all translators that a new release will be happening soon.

+ +

Note that while we only remove languages in major releases, we are happy to add them back for minor releases, so it’s always a good time to jump in and start translating.

+ +

Report timezone

+ +

Use report timezone to set a default display time zone for dates and times in Metabase. The report timezone setting is a display setting only, so changing the report timezone won’t affect the time zone of any data in your database.

+ +

Report timezone doesn’t apply to timestamp without time zone data types, including the output of convertTimezone expressions. For example:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Raw timestamp in your databaseData typeReport time zoneDisplayed as
2022-12-28T12:00:00 AT TIME ZONE 'CST'timestamp with time zone‘Canada/Eastern’Dec 28, 2022, 7:00 AM
2022-12-28T12:00:00-06:00timestamp with offset‘Canada/Eastern’Dec 28, 2022, 7:00 AM
2022-12-28T12:00:00timestamp without time zone‘Canada/Eastern’Dec 28, 2022, 12:00 AM
+ +

Report timezone is only supported for the following databases:

+ +
    +
  • BigQuery
  • +
  • Druid
  • +
  • MySQL
  • +
  • Oracle
  • +
  • PostgreSQL
  • +
  • Presto
  • +
  • Redshift
  • +
  • Vertica
  • +
+ +

First day of the week

+ +

If you need to, you can change the first day of the week for your instance (the default is Sunday). Setting the first day of the week affects things like grouping by week and filtering in questions built using the query builder. This setting doesn’t affect SQL queries.

+ +

Localization options

+ +

Localization options allow you to set global default display formats for dates, times, numbers, and currencies.

+ +

You can also override these localization options for specific fields or questions. For more info, see Formatting.

+ +

Dates and times

+ +
    +
  • Date style: the way dates should be displayed in tables, axis labels, and tooltips.
  • +
  • Date separators: you can choose between slashes (2022/12/14), dashes (2022-12-14), and dots (2022.12.14.).
  • +
  • Abbreviate names of days and months: whenever a date is displayed with the day of the week and/or the month written out, turning this setting on will display e.g. “January” as “Jan” or “Monday” as “Mon”.
  • +
  • Time style: choose to display the time using either a 12 or 24-hour clock (e.g., 3:00 PM or 15:00).
  • +
+ +

Numbers

+ +
    +
  • Separator style: some people use commas to separate thousands places, and others use periods. Here’s where you can indicate which camp you belong to.
  • +
+ +

Currency

+ +
    +
  • Unit of currency: if you do most of your business in a particular currency, you can specify that here.
  • +
  • Currency label style: whether you want to have your currencies labeled with a symbol, a code (like “USD”), or its full name.
  • +
  • Where to display the unit of currency: this pertains specifically to tables, and lets you choose if you want the currency labels to appear only in the column heading, or next to each value in the column.
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+ + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/log-configuration.html b/_site/docs/doc-update-detection/configuring-metabase/log-configuration.html new file mode 100644 index 000000000..8095854a7 --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/log-configuration.html @@ -0,0 +1,3099 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Metabase logs | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Metabase logs

+ +

Metabase logs quite a bit of information by default. It uses Log4j 2 under the hood, so you can configure how much information Metabase logs.

+ +

Configuring Logging Level

+ +

Here is Metabase’s default logging configuration. You can override this XML file and tell Metabase to use your own logging configuration file by passing a -Dlog4j.configurationFile argument when running Metabase. For example, if your custom XML file is found in /path/to/custom/log4j2.xml, you can use it like so:

+ +
java -Dlog4j.configurationFile=file:/path/to/custom/log4j2.xml -jar metabase.jar
+
+ +

To get started customizing the logs, make a copy of the default log4j2.xml file and adjust it to meet your needs. You’ll need to restart Metabase for changes to the file to take effect. See Log4j’s docs for info on log levels.

+ +

You can set different log levels for different areas of the application, e.g.,:

+ +
<Loggers>
+    <Logger name="metabase" level="INFO"/>
+    <Logger name="metabase-enterprise" level="INFO"/>
+    <Logger name="metabase.plugins" level="DEBUG"/>
+    <Logger name="metabase.server.middleware" level="DEBUG"/>
+    <Logger name="com.mchange" level="ERROR"/>
+
+    <!-- Example: Add trace logging to the Metabase analysis process, which can help debugging trouble with syncing, fingerprinting and scanning -->
+    <Logger name="metabase.sync" level="TRACE"/>
+
+    <Root level="WARN">
+      <AppenderRef ref="STDOUT"/>
+    </Root>
+</Loggers>
+
+ +

Check out How to read the logs.

+ +

Jetty logs

+ +

You can configure Metabase’s web server to provide more detail in the logs by setting the log level to DEBUG. Just keep in mind that Jetty’s debug logs can be really chatty, which can make it difficult to find the data you’re looking for.

+ +

To get Jetty logs, add the following lines to the Log4J2 XML file in the node:

+ +
<Logger name="org.eclipse.jetty" level="DEBUG"/>
+
+ +

Using Log4j 2 with Docker

+ +

Before running the Metabase Docker image, you’ll need to pass the custom log4j.configurationFile argument. Add a JAVA_OPTS=-Dlog4j.configurationFile=file:/path/to/custom/log4j2.xml to the environment variables of the container, like this:

+ +
docker run -p 3000:3000 -v $PWD/my_log4j2.xml:/tmp/my_log4j2.xml -e JAVA_OPTS=-Dlog4j.configurationFile=file:/tmp/my_log4j2.xml metabase/metabase`
+
+ +

Disable emoji or colorized logging

+ +

By default Metabase will include emoji characters in logs. You can disable emoji by using the MB_EMOJI_IN_LOGS environment variable:

+ +

Configuring Emoji Logging

+ +
export MB_EMOJI_IN_LOGS="false"
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/setting-up-metabase.html b/_site/docs/doc-update-detection/configuring-metabase/setting-up-metabase.html new file mode 100644 index 000000000..5c1cc8b4a --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/setting-up-metabase.html @@ -0,0 +1,3131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Setting up Metabase | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Setting up Metabase

+ +

This guide will help you set up Metabase once you’ve gotten it installed. If you haven’t installed Metabase yet, you can get Metabase here.

+ +

Start Metabase up for the first time and you’ll see this screen: +Welcome Screen

+ +

Go ahead and click Let’s get started.

+ +

Setting up an admin account

+ +

The first thing you’ll need to do is set up an admin account. The account you create when you first install Metabase is an admin account by default — handy! If you’ve installed Metabase on a production server, you should be really careful to remember the password for this account since it will be used to add other users, connect to databases, set up email, and more. You can also create additional admin accounts later.

+ +

For now, let’s just create an account for ourselves to explore Metabase. Type in your info, and when you’re ready to continue, click the Next button.

+ +

Account Setup

+ +

What will you use Metabase for?

+ +

Let us know your plans with Metabase so that we can best guide you.

+ +

What will you use Metabase for?

+ +
    +
  • Self-service analytics for my own company
  • +
  • Embedding analytics into my application
  • +
  • A bit of both
  • +
  • Not sure yet
  • +
+ +

Don’t worry about picking the wrong option. If you say you’re interested in embedding, Metabase will display a card with a link to the embedding settings when you (the admin) first log in to your instance. Just a little convenience thing, that’s all.

+ +

Gathering your database info

+ +

At this point you’ll need to gather some information about the database you want to use with Metabase. We won’t be able to connect to your database without it, but you’d like to deal with all of this later, that’s okay: just click I’ll add my data later. Metabase comes with a Sample Database that you can play around with to get a feel for how Metabase works.

+ +

If you’re ready to connect, here’s what you’ll need:

+ +
    +
  • The hostname of the server where your database lives
  • +
  • The port the database server uses
  • +
  • The database name
  • +
  • The username you use for the database
  • +
  • The password you use for the database
  • +
+ +

If you don’t have this information handy, the person responsible for administering the database should have it.

+ +

Connect to your database

+ +

Now that you have your database info you can connect to your database. Sweet, sweet data at last. Just go ahead and put your info into this form and click Next.

+ +

adddatabase

+ +

For more on connecting to databases, see Adding and managing databases.

+ +

Activate your license

+ +

If you’re self-hosting Metabase on the Pro or Enterprise plan, Metabase will prompt you for your license. This step is just a convenience. You don’t need to enter your license here; you can activate your license at any time. Just know that all of your Pro and Enterprise features won’t work until you’ve activated your license.

+ +

If you’re running Pro on Metabase Cloud, we’ll handle this step for you. Your Pro features should already be available.

+ +

Usage data preferences

+ +

One last quick thing that you’ll have to decide is if it’s okay for us to collect some anonymous info about how you use the product — it helps us make Metabase better. Like the box says:

+ +
    +
  • Metabase never collects anything about your data or question results.
  • +
  • All collection is completely anonymous.
  • +
  • Collection can be turned off at any point in your admin settings.
  • +
+ +

Usage data preferences

+ +

If you’re ready to start using Metabase, go ahead and click Next.

+ +

Staying in touch

+ +

At this point you are all set and ready to use Metabase. Since we like keeping in touch with our friends we made it easy to sign up for our newsletter (infrequent emails) with a single click!

+ +

Metabase Newsletter

+ +

Once you’re done here simply follow the link to Take me to Metabase. And if you decided to skip the newsletter sign-up, it’s cool, we still like you :)

+ +

Getting started with Metabase

+ +

For a tutorial on getting up and running with questions and dashboards, head over to Learn Metabase.

+ +
+ +

If you’d like more technical resources to set up your data stack with Metabase, connect with a Metabase Expert.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/settings.html b/_site/docs/doc-update-detection/configuring-metabase/settings.html new file mode 100644 index 000000000..5280766e6 --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/settings.html @@ -0,0 +1,3112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +General settings | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

General settings

+ +

This section contains settings for your whole instance, like its URL, the reporting timezone, and toggles for disabling or enabling some of Metabase’s optional features.

+ +

You can configure these settings from Settings > Admin Settings > General.

+ +

Site name

+ +

How you’d like to refer to this instance of Metabase.

+ +

Site URL

+ +

The site URL is the web address that people use to access your Metabase instance. Make sure to include http:// or https:// to make sure it’s reachable. This feature is only available for self-hosted Metabases. For customers on Metabase Cloud, check out Custom domains.

+ +

Custom homepage

+ +

Admins can pick a dashboard to serve as the homepage. If people lack permissions to view the selected dashboard, Metabase will redirect them to the default homepage.

+ +

If you’ve set a dashboard as your homepage, and want to revert to the default Metabase homepage, simply turn off the Enabled toggle to disable the Custom Homepage feature.

+ +

Redirect to HTTPS

+ +

By default, Metabase is served over HTTP.

+ +

To force all traffic to use HTTPS via redirect, click http:// (under the Site URL section) and select https:// from the dropdown menu.

+ +

For example, say you enable HTTPS redirect for a Metabase instance at the site URL “example.com”. When someone enters an address like example.com/data in their browser’s address bar, they’ll get automatically redirected to a secure connection at https://example.com/data.

+ +
+

Note: if you haven’t set up HTTPS on your server, Metabase will not let you enable HTTPS redirect. Instead, you’ll get a warning saying “It looks like HTTPS is not properly configured.”

+
+ +

Email address for help requests

+ +

This email address will be displayed in various messages throughout Metabase when users encounter a scenario where they need assistance from an admin, such as a password reset request.

+ +

Anonymous tracking

+ +

This option turns determines whether or not you allow anonymous data about your usage of Metabase to be sent back to us to help us improve the product. Your database’s data is never tracked or sent.

+ +

Friendly table and field names

+ +

By default, Metabase attempts to make field and table names more readable by changing things like somehorriblename to Some Horrible Name. This does not work well for languages other than English, or for fields that have lots of abbreviations or codes in them. If you’d like to turn this setting off, you can do so from the Admin Panel under Settings > Admin settings > General.

+ +

If you re-enable this setting, Metabase will run a scan against your database to review your table and column names again.

+ +

To manually label field or table names in Metabase, check out the Table Metadata section in your admin settings. Metadata in the Table Metadata can be further curated in models.

+ +

Enable X-rays

+ +

X-rays are a great way for people to get quick summary stats on your data. If these X-ray queries get too slow or expensive, you can turn them off here.

+ +

Allowed domains for iframes in dashboards

+ +

Make sure you trust the sources that you allow people to embed in dashboards.

+ +

You can include multiple domains separated by a comma. Including a subdomain is more restrictive than including the domain.

+ +
    +
  • For Domains, (e.g., example.com), Metabase will allow any iframe from the domain (example.com) and its subdomains (e.g., data.example.com, docs.example.com, etc.).
  • +
  • For Subdomains (e.g., data.example.com) Metabase will restrict iframes to those subdomains. In this case, iframes must be from data.example.com (or any of the other allowed domains). Metabase will block iframes from all other subdomains, including example.com.
  • +
+ +

So if you included the following:

+ +
data.example.com,
+docs.example.com
+
+ +

Metabase would only allow iframes from data.example.com and docs.example.com. Metabase would block iframes from all other domains, including iframes from example.com and its other subdomains.

+ +

See iframes in dashboards.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/slack.html b/_site/docs/doc-update-detection/configuring-metabase/slack.html new file mode 100644 index 000000000..fe7376c05 --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/slack.html @@ -0,0 +1,3136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Set up Slack | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Set up Slack

+ +

If you want to have your dashboard subscriptions or alerts sent to Slack channels (or people on Slack), an admin must first integrate your Metabase with Slack.

+ +

Create your Slack App

+ +

For Metabase to post to your Slack channels, you’ll need to create a Slack App and make it available to Metabase.

+ +

From any Metabase page, go to Admin settings > Settings > Notification channels > Slack.

+ +

Click on Open Slack Apps. Metabase will open a new browser tab and send you over to the Slack website to create the Slack app.

+ +

On the Slack website, click Create an App.

+ +

Pick a workspace to develop your app

+ +

Select the workspace you want to create your app.

+ +

The app manifest

+ +

When you click on Open Slack App, Metabase will pass along the app manifest, which Slack will use to set up your app.

+ +

You may get a warning that says:

+ +

This app is created from a 3rd party manifest Always verify URLs and permissions below.

+ +

This warning is expected (Metabase is the third party here). You can click on Configure to see the app manifest Metabase sent along in the URL. Here is the manifest in YAML format:

+ +
_metadata:
+  major_version: 1
+  minor_version: 1
+display_information:
+  name: Metabase
+  description: Bringing the power of Metabase to your Slack #channels!
+  background_color: "#509EE3"
+features:
+  bot_user:
+    display_name: Metabase
+oauth_config:
+  scopes:
+    bot:
+      - users:read
+      - channels:read
+      - channels:join
+      - files:write
+      - chat:write
+      - chat:write.customize
+      - chat:write.public
+      - groups:read
+
+ +

The manifest just take cares of some settings for your app and helps speed things along.

+ +

Click the Next button. Then hit Create to set up your Slack app.

+ +

Install your app to your workspace

+ +

On the Slack site for your newly created app, in the Settings > Basic Information tab, under Install your app, click on Install to workspace. On the next screen, click Allow to give Metabase access to your Slack workspace.

+ +

The Bot User OAuth Token

+ +

On the Slack site page for your Slack app, on the left in the Features section, click on OAuth and Permissions in the Slack Apps sidebar and then copy the Bot User OAuth Token. Return to the Slack settings page in your Metabase and paste this token in the Metabase field with the same name.

+ +

Save your changes in Metabase

+ +

In Metabase, click on the Save changes button and that’s it! Metabase will automatically run a quick test to check that the API token is working properly. If something goes wrong, it’ll give you an error message.

+ +

Sending alerts and subscriptions to private Slack channels

+ +

In order to send subscriptions and alerts to private Slack channels, you must first add the Metabase app to the private channel.

+ +

In Slack, go to the private channel and mention the Metabase app. For example, if you called your Slack app “Metabase”, you’d just type @Metabase. Slack will ask you if you want to invite your app to your channel, which you should.

+ +

Metabase not listing your private channel?

+ +

It can take a little time for metabase to see all the channels the app has been invited to. New channels may not appear in listings for up to 10 minutes after inviting the app to the channel.

+ +

In order for metabase to see private channels, the app must have the groups:read oauth scope. Although this scope should be granted when setting up the app through metabase, older installations might not have this scope. +If you think this might be the case visit the app settings in slack:

+
    +
  • Click on the metabase app in the app listing.
  • +
  • Click on OAuth & Permissions in the sidebar.
  • +
  • Under Scopes add the groups:read scope.
  • +
  • The app will the need to be reinstalled to the workspace +by clicking the Reinstall button under OAuth Tokens.
  • +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/start.html b/_site/docs/doc-update-detection/configuring-metabase/start.html new file mode 100644 index 000000000..2b88c1582 --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/start.html @@ -0,0 +1,3101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Configuration overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Configuration overview

+ +

Setting up Metabase

+ +

A walkthrough of when you first boot up your Metabase.

+ +

General settings

+ +

Site name, report timezone, and more settings.

+ +

Email

+ +

Set up email for Alerts and Dashboard subscriptions.

+ +

Slack

+ +

Set up Slack for Alerts and Dashboard subscriptions.

+ +

Webhooks

+ +

Set up webhooks as notification channels for alerts.

+ +

Environment variables

+ +

Configure Metabase on launch via environment variables.

+ +

Configuration file

+ +

On self-hosted Pro and Enterprise plans, you can configure Metabase via a configuration file.

+ +

Metabase logs configuration

+ +

Tell Metabase what to log.

+ +

Timezones

+ +

Guidance on timezone settings.

+ +

Languages and localization

+ +

Set language, datetime, and currency settings.

+ +

Uploads

+ +

Allow people to upload data to collections.

+ +

Appearance

+ +

Customize colors, fonts, and other visual elements.

+ +

Caching query results

+ +

Cache query results for faster loading times.

+ +

Custom maps

+ +

Upload custom maps to your Metabase.

+ +

Customizing the Metabase Jetty webserver

+ +

Set SSL and port settings for the Jetty webserver.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/timezones.html b/_site/docs/doc-update-detection/configuring-metabase/timezones.html new file mode 100644 index 000000000..0082c7ee5 --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/timezones.html @@ -0,0 +1,3113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Timezones | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Timezones

+ +

Metabase does its best to ensure proper and accurate reporting in whatever timezone you want. But timezones are mysterious creatures.

+ +

Time zone settings

+ +

The following places where timezones are set can all impact the data you see:

+ +
    +
  • Database - includes global database timezone settings, specific column type settings, and even individual data values.
  • +
  • OS & JVM - on whatever system is running Metabase the timezone settings of the Operating System as well as the Java Virtual Machine can impact your reports.
  • +
  • Metabase - inside Metabase the reporting timezone setting (if set) will influence how your data is reported.
  • +
  • Metabase Cloud - the timezone on the server that hosts your Metabase Cloud instance.
  • +
+ + + +

To ensure proper reporting it’s important that timezones be set consistently in all places. Metabase recommends the following settings:

+ +
    +
  • Make sure all of your database columns are properly setup to include time zone awareness.
  • +
  • Unless you have a special need it’s best to set your database reporting time zone to UTC and store all of your date/time related values in UTC.
  • +
  • Configure your JVM to use the same timezone you want to use for reporting, which ideally should also match the timezone of your database.
  • +
  • Set the Metabase Report Timezone to match the timezone you want to see your reports in, again, this should match the rest of the timezone settings you’ve made.
  • +
  • If you want to change your Metabase Cloud timezone, please contact support.
  • +
+ +

Data types

+ +

You can make your database columns time zone aware by storing them as specific data types, such as:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeDescriptionExample
timestamp with time zoneKnows about location.2022-12-28T12:00:00 AT TIME ZONE 'America/Toronto'
timestamp with offsetKnows about the time difference from UTC.2022-12-28T12:00:00-04:00
timestamp without time zoneNo time zone info.2022-12-28T12:00:00
+ +

The exact data type will depend on your database. Some Metabase features only work with specific data types:

+ + + +

Common pitfalls

+ +
    +
  1. Your database is using date/time columns without any timezone information. Typically when this happens your database will assume all the data is from whatever timezone the database is configured in or possible just default to UTC (check your database vendor to be sure).
  2. +
  3. Your JVM timezone is different from your Metabase Report Timezone choice. This is a very common issue and can be corrected by launching java with the -Duser.timezone=<timezone> option properly set to match your Metabase report timezone.
  4. +
+ +

If you are still experiencing timezone problems, then have a look at the timezone troubleshooting guide.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/configuring-metabase/webhooks.html b/_site/docs/doc-update-detection/configuring-metabase/webhooks.html new file mode 100644 index 000000000..76f648f3c --- /dev/null +++ b/_site/docs/doc-update-detection/configuring-metabase/webhooks.html @@ -0,0 +1,3161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Webhooks | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Webhooks

+ +

Admins can set up webhooks so that people can send alerts to a particular URL. Which means you can set up an alert to send the results of a question to an endpoint of your choice: to your app, a third-party service, or wherever.

+ +

For now, webhooks are only available for alerts; you can’t select a webhook as the recipient of a dashboard subscription.

+ +

Creating a webhook

+ +

Before you can send an alert to a webhook, an admin will need to create a webhook to target.

+ +

Admins can create a webhook by clicking on the gear icon > Admin settings > Notification channels. In the Webhooks for alerts, click + Add another. Metabase will hand you a short form to fill out:

+ +
    +
  • Webhook URL. Where you want Metabase to send the results of an alert. Must be a valid URL.
  • +
  • Give it a name. You have to name the webhook so that people can pick the right hook when setting up an alert on a question.
  • +
  • Description. You should probably tell people what the hook is for.
  • +
  • Authentication method. See below.
  • +
+ +

Webhook authentication method

+ +

You can specify an auth method for the webhook.

+ +
    +
  • None: Anything goes.
  • +
  • Basic: Set a username and password.
  • +
  • Bearer: Include a secret token.
  • +
  • API key: You can add the API key to the Header or as a Query param. Both approaches require a key and value (the API key itself).
  • +
+ +

Webhook payload

+ +

Metabase will send the results of an alert in JSON. The JSON will include some metadata about the question, like the alert’s creator and its ID (null in the case of test alerts).

+ +

Metabase will send the “attached” visualization as a base64-encoded PNG in the data key, under visualization.

+ +

The encoded PNG chart

+ +

And the data as seen in the table view, which Metabase will send as a raw_data.

+ +

Results as table view

+ +

Here’s an example payload for an alert (we truncated the PNG encoding because it’s long and extremely boring):

+ +
{
+  "type": "alert",
+  "alert_id": null,
+  "alert_creator_id": 2666,
+  "alert_creator_name": "Roberto Bolaño",
+  "data": {
+    "type": "question",
+    "question_id": 108,
+    "question_name": "Sales",
+    "question_url": "http://example.com/question/108",
+    "visualization": "data:image/png;base64,=...LONG_ENCODED_PNG_HERE...",
+    "raw_data": {
+      "cols": [
+        "CREATED_AT",
+        "count"
+      ],
+      "rows": [
+        [
+          "2023-09-01T00:00:00Z",
+          346
+        ],
+        [
+          "2023-10-01T00:00:00Z",
+          354
+        ],
+        [
+          "2023-11-01T00:00:00Z",
+          394
+        ],
+        [
+          "2023-12-01T00:00:00Z",
+          418
+        ],
+        [
+          "2024-01-01T00:00:00Z",
+          457
+        ],
+        [
+          "2024-02-01T00:00:00Z",
+          404
+        ],
+        [
+          "2024-03-01T00:00:00Z",
+          445
+        ],
+        [
+          "2024-04-01T00:00:00Z",
+          439
+        ],
+        [
+          "2024-05-01T00:00:00Z",
+          520
+        ],
+        [
+          "2024-06-01T00:00:00Z",
+          455
+        ],
+        [
+          "2024-07-01T00:00:00Z",
+          523
+        ],
+        [
+          "2024-08-01T00:00:00Z",
+          501
+        ]
+      ]
+    }
+  },
+  "sent_at": "2024-09-30T20:16:15.76582Z"
+}
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/dashboards/actions.html b/_site/docs/doc-update-detection/dashboards/actions.html new file mode 100644 index 000000000..2ca4ce11b --- /dev/null +++ b/_site/docs/doc-update-detection/dashboards/actions.html @@ -0,0 +1,3103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Actions on dashboards | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Actions on dashboards

+ +

Dashboard with filter, action button, and detail card view

+ +

To put actions in action, you can combine them with a model and a filter on a dashboard.

+ +

Adding an action to a dashboard

+ +

Visit a dashboard page and click on the pencil icon, then click on the box with a mouse pointer to add an action.

+ +

Metabase will add an action button to the dashboard grid, and open a sidebar with the buttons settings.

+ +

Button text

+ +

A label explaining what the button does, e.g., “Ignition”.

+ +

Button variant

+ +

You can select from a variety of handsome buttons:

+ +
    +
  • Primary
  • +
  • Outline
  • +
  • Danger
  • +
  • Success
  • +
  • Borderless
  • +
+ +

Button types

+ +

Connecting an action to a dashboard filter

+ +

For most actions, when people click on a button, they’ll be prompted to input values in the fields defined by that action.

+ +

Many types of actions rely on knowing the Entity ID for the model to determine which records to update or delete. To have people select the ID for the action, you’ll need to:

+ +
    +
  1. Click on the pencil icon to edit the dashboard.
  2. +
  3. Add an action to the dashboard (if you haven’t already).
  4. +
  5. Add a filter to a dashboard, wire it up to any cards that you want to, and click Done in the bottom of the sidebar.
  6. +
  7. Hover over the action button and click on the gear icon, and select Change action.
  8. +
  9. Click on the field’s dropdown to select where the action should get it’s value. Here you can select “Ask the user” or have it automatically populated by a dashboard filter. In this case, we’ll select our “ID” filter.
  10. +
+ +

Wiring up an action button to a dashboard filter

+ +

If you also wire that filter up to a card with a model on the dashboard, you can filter for individual records in that model, view them in the model’s card, and have the action buttons auto-populate the id.

+ +

Button form

+ +

You can add as many buttons as you want, and wire them up to one or more filters.

+ +

Actions are unavailable for public dashboards and dashboards in static embeds

+ +

While you can add actions to dashboards and use them in your Metabase, actions won’t work on dashboards accessed via public links, or dashboards in static embeds.

+ +

If you want people outside of your Metabase to use an action, you can create a public form for an action, or expose actions via interactive embedding.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/dashboards/filters.html b/_site/docs/doc-update-detection/dashboards/filters.html new file mode 100644 index 000000000..8fb9ce6ae --- /dev/null +++ b/_site/docs/doc-update-detection/dashboards/filters.html @@ -0,0 +1,3350 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Dashboard filters | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Dashboard filters and parameters

+ +

Dashboard Filters

+ +

Have you ever found yourself in a situation where it seems like you need to create nearly identical copies of the same dashboard, with just one different variable? Maybe you have an Earnings dashboard, but you want to see the data for each city your business is in, or maybe you have a KPI dashboard that you want to see broken out by month.

+ +

Instead of creating duplicate dashboards, you can add filter or parameter widgets to let people change variables for cards on a dashboard.

+ +

Adding a filter or parameter

+ +

Add a Filter

+ + + +

Metabase will display the filter only if the filter is connected to a card on the current dashboard tab.

+ +

Filter and parameter types

+ +

The type of filter or parameter widget you choose will determine how the widget works, as well as which fields you’ll be able to filter your cards by.

+ +

Filter widgets

+ + + +

Parameter widgets

+ + + +

Date picker filters

+ +

When picking a Time filter, Metabase will prompt you to pick a specific type of date picker widget:

+ +
    +
  • Month and Year
  • +
  • Quarter and Year
  • +
  • Single Date
  • +
  • Date Range
  • +
  • Relative Date
  • +
  • All Options
  • +
+ +

Single Date and Date Range will provide a calendar widget, while the other options all provide slightly different dropdown interfaces for picking values. To get a widget that’s just like the time filter in the query builder, choose All options.

+ +

Time grouping parameter

+ +

Time grouping

+ +

You can add a time grouping widget to a dashboard to change how charts are grouped by time. For example, you may want to look at the time series charts grouped by month by default, but give people the option to view the results by other groupings: by week, by quarter, and so on.

+ +
+

Time grouping parameter widget can only be connected to questions built with the graphical query builder.

+
+ +

This widget doesn’t filter data in the charts; the widget just changes the time granularity for any cards that have a datetime field connected to the widget.

+ +

You can group by:

+ +
    +
  • Minute (or minute of hour)
  • +
  • Hour (or hour of day)
  • +
  • Day (or day of week, month, or year)
  • +
  • Week (or week of year)
  • +
  • Month (or month of year)
  • +
  • Quarter (or quarter of year)
  • +
  • Year
  • +
+ +

Location filters

+ +

There are four types of Location filters to choose from:

+ +
    +
  • City
  • +
  • State
  • +
  • ZIP or Postal Code
  • +
  • Country
  • +
+ +

ID filter

+ +

The ID filter provides a simple input box where you can type the ID of a user, order, etc.

+ +

Number filter

+ +

You can choose from:

+ +
    +
  • Equal to
  • +
  • Not equal to
  • +
  • Between
  • +
  • Greater than or equal to
  • +
  • Less than or equal to
  • +
+ +

Text or category filter

+ +

A flexible filter type that will let you create either a dropdown menu or an input box to filter on any category field in your cards. Options include:

+ +
    +
  • Is. Select one or more values from a list or search box. Use Is when you just want to plug a value into a variable. For multiple values, the card must be either a question built using the query builder, or a native/SQL question using a field filter.
  • +
  • Is not. Exclude one or more specific values.
  • +
  • Contains. Match values that contain the entered text.
  • +
  • Does not contain. Filter out values that contain the entered text.
  • +
  • Starts with. Match values that begin with the entered text.
  • +
  • Ends with. Match values that end with the entered text.
  • +
+ +

Connecting a filter or parameter widget to dashboard cards

+ +

Dashboard widgets apply across all dashboard tabs, though they’ll only be displayed when a tab has cards connected to the widget.

+ +

For each widget that you add, you’ll need to tell Metabase which column the filter should update for each card.

+ +

Click on a card’s dropdown menu to select the field that you want the widget to filter on.

+ +

Here we’ve wired up a Text filter to the “Event types” card, telling Metabase that the column to filter on should be the Analytics.Event.Button.Label field:

+ +

Wiring up a dashboard filter to a card

+ +

Auto-connecting filters to cards

+ +

If there are other cards that also have the field you select, Metabase will offer to automatically connect the filter to those cards too (including to relevant cards on other tabs). If you later add a card with the selected field, Metabase will also try to connect that filter to the new card.

+ +

To undo this auto-connecting of cards, click on the toast that pops up when Metabase auto-connects the cards, or manually disconnect the cards by clicking on the “X” next to the connected field.

+ +

Filtering dashboards with native/SQL questions

+ +

If you’re trying to connect a filter to a card with a native/SQL questions, you’ll need to add a variable or field filter to your query. For an in-depth article, check out Adding filters to dashboards with SQL questions.

+ +

You can’t connect a time grouping parameter widget to a card with a SQL question.

+ +

Wiring up dashboard filters to text cards

+ +

You can even wire up filters to text cards, but only if the text card includes a variable.

+ +

Requiring a filter or parameter

+ +

You can tell Metabase to require a filter so that people must filter the dashboard by a certain column on a card. If you require a filter, you’ll also need to supply a default value for that filter.

+ +

You might want to require a filter value if:

+ +
    +
  • Your unfiltered dashboard contains questions that pull lots of data, as enforcing filtered data can prevent people from inadvertently querying tons of data and running up your data warehouse costs.
  • +
  • The questions on your dashboard don’t make sense without a filter. For example, if you create a dashboard intended to view data relevant to a specific customer (as opposed to all customers), you can require a customer ID so that the dashboard only loads data for a particular customer.
  • +
+ +

Editing a filter

+ +

To edit a filter’s settings:

+ +
    +
  1. Click the pencil icon to enter dashboard editing mode.
  2. +
  3. Click the gear icon on the filter you want to edit.
  4. +
+ +

From this filter editing view, you can wire up dashboard cards to the filter, or use the filter settings sidebar to:

+ + + +

Rename filter

+ +
    +
  1. In dashboard edit mode, click your filter’s gear icon.
  2. +
  3. Change the label text.
  4. +
+ +

Renaming the filter only affects the filter’s display; the label has no effect on which columns Metabase filters.

+ +

Set filter input type

+ +
    +
  1. In dashboard edit mode, click your filter’s gear icon.
  2. +
  3. From the filter settings sidebar, set How should people filter on this column?:
  4. +
+ + + + + +

A list of all of the possible values in a column. People can use checkboxes to select more than one value on multi-select filters. You should choose the dropdown widget if you want the list of filter values to load instantly (from cache).

+ +

If you’re not seeing the Dropdown list option, and your dashboard filter is based on a column from a:

+ + + + + +

A search box that suggests a list of matching filter values as you type. The suggestion list will display checkboxes for multi-select filters.

+ +

The search box is a good choice for most columns containing labels, categories, statuses, and so on. It’s is the default filter widget for columns with less than 100 unique values.

+ +

Plain input box

+ +

An input box that lets people enter plain text (no suggestion list).

+ +

Useful for looking up partial matches (such as the “contains” filter) in columns that contain free text, such as comments or descriptions. The input box is the default filter widget for columns with more than 100 unique values.

+ +

Set a default filter value

+ +
    +
  1. In dashboard edit mode, click your filter’s gear icon.
  2. +
  3. From the sidebar, choose a value from the Default value input field.
  4. +
+ +

For example, you might want to set a default filter value like “Active”, so that when people load your dashboard, they only see data for “Active” records (not “Inactive”, “Cancelled”, etc).

+ +

Remove a filter

+ +
    +
  1. In dashboard edit mode, click your filter’s gear icon.
  2. +
  3. From the sidebar, click Remove.
  4. +
+ +

If you accidentally remove a filter, just click Cancel in the top-right to exit dashboard edit mode without saving your changes.

+ +

Reorder filters

+ +

In dashboard edit mode, click on the grabber handle (six dots) on the left side of a filter widget, then drag the widget to a different position.

+ +

Make a multi-select filter

+ +
    +
  1. In dashboard edit mode, click your filter’s gear icon.
  2. +
  3. From the sidebar, find People can pick and select “Multiple values”.
  4. +
+ +

A multi-select filter with the widget type Dropdown list or Search box will display a list of values with checkboxes.

+ +

Change a filter’s selectable values

+ +
    +
  1. In dashboard edit mode, click your filter’s gear icon.
  2. +
  3. From the sidebar, find How should users filter on this column?.
  4. +
  5. Select “Dropdown list”.*
  6. +
  7. Click Edit (to the right of “Dropdown list”) to specify where the values should come from: +
      +
    • From connected fields
    • +
    • From another model or question
    • +
    • Custom list
    • +
    +
  8. +
+ +

Selectable values

+ +

* If you don’t see “Dropdown list” as an option, go to Filter widgets: Dropdown list for more info.

+ +

Linking filters

+ +

See Linked filters.

+ +

Auto-apply filters

+ +

By default, each time you change the value in a filter on a dashboard, the dashboard will refresh to get the results of each card with that new filter value applied.

+ +

If a dashboard is particularly large or slow, or you have multiple filters that you want to adjust before the dashboard refreshes its results, you may want to tell Metabase when to apply those filters and refresh the dashboard.

+ +

To turn off the automatic application of filters, click on the info i icon, and toggle the Auto-apply filters option. With auto-apply turned off, each time you change a value in a filter, you’ll need to click the Apply button to refresh the dashboard with the new filter value.

+ +

Click Apply to apply the filters and refresh the dashboard

+ +

Using filter widgets

+ +

Once you’ve added a filter to your dashboard, just click on the filter widget to select a value and activate the filter. To stop filtering, just click the blue X.

+ +

Your active filter will only apply to your view of the dashboard. If someone else is viewing the same dashboard link at the same time, they won’t see your filter.

+ +

Using a filter

+ +

You can also set up a dashboard question to update a filter on click.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/dashboards/images/add-filter.png b/_site/docs/doc-update-detection/dashboards/images/add-filter.png new file mode 100644 index 000000000..460ab1466 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/add-filter.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/add-section.png b/_site/docs/doc-update-detection/dashboards/images/add-section.png new file mode 100644 index 000000000..c367bdf42 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/add-section.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/add_series.png b/_site/docs/doc-update-detection/dashboards/images/add_series.png new file mode 100644 index 000000000..625512ea9 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/add_series.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/add_values.png b/_site/docs/doc-update-detection/dashboards/images/add_values.png new file mode 100644 index 000000000..2ce7ba3ee Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/add_values.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/apply-button.png b/_site/docs/doc-update-detection/dashboards/images/apply-button.png new file mode 100644 index 000000000..57030f9a8 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/apply-button.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/autorefresh.png b/_site/docs/doc-update-detection/dashboards/images/autorefresh.png new file mode 100644 index 000000000..544a780f7 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/autorefresh.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/button-form.png b/_site/docs/doc-update-detection/dashboards/images/button-form.png new file mode 100644 index 000000000..af2cda3fa Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/button-form.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/buttons.png b/_site/docs/doc-update-detection/dashboards/images/buttons.png new file mode 100644 index 000000000..3c5c347b2 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/buttons.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/click-behavior-icon.png b/_site/docs/doc-update-detection/dashboards/images/click-behavior-icon.png new file mode 100644 index 000000000..c5a59d832 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/click-behavior-icon.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/click-behavior-menu.png b/_site/docs/doc-update-detection/dashboards/images/click-behavior-menu.png new file mode 100644 index 000000000..259440e37 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/click-behavior-menu.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/cross-filter.png b/_site/docs/doc-update-detection/dashboards/images/cross-filter.png new file mode 100644 index 000000000..6a0ff1847 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/cross-filter.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/custom-destination.png b/_site/docs/doc-update-detection/dashboards/images/custom-destination.png new file mode 100644 index 000000000..bbe86017e Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/custom-destination.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/dark-mode.png b/_site/docs/doc-update-detection/dashboards/images/dark-mode.png new file mode 100644 index 000000000..9a8b84c91 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/dark-mode.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/dashboard-filter-action.png b/_site/docs/doc-update-detection/dashboards/images/dashboard-filter-action.png new file mode 100644 index 000000000..d18c28a9f Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/dashboard-filter-action.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/dashboard-tabs.png b/_site/docs/doc-update-detection/dashboards/images/dashboard-tabs.png new file mode 100644 index 000000000..74f962ab8 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/dashboard-tabs.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/dashboard-with-iframe.png b/_site/docs/doc-update-detection/dashboards/images/dashboard-with-iframe.png new file mode 100644 index 000000000..e92179246 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/dashboard-with-iframe.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/dashboard-with-link-cards.png b/_site/docs/doc-update-detection/dashboards/images/dashboard-with-link-cards.png new file mode 100644 index 000000000..f23ecd9a4 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/dashboard-with-link-cards.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/dashboard.png b/_site/docs/doc-update-detection/dashboards/images/dashboard.png new file mode 100644 index 000000000..98ce0a0ae Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/dashboard.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/drill-through-menu.png b/_site/docs/doc-update-detection/dashboards/images/drill-through-menu.png new file mode 100644 index 000000000..292efcbbe Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/drill-through-menu.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/duplicate-card.png b/_site/docs/doc-update-detection/dashboards/images/duplicate-card.png new file mode 100644 index 000000000..ccb0d7172 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/duplicate-card.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/edit_modal.png b/_site/docs/doc-update-detection/dashboards/images/edit_modal.png new file mode 100644 index 000000000..0acb0962e Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/edit_modal.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/edit_modal_multi-series.png b/_site/docs/doc-update-detection/dashboards/images/edit_modal_multi-series.png new file mode 100644 index 000000000..3959bf0a3 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/edit_modal_multi-series.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/email-options.png b/_site/docs/doc-update-detection/dashboards/images/email-options.png new file mode 100644 index 000000000..53172b9f8 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/email-options.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/email-or-slack.png b/_site/docs/doc-update-detection/dashboards/images/email-or-slack.png new file mode 100644 index 000000000..ea6e77087 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/email-or-slack.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/enter-a-url.png b/_site/docs/doc-update-detection/dashboards/images/enter-a-url.png new file mode 100644 index 000000000..68fe5a239 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/enter-a-url.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/field-values-linked-filters.png b/_site/docs/doc-update-detection/dashboards/images/field-values-linked-filters.png new file mode 100644 index 000000000..7121af8bb Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/field-values-linked-filters.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/filters.png b/_site/docs/doc-update-detection/dashboards/images/filters.png new file mode 100644 index 000000000..7045deead Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/filters.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/foreign-key-linked-filters.png b/_site/docs/doc-update-detection/dashboards/images/foreign-key-linked-filters.png new file mode 100644 index 000000000..686671f73 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/foreign-key-linked-filters.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/id-value.png b/_site/docs/doc-update-detection/dashboards/images/id-value.png new file mode 100644 index 000000000..aeb81fd7c Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/id-value.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/interactive-dashboard.png b/_site/docs/doc-update-detection/dashboards/images/interactive-dashboard.png new file mode 100644 index 000000000..2ea88ff04 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/interactive-dashboard.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/kpi-grid.png b/_site/docs/doc-update-detection/dashboards/images/kpi-grid.png new file mode 100644 index 000000000..f5d97658f Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/kpi-grid.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/kpis-with-large-chart-below.png b/_site/docs/doc-update-detection/dashboards/images/kpis-with-large-chart-below.png new file mode 100644 index 000000000..25dba58f7 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/kpis-with-large-chart-below.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/large-chart-with-kpis-to-the-right.png b/_site/docs/doc-update-detection/dashboards/images/large-chart-with-kpis-to-the-right.png new file mode 100644 index 000000000..272901fc1 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/large-chart-with-kpis-to-the-right.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/linked-filter.png b/_site/docs/doc-update-detection/dashboards/images/linked-filter.png new file mode 100644 index 000000000..61c8c35c5 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/linked-filter.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/markdown.png b/_site/docs/doc-update-detection/dashboards/images/markdown.png new file mode 100644 index 000000000..7e0049500 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/markdown.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/multi-series_query_builder.png b/_site/docs/doc-update-detection/dashboards/images/multi-series_query_builder.png new file mode 100644 index 000000000..ae5f0e713 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/multi-series_query_builder.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/notebook_editor_multi-series.png b/_site/docs/doc-update-detection/dashboards/images/notebook_editor_multi-series.png new file mode 100644 index 000000000..3afa5c307 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/notebook_editor_multi-series.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/numbers_to_bar_chart.png b/_site/docs/doc-update-detection/dashboards/images/numbers_to_bar_chart.png new file mode 100644 index 000000000..ff6686c6d Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/numbers_to_bar_chart.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/pass-category-to-filter.png b/_site/docs/doc-update-detection/dashboards/images/pass-category-to-filter.png new file mode 100644 index 000000000..96f7e4daa Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/pass-category-to-filter.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/pass-value.png b/_site/docs/doc-update-detection/dashboards/images/pass-value.png new file mode 100644 index 000000000..19d1856c2 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/pass-value.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/result.png b/_site/docs/doc-update-detection/dashboards/images/result.png new file mode 100644 index 000000000..fd34bbc1b Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/result.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/selectable-values.png b/_site/docs/doc-update-detection/dashboards/images/selectable-values.png new file mode 100644 index 000000000..d27e5a5eb Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/selectable-values.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/set-filter-values.png b/_site/docs/doc-update-detection/dashboards/images/set-filter-values.png new file mode 100644 index 000000000..633b380d9 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/set-filter-values.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/share-icon.png b/_site/docs/doc-update-detection/dashboards/images/share-icon.png new file mode 100644 index 000000000..04b70a09e Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/share-icon.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/slack-subscription-options.png b/_site/docs/doc-update-detection/dashboards/images/slack-subscription-options.png new file mode 100644 index 000000000..37d3b51d7 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/slack-subscription-options.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/text-card-button.png b/_site/docs/doc-update-detection/dashboards/images/text-card-button.png new file mode 100644 index 000000000..9b7d8e28a Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/text-card-button.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/time-grouping.png b/_site/docs/doc-update-detection/dashboards/images/time-grouping.png new file mode 100644 index 000000000..4de5638ef Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/time-grouping.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/toggle-width.png b/_site/docs/doc-update-detection/dashboards/images/toggle-width.png new file mode 100644 index 000000000..084a9fd34 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/toggle-width.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/update-a-dashboard-filter.png b/_site/docs/doc-update-detection/dashboards/images/update-a-dashboard-filter.png new file mode 100644 index 000000000..57dabebe6 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/update-a-dashboard-filter.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/use-filter.png b/_site/docs/doc-update-detection/dashboards/images/use-filter.png new file mode 100644 index 000000000..e8c930d17 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/use-filter.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/visualization-settings.png b/_site/docs/doc-update-detection/dashboards/images/visualization-settings.png new file mode 100644 index 000000000..160328747 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/visualization-settings.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/wiring-cards.png b/_site/docs/doc-update-detection/dashboards/images/wiring-cards.png new file mode 100644 index 000000000..c00ed7652 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/wiring-cards.png differ diff --git a/_site/docs/doc-update-detection/dashboards/images/wiring-up-filter.png b/_site/docs/doc-update-detection/dashboards/images/wiring-up-filter.png new file mode 100644 index 000000000..efe1e7d45 Binary files /dev/null and b/_site/docs/doc-update-detection/dashboards/images/wiring-up-filter.png differ diff --git a/_site/docs/doc-update-detection/dashboards/interactive.html b/_site/docs/doc-update-detection/dashboards/interactive.html new file mode 100644 index 000000000..f7776f0df --- /dev/null +++ b/_site/docs/doc-update-detection/dashboards/interactive.html @@ -0,0 +1,3174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Dashboard interactivity | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Dashboard interactivity

+ +

You can customize what happens when people click on questions in your dashboard.

+ +

By default, when you create charts using Metabase’s graphical query builder, your charts automatically come with drill-through capabilities, which let folks click on a chart to explore further. But if you have a more customized click path in mind, Metabase allows you to customize what happens when a user clicks on a chart or table in your dashboard.

+ +

You can set up a dashboard card to:

+ + + +

To configure this interactivity, you’ll use the click behavior option on a dashboard card.

+ +

Customizing click behavior

+ +

From your dashboard, first click on the pencil icon to enter dashboard edit mode.

+ +

If you hover over the card that contains question you want to customize, Metabase will display a menu at the top right of that card containing these options, from left to right:

+ +
    +
  • Visualization options: This icon looks like a painter’s palette.
  • +
  • Click behavior: This is the icon with the mouse cursor clicking on a card.
  • +
  • Add series: If your question has a visualization to which you can add an additional series (like a line or bar chart), you’ll see this icon as a + next to a small representation of that chart type. Not all cards will show this option.
  • +
  • Remove: This icon is an X. Selecting this will remove your question from the dashboard.
  • +
+ +

Select the Click behavior option.

+ +

Click behavior icon

+ +

Metabase will slide out the Click behavior sidebar:

+ +

Click behavior menu

+ +

For questions composed using the query builder, you can select from three options:

+ +
    +
  • Open the Metabase drill-through menu.
  • +
  • Go to a custom destination.
  • +
  • Update a dashboard filter (if the dashboard has a filter).
  • +
+ +

SQL questions will only have the option to Go to a custom destination, and Update a dashboard filter.

+ +

If your dashboard has a filter, you’ll also see an option to update the filter.

+ +

Open the drill-through menu

+ +

For questions composed using the query builder, the default click behavior is to open the drill-through menu, which presents people with the option to drill through the data:

+ +

Drill-through menu

+ +

Custom destinations

+ +

You can set custom destinations for all questions, including SQL questions.

+ +

Custom destinations

+ +

Possible destinations include:

+ +
    +
  • Dashboards
  • +
  • Saved questions
  • +
  • URLs
  • +
+ +

Internal Metabase destinations (dashboards or saved questions) will load in the same browser tab or window. External URLs will open in a new tab or window.

+ +

Passing values to the destination

+ +

If you’re linking to a dashboard or a SQL question that has filters, you can pass values from the current dashboard to filters in the destination.

+ +

For example, if you link to a dashboard that has a filter for Category, you can pass a value for Category from the origin question to the destination dashboard:

+ +

Pass value to dashboard

+ +

Once you select the column that contains the value you want to pass, the sidebar will display the column used to pass the value, as well as the target filter at the destination that Metabase will pass the value to:

+ +

Pass category to filter

+ +

In the example above, when a user clicks on the Orders by product category card, Metabase will pass the clicked Product -> Category to the destination dashboard (“Interactive Dashboard”), which will then filter its cards by that Category.

+ +

You can also send the currently selected value of a dashboard filter on the current dashboard to the destination. In some plans, you can pass a user attribute provided by SSO to the destination, too. Those user attributes will show up as options when you click on one of the destination’s filters (provided the values are compatible with that filter).

+ +

When displaying questions as tables, you can select different click behaviors for different columns in the table. You can also modify the contents of the cells in a given column, replacing the value with custom text. For example, if you had a column that listed categories, you could change the text in the cell to read: “Click for details about {{Category}}”, where Category is the name of your column.

+ +

You can also use values to construct URLs to external resources.

+ +

Enter a URL

+ +

From the Click behavior sidebar, select Go to a custom destination and link to URL. The Enter a URL to link to modal will pop up, allowing you to specify a URL, as well as a column or dashboard filter.

+ +

What we need to do here is to type in the full URL of where a user should go when they click on a value in a card. But the really powerful thing we can do is to include variables in the URL. These variables will insert the value that the user clicks on into the URL.

+ +

For example, we could type a URL like this:

+ +
https://www.metabase.com/search.html?query={{Category}}
+
+ +

The important part is the {{Category}} bit. What we’re doing here is referring to the Category that the user clicked on. So if someone clicks on the Widget bar in our chart, the value of the Category column for that bar (Widget) would be inserted into our URL: https://www.metabase.com/search.html?query=Widget. Your URL can use as many column variables as you want - you can even refer to the same column multiple times in different parts of the URL. To see which variables you can include in the URL, click on the dropdown menu Values you can reference.

+ +

Next we’ll click Done, then Save our dashboard. Now when we click our chart, we’ll be taken to the URL that we entered above, with the value of the clicked bar inserted into the URL.

+ +

To learn more, check out Custom destinations: choose what happens when people click on charts in your dashboard.

+ +

Use a chart to filter a dashboard

+ +

If your dashboard contains at least one filter, you can set things up so that clicking on a chart in the dashboard will update a filter.

+ +

When a user clicks on, say, a bar in a bar chart, you could send the value of the clicked bar to the filter, and update cards across the dashboard. We call this functionality cross-filtering. You can use this cross-filtering to make a chart behave as kind of “navigation question” that filters data across other cards.

+ +

For example, clicking on the Widget bar will update the current dashboard’s category filter to filter for Widget:

+ +

Cross-filtering

+ +

To set up cross-filtering, choose a dashboard filter that you’d like to update on click, and a question to use to update that filter. You can think of this question as your “navigation question.” Instead of wiring this navigation question up to the filter, you’ll wire up every other question on the dashboard to the filter.

+ +

Below, we’ll use the Orders by product category question as our navigation question, so we’ll leave this question disconnected from the filter, and connect all the other questions to the Category filter.

+ +

Wiring up filter

+ +

With your filter wired up, stay in dashboard edit mode, and hover over the question you want to use as your navigation question to filter the dashboard. Click on the click behavior icon, then select the Update a dashboard filter.

+ +

Metabase will list the filters you can update. Here we select the Category filter, and supply the value to that filter from the question’s Product -> Category column.

+ +

Update a dashboard filter

+ +

Click Done in the sidebar, then Save your dashboard.

+ +

Now we can use our navigation question (Orders by product category) to interactively filter the data across your dashboard. When people click on a value in the navigation question, Metabase will send the clicked value to the filter, and update every card on the dashboard by filtering them for the clicked value - every card except for the navigation question: Orders by product category. The reason we don’t want the navigation question to update is so that we can click on other bars to update the filter with a different value.

+ +

To learn more, check out Cross-filtering: using a chart to update a dashboard filter.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/dashboards/introduction.html b/_site/docs/doc-update-detection/dashboards/introduction.html new file mode 100644 index 000000000..558147bed --- /dev/null +++ b/_site/docs/doc-update-detection/dashboards/introduction.html @@ -0,0 +1,3411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Introduction to dashboards | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Introduction to dashboards

+ +

Interactive dashboard

+ +

What is a dashboard?

+ +

Dashboards group a set of questions into tabs on a single page. You can think of dashboards as shareable reports that feature a set of related questions. You can set up subscriptions to dashboards via email or Slack to receive the exported results of the dashboard’s questions.

+ +

A dashboard comprises a set of cards arranged on a grid. These cards can be:

+ + + +

You can add filter widgets to dashboards that filter data identically across multiple questions, and customize what happens when people click on a chart or a table.

+ +

You can make as many dashboards as you want. Go nuts.

+ +

How to create a dashboard

+ +

In the top right of the screen, click the + New > Dashboard. Give your new dashboard a name and a description, choose which collections the dashboard should go in, then click Create, and Metabase will take you to your shiny new dashboard.

+ +

Adding or saving questions to a dashboard

+ +

You can add questions that are saved to collections, or save questions directly to a dashboard.

+ +

From a dashboard

+ +

When editing a dashboard, you can add a question by clicking the + icon in the top right. You can add a chart from a new question, SQL/native query, or an existing question.

+ +

You can’t add questions that are saved to other dashboards. If you want to add a question to multiple dashboards, you should save that question to a collection. Alternatively, if the questions don’t need to stay in sync, you could duplicate a question, and save that duplicate to your dashboard. Just keep in mind that changes to one question won’t affect the duplicate question.

+ +

From a question

+ +

When creating or editing a question, you can save the question directly to a dashboard. That question can only be used by that dashboard.

+ +

Adding a question saved to a collection

+ +

To add a question saved to a collection to a dashboard, visit the question and click on the three-dot menu () at the top right and select Add to dashboard. You can also browse questions from dashboard edit mode.

+ +

Adding a question to a dashboard does not save the question to the dashboard.

+ +

If a question is saved to your personal collection, you’ll only be able to add that question to dashboards in your personal collection. If you want to add the question to a dashboard in a public collection, you’ll need to move your question out of your personal collection.

+ +

Adding headings or descriptions with text cards

+ +

Another neat thing you can do is add heading and text cards to your dashboards. Text cards allow you to include descriptions, explanations, notes, or even images and GIFs to your dashboards. You can also use text cards to create separations between sections of charts in your dashboards, or include links to other dashboards, questions, or websites.

+ +

To add a new text card, create a new dashboard (or edit an existing one) and click on the text card button, T, in the top-right:

+ +

Text card button

+ +

You have two options:

+ +
    +
  • Heading: a preformatted heading text card that spans the width of the dashboard.
  • +
  • Text: a customizable text card that will render Markdown-formatted text.
  • +
+ +

Each text card has two modes: writing and previewing. When you click to focus on the card, the card will enter editing mode. When you click away from the card, Metabase will render the card to show you what it will look like on the live dashboard.

+ +

Markdown

+ +

You can use Markdown to format the text in your text card, create inline tables or code snippets, or even embed linked images (easy on the GIFs, friends). To preview the rendered card, just click away from the card.

+ +

Result

+ +

To learn more, see Fun with Markdown in your dashboards.

+ +

Including variables in text cards

+ +

You can include a variable in a text card, then wire that variable up to a dashboard filter. All you need to do to create a variable is to wrap a word in double braces, {{ and }} (the variable can’t contain any spaces). For example, you could add a text card with the following text:

+ +

+# {{state}} orders
+
+
+ +

And connect that variable to a dashboard filter widget that filters for states. If someone selected WI in the state filter, the text in the markdown card would read: WI orders.

+ +

You can also make text optional by wrapping the text in double brackets, [[ and ]]:

+ +

+# Orders [[from {{state}}]
+
+
+ +

In this case, the phrase from {{state}} would only display if someone selected a value (or values) in the filter widget.

+ +

To see how to wire up a filter to a card, see dashboard filters.

+ + + +

Dashboards with link cards

+ +

Link cards are specialized cards that let you search and link to other items in your Metabase. You can also use them for external links. Useful for pointing people to other resources relevant to your dashboard.

+ +

To add a link card to a dashboard, click the pencil icon to enter dashboard editing mode, then click on the link icon. Click on the input field in the link card to search your Metabase for an item to link to, or paste an external link.

+ +

Link cards support variables so you can use dashboard filters to update values in the link card’s URL. For example, you could include a variable in a URL using double braces, like so:

+ +

+https://www.example.com/{{path}}
+
+
+ +

To provide values for the variable, you’ll need to add a filter to the dashboard, and connect that filter to the card’s variable (in this case path). Parameters are only supported for non-Metabase URLs (that is, URLs that you manually enter, not URLs you search and select from your Metabase). You can optionally set a default value for the variable. See Connecting a filter or parameter widget to dashboard cards.

+ +

Iframe cards

+ +

Iframes allow you to nest one HTML page in another HTML page. With iframe cards in Metabase, you can embed a webpage in your dashboard. You can embed:

+ +
    +
  • Spreadsheets or surveys for data entry or workflows
  • +
  • Videos or slides for contextualizing and storytelling on dashboards
  • +
  • Live charts and visualizations from other tools
  • +
+ +

To add an iframe card to a dashboard, click the pencil icon to enter dashboard editing mode, then click on the link icon and select Iframe. Then paste the iframe URL. Here’s an iframe for our video on how to create a dashboard:

+ +
<iframe
+  width="560"
+  height="315"
+  src="https://www.youtube.com/embed/W-i9E5_Wjmw?si=qWeMGxEymVOIHiXo"
+  title="YouTube video player"
+  frameborder="0"
+  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
+  referrerpolicy="strict-origin-when-cross-origin"
+  allowfullscreen
+></iframe>
+
+ +

And behold, a dashboard with an embedded video:

+ +

Dashboard with iframe of video

+ +

Iframe cards support variables so that you can use a filter widget to update values in the iframe. For example, you could include a variable in the iframe’s src URL with double braces, like so:

+ +

+src="https://www.youtube.com/embed/{{video_id}}
+
+
+ +

To provide values for the variable, you’ll need to add a filter to the dashboard, and connect that filter to the card’s variable (in this case video_id). You can optionally set a default value for the variable. See Connecting a filter or parameter widget to dashboard cards.

+ +

Dashboard tabs

+ +

You can add multiple tabs to a dashboard to keep your cards organized.

+ +

Dashboard tabs

+ +

Duplicate a tab

+ +

When in dashboard edit mode, you can duplicate a tab and all the its cards by clicking on the down arrow next to the tab that you want to copy.

+ +

Moving cards between tabs

+ +

See Arranging cards.

+ +

Duplicating a dashboard

+ +

If you don’t want to build a dashboard from scratch, or want to experiment by making changes to an existing dashboard without affecting the original, you can duplicate an existing dashboard.

+ +

To duplicate a dashboard, click on the menu in the upper right of the dashboard, and select Duplicate.

+ +

By default, Metabase will create a new dashboard, with copies of the questions in the original dashboard (including the dashboard’s tabs). Metabase will save the duplicated questions either to the target collection, or to the duplicated dashboard, depending on where the original questions were saved.

+ +

Duplication only includes the dashboard, its card layout, filters, and (optionally) the questions. What’s not copied: dashboard subscriptions, actions, or any sharing or embedding data settings. For example, if you copy a dashboard that has been made public, that copied dashboard will not be public by default.

+ +

Arranging dashboard cards

+ +

To edit dashboard cards and move them around, click the pencil icon in the top right of a dashboard to enter the dashboard’s editing interface.

+ +

Editing cards

+ +

Once you’re in edit mode, you’ll see a grid appear. You can move and resize the cards in the dashboard to your liking and they’ll snap to the grid.

+ +

Editing dashboard

+ +
    +
  • Duplicate a card: hover over the card and click the Duplicate icon.
  • +
  • Move a card to a new tab: hover over the card, click the move icon, and select that tab you want to move the card to.
  • +
  • Move a card within a tab: click and drag the card. Other cards will move out of the way.
  • +
  • Resize a card: click the handle at the bottom right corner of the card, and drag to resize. Nearby cards will move away to accommodate the new size.
  • +
  • Remove a card: hover over the card and click the X icon in the top right corner.
  • +
  • Replace a card: hover over the card and click the Replace icon in the top right corner. Search for a question to swap in for the existing question on that card. You can only replace a question with another question, not another type of card (like a text card).
  • +
+ +

Metabase will automatically update a question’s display to make sure your data looks great at any size you choose.

+ +

Dashboard sections

+ +

To speed up card arrangement, you can add sections to your dashboards.

+ +

Add section

+ +

Sections are templates with headings and pre-arranged cards. Once you add a section to a dashboard, you can pick questions for each card, and make any other changes you like. You can only pick questions for cards, not another type of card (like a text card).

+ +

If you forget to set a question for a card, the dashboard will simply render a blank card.

+ +

Sections include:

+ +

KPI Grid

+ +

KPI Grid

+ +

Large chart with KPIs to the right

+ +

Large chart with KPIS to the right**

+ +

KPIs with large chart below

+ +

KPIs with large chart below

+ +

Dashboard width

+ +

You can change the width of a dashboard by going into the three dots menu in the upper right:

+ +

Change dashboard width

+ +
    +
  • Fixed width (default). Metabase will restrict the layout to a fixed width in the center of the screen. This fixed width can keep dashboard layouts consistent between smaller laptop screens and larger desktop screens.
  • +
  • Full width. The layout and cards will expand to take up the full width of the screen.
  • +
+ +

Changing a card’s visualization settings

+ +

You can change a card’s visualization settings (to add a goal line, for example). Changing a card’s visualization settings will only affect how the question appears on that dashboard card; these changes won’t affect the original question’s visualization settings.

+ +

Click on the pencil icon to enter dashboard edit mode, hover over the question you want to edit, and click on the palette icon to edit a card’s visualization’s settings.

+ +

Visualization settings

+ +

Hiding a card when it doesn’t return results

+ +

One neat thing to call out: if you have a question card that rarely returns results, but you still want to include that card in your dashboard because you want to know when the question does return results, you can tell Metabase to hide the card unless it returns at least one row of data.

+ +

When in dashboard edit mode, click on the Visualization settings for the card.

+ +
    +
  • If the card displays a table, the option is in the Columns tab.
  • +
  • If the card displays a chart, the option is in the Display tab.
  • +
+ +

Toggle the option Hide this card if there are no results. When you turn on this option, the query will still run in the background, but the dashboard won’t display the card. If the query returns results, the dashboard will display the card, moving the other cards around to make room for it according to how you’ve arranged the cards in dashboard edit mode.

+ +

Resetting a card’s visualization settings

+ +

If you want to revert a dashboard card to its original visualization settings (i.e., the settings on the question when it was first saved to your dashboard):

+ +
    +
  1. Go to your dashboard and click the pencil icon to go into edit mode.
  2. +
  3. Hover over the card (question) that you want to edit.
  4. +
  5. Click the palette icon to bring up the visualization settings for that card.
  6. +
  7. Click Reset to defaults.
  8. +
  9. Click Done to save the card’s visualization settings.
  10. +
  11. Click Save to save the dashboard.
  12. +
+ +

Fullscreen dashboards

+ +

After you’ve made your ideal dashboard, you may want to put the dashboard on a TV to help keep your team up to date throughout the day.

+ +

To enter fullscreen mode, click the fullscreen icon in the top right of the dashboard (the icon with the arrows pointing in opposite directions). Once you’ve entered fullscreen mode, you can also switch the dashboard into “Night mode” for higher contrast.

+ +

Night mode

+ +

Auto refresh

+ +

If your data updates frequently, you can set up your dashboard to refresh automatically by clicking on the clock icon.

+ +

Autorefresh

+ +

You can set your dashboard to update in 1, 5, 10, 15, 30, and 60 minute intervals, depending on how fresh you need the data to be.

+ +

Enabling auto refresh will re-run all the queries on the dashboard at the interval you choose, so keep the size of the dashboard and the complexity of the questions in mind when setting up auto refresh.

+ +

Combining fullscreen mode and auto refresh is a great way to keep your team in sync with your data throughout the day.

+ +

Caching dashboard results

+ +
+
+ + + + + + + +

Caching dashboard results is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

See Caching per dashboard.

+ + + +

If your Metabase administrator has enabled public sharing on a saved question or dashboard, you can go to that question or dashboard and click on the sharing icon to find its public links.

+ +

Share icon

+ +

Public links can be viewed by anyone, even if they don’t have access to Metabase. You can also use the public embedding code to embed your question or dashboard in a simple web page or blog post. Check out examples of simple apps with embedded dashboards in our embedding-reference-apps repository. To learn more about embedding, check out our article on How to use Metabase to deliver analytics to your customers, as well as an article on how to combine branding, Single Sign-On, full app embedding, and data sandboxing to deliver multi-tenant, self-service analytics.

+ +

Exporting results from a dashboard

+ +

See Exporting results.

+ +

Configuring a dashboard through its URL

+ +

You can amend the URL of a dashboard to automatically enter fullscreen, enable night mode, or auto-refresh the dashboard. Customizing the dashboard’s URL allows you to configure the dashboard - even when you do not have any input access to the device where the dashboard will be displayed, like scripted screens, for example.

+ +

To configure a dashboard using its URL, you can add the following optional keywords:

+ +
    +
  • fullscreen
  • +
  • night
  • +
  • refresh
  • +
+ +

Here’s an example URL:

+ +
https://metabase.mydomain.com/dash/2#refresh=60&fullscreen&night
+
+ +

The part that says refresh=60 sets the dashboard to automatically refresh every 60 seconds, fullscreen sets it to fullscreen mode, and night sets it to night mode (night mode only works when using fullscreen). Use an ampersand, &, in between keywords, and make sure there’s a hash, #, after the dashboard’s ID number.

+ +

There is one important limitation with the fullscreen option: for security reasons, many browsers require user interaction to initiate fullscreen. In those browsers, using the fullscreen option will enable the fullscreen UI in Metabase, but it won’t expand the browser content to fill the screen. To ensure the dashboard occupies the entire screen, either activate fullscreen by clicking the button in the UI, or use the fullscreen URL option and launch the browser in fullscreen or kiosk mode.

+ +

Dashboard version history

+ +

For questions, dashboards, and models, Metabase keeps a version history for the previous fifteen versions of that item.

+ +

See History.

+ +

Verifying a dashboard

+ +

See content verification.

+ +

Deleting a dashboard

+ +

See deleting and restoring.

+ +

Tips on creating helpful dashboards

+ +

To make a great dashboard, you first need to decide what you want the dashboard to tell about your data. What questions will give you insight into what you want to know? It helps to think of a topic or theme for your dashboard — something like “customer satisfaction,” or “second quarter sales goals”.

+ +

Some tips:

+ +
    +
  • Emphasize the most important questions. To draw people’s attention to what matters most, place the most important saved question cards near the top of the dashboard, and/or make them bigger than the other cards,
  • +
  • Keep dashboards focused. If you have more than 10 cards on a dashboard, think about breaking the dashboard into two separate ones. You don’t want to overwhelm people with too much information, and each dashboard should revolve around one theme or topic. Remember — you can make as many dashboards as you want, so you don’t have to cram everything into just one.
  • +
  • Add filters to your dashboard. Adding filters to dashboards makes them more useful. For example, instead of your dashboard being full of questions that are restricted to a specific time span, you can make more general questions and use dashboard filters to change the time span you’re looking at.
  • +
  • Make your dashboards interactive. Customize what happens when users click on a chart or table in your dashboard.
  • +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/dashboards/linked-filters.html b/_site/docs/doc-update-detection/dashboards/linked-filters.html new file mode 100644 index 000000000..f995f25d8 --- /dev/null +++ b/_site/docs/doc-update-detection/dashboards/linked-filters.html @@ -0,0 +1,3113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Linked filters | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Linked filters

+ +

You can link filters on a dashboard so that a child filter limits its values based on the value(s) applied by a parent filter.

+ +

For example, let’s say you want a filter for the state column to restrict the values available to a filter on the city column, so that if someone selects a state, they’ll only be able to select cities in that state. To do this, you can link the city filter (child) to a (parent) state filter.

+ +

Linked filters

+ +

Set up tables for linked filters

+ +

You can only link dashboard filters that are wired to database columns (not custom columns or summaries) on dashboard cards, because Metabase needs column metadata to create linked filters. Metabase needs to know what values are there in the columns, and how the columns in the parent and child relate to each other.

+ +

Filters can only be linked when they’re connected to columns that have an explicit relationship in the table metadata. By relationship, we mean that the columns should be either:

+ +
    +
  • In the same table.
  • +
  • In two different tables that have a foreign key relationship specified in the table metadata.
  • +
  • In two different tables that have a foreign key relationships to one or more intermediate tables, as specified in the table metadata
  • +
+ +

Setting up foreign key in table metadata

+ +

If you try to set up linked filters between two columns that aren’t connected, Metabase won’t show an error, but you’ll see that the values in the child filter aren’t restricted by the parent filter. For more troubleshooting tips, see Troubleshooting link filters.

+ +

Set up linked filters

+ +

You can link a child filter to one or more parent filters. The child filter must be either an ID, Location, or Text or Category filter. Parent filters can be any filter type.

+ +

To link a child filter on a dashboard to one or more parent filters:

+ +
    +
  1. Edit the dashboard by clicking on the pencil icon in the top right of the dashboard.
  2. +
  3. Edit the child filter by clicking on the gear icon in the filter.
  4. +
  5. In the filter settings sidebar, switch to Linked filters tab.
  6. +
  7. Select the parent filter(s).
  8. +
+ +

Linked filters

+ +

The filter(s) you select in the linked filters tab will be the parent filter(s), that is, the filter(s) that limit the values this (child) filter that you’re currently editing.

+ +

Limitations of linked filters

+ +

Linked filters ignore relationships defined by models and questions

+ +

Linked filters are only “aware” of relationships defined in the table metadata. This constraint lets people connect filters to the same column on multiple dashboard cards (across multiple tabs), but the constraint also means that:

+ +
    +
  • Linked filters can’t see relationships defined by joins in models or questions.
  • +
  • Linked filters can’t use any filter or join logic from any underlying card or model
  • +
+ +

For example, say you have a table with State and City columns, and you build a model that filters out rows with City = San Francisco. You ask a question based on that model, and add it to a dashboard. You add State and City filters to the dashboard, and link them. If you select were to select State = CA, the city filter may still show San Francisco as option, even though there are no records with San Francisco in the question and the underlying model, because the filter only “knows” about the underlying table metadata (which includes sample values for the column).

+ +

Linked filters don’t work with custom columns or summaries

+ +

Metabase uses database column metadata to populate values for linked filters, which means that linked filters have to be connected to database columns. In particular:

+ +
    +
  • +

    You can’t create linked filters on custom columns

    +
  • +
  • +

    Native/SQL questions must have a field filter variable in order to be linked. Basic SQL variables aren’t connected to database columns, so they won’t work for linked filters.

    +
  • +
  • +

    You can’t link filters that use “Custom List” or “From another model or question” as their value’s source.

    +
  • +
+ +

Troubleshooting linked filters

+ +

If you’re not seeing what you expect with linked filters, make sure that your table relationships are set up to support linked filters . See Troubleshooting linked filters for more troubleshooting information.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/dashboards/multiple-series.html b/_site/docs/doc-update-detection/dashboards/multiple-series.html new file mode 100644 index 000000000..414c37241 --- /dev/null +++ b/_site/docs/doc-update-detection/dashboards/multiple-series.html @@ -0,0 +1,3163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Charts with multiple series | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Charts with multiple series

+ +

Data in isolation is rarely all that useful. One of the best ways to add context and clarity when communicating with data is to show data side-by-side with other data. Here are just a few examples of data that is better together than apart.

+ +
    +
  • Your company’s revenue vs. its costs over time.
  • +
  • Average order price this month and user signups for that month.
  • +
  • New users per day vs. returning users per day.
  • +
  • Orders per day from a few different product lines.
  • +
+ +

Displaying data side by side

+ +

There are two main ways to visualize data side by side:

+ +
    +
  1. +

    Ask a question that involves multiple dimensions with the query builder (or in SQL, if you’re fancy). Example: the count of users by region over time.

    +
  2. +
  3. +

    Combine two saved questions that share a common dimension (like time) on a dashboard. For example, you could look at revenue over time and costs over time together.

    +
  4. +
+ +

Ask a question that involves multiple dimensions

+ +

If you’re creating a new question, you can view the results as a multi-series visualization by summarizing your data and grouping it into two groups.

+ +

As an example, we might want to see which website or service is referring the most people to our website. In the Sample Database that ships with Metabase, you would group by the Source and Created At columns of the People table.

+ +

To create the multi-series chart, select the People table, click on the Summarize button in the upper right, then add Source and Created At as groupings (the count of rows metric that we want is selected by default). Be sure to click the plus button to the right of your selection, so Metabase knows to add the grouping; otherwise, Metabase will switch to that grouping. Learn more about asking questions.

+ +

Metabase will automatically display a multi-series line chart visualization of how each referrer has performed for us.

+ +

multi-series in the query builder

+ +

You can also create a multi-series chart by composing a custom question in the notebook editor. All you need to do is summarize your data (e.g., count the rows) and group that data into multiple groups (e.g. Created At by month and Product Category).

+ +

Composing a multi-series question in the notebook editor

+ +

Note: you won’t be able to add another saved question to multi-series visualizations made in this fashion. Metabase can visualize up to 100 distinct values of a dimension at once, so if you’re selecting a field that contains a lot of values, you might need to filter the values.

+ +

Combining two saved questions

+ +

If you already have two or more saved questions you’d like to compare, and they have the same first dimension, they can be combined onto a single dashboard card. You can even compare questions that pull data from different databases. Here’s how:

+ +
    +
  1. +

    Add a question with a dimension like time or category to a dashboard. In practice, these will usually be line charts or bar charts.

    +
  2. +
  3. +

    While in edit mode on the dashboard, hovering over a card will display some editing options in the upper right of the question, including an option to add a line, as well as a gear icon. Click on the add a line option (the + with a line and the word “Add” next to it).

    +
  4. +
+ +

add multi-series

+ +
    +
  1. In the Edit Data modal, you’ll see the original question on the left, with a list of compatible questions you can choose from on the right. Search question(s) to add, and check the box next to each question you’d like to see alongside with the original. Metabase will add the question(s) to the same chart.
  2. +
+ +

multi-series edit modal

+ +

If necessary, the X and Y axes will automatically update. Metabase will create a legend using the existing card titles to help you understand which question maps to which series on the chart. Repeat this process as many times as you need.

+ +

Edit modal with multi-series

+ +

To remove a series, simply uncheck its box.

+ +

Once you have your chart looking how you’d like, hit done. Metabase will show your changes on the card in the dashboard. Depending on how dense your data is, at this point you might want to consider enlarging your chart to make sure the data is legible.

+ +
+

SQL questions may not work. Metabase has less information about SQL-based questions, so we cannot guarantee they can be added reliably. You’ll see a little warning sign next to SQL questions to indicate this uncertainty, so be aware that adding these kinds of questions may not work.

+
+ +

Combining Number charts

+ +

If you need to compare single numbers to get a sense of how they differ, Metabase can turn multiple number charts into a bar chart.

+ +

As above, while editing a dashboard, hover over a number chart of your choice, and click on the icon with the + and bar chart icon to add a saved question.

+ +

Use the search bar to find other saved question(s) that you’d like to see represented on the bar chart, and click the checkbox to add them to your chart. In this case, we added Widget orders to compare them to Gadget orders.

+ +

From numbers to bar chart

+ +

Multi-series charts, values, and legibility

+ +

When displaying multiple series, it’s important to keep legibility in mind. Combining many series can sometimes decrease the communication value of the data.

+ +

Metabase allows you to add values to multi-series charts, but go easy on this feature, especially on charts with lots of data points. Adding values to multiple series, each with many data points, can make charts more difficult to read.

+ +

From the Visualization > Display options, you can toggle the option: Show values on data points. Metabase will do its best to fit as many values as can fit nicely. You can also force Metabase to (begrudgingly) show values for all data points, by setting the Values to show to All.

+ +

add values to multi-series chart

+ +

You can also toggle values for each individual series. If you have three series, for example, you can show values on one, two, or all three series.

+ +
    +
  • +

    For a question with multiple dimensions, go to Visualization > Data tab, click on the three dots menu to the right of a series, and toggle Show values for this series to show or hide its values.

    +
  • +
  • +

    For a dashboard card that combines multiple saved questions, go to the Visualization > Display tab, click on the down arrow to the right of a series to expand its details, and toggle Show values for this series to show or hide its values.

    +
  • +
+ +

You can also toggle values for the whole chart, then selectively hide values for individual series until you have your chart looking just right.

+ +

Additionally, there is an option to configure the formatting of the values:

+ +
    +
  • Auto. Metabase selects the appropriate style for you
  • +
  • Compact. Metabase abbreviates values, e.g., 1,000 becomes 1K.
  • +
  • Full. Values are displayed in their natural beauty.
  • +
+ +

Now go forth and start letting your data get to know each other!

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/dashboards/start.html b/_site/docs/doc-update-detection/dashboards/start.html new file mode 100644 index 000000000..39e683ecb --- /dev/null +++ b/_site/docs/doc-update-detection/dashboards/start.html @@ -0,0 +1,3067 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Dashboards overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Dashboards overview

+ +

Example dashboard

+ +

Introduction to dashboards

+ +

Learn how to arrange tables, charts, and text cards on a dashboard.

+ +

Dashboard filters

+ +

Add filters to dashboards to update tables and charts.

+ +

Interactive dashboards

+ +

Customize what happens when people click on a chart in your dashboard.

+ +

Charts with multiple series

+ +

Combine multiple questions on a single chart.

+ +

Dashboard subscriptions

+ +

Set up a dashboard to email or Slack its results on a schedule.

+ +

Actions on dashboards

+ +

Add action buttons to dashboards.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/dashboards/subscriptions.html b/_site/docs/doc-update-detection/dashboards/subscriptions.html new file mode 100644 index 000000000..8fcc156fa --- /dev/null +++ b/_site/docs/doc-update-detection/dashboards/subscriptions.html @@ -0,0 +1,3225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Dashboard subscriptions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Dashboard subscriptions

+ +

Dashboard subscriptions allow you to send the results of questions on a dashboard to people via email or Slack - even to people who lack an account in your Metabase.

+ +

If your Metabase has email or Slack set up, all you need to do is create a dashboard, add subscribers to it, and tell Metabase how often you’d like the send out an update. You can set up as many subscriptions to a dashboard as you like, and if you make any changes to the dashboard, Metabase will update the subscriptions the next time they’re delivered.

+ +

Enabling dashboard subscriptions

+ +

To enable dashboard subscriptions, your administrators will need to have set up email or Slack for your Metabase. See Setting up email or Setting up Slack.

+ +

Setting up a dashboard subscription

+ +

To set up a subscription to a dashboard, click on the Sharing icon and select Subscriptions. Metabase will slide out a sidebar on the right, with an option to set up a subscription via email or Slack:

+ +

Set up a dashboard subscription with email or slack

+ +

Let’s say we want to email a dashboard. We’ll click on the Email it option in the sidebar, and Metabase will give us some options:

+ +

Dashboard subscription email options

+ +

Email subscription options

+ +

For emails, we can:

+ +

Add subscribers

+ +

Add email addresses to register subscribers. On Metabase Pro and Enterprise, admins can limit email recipients to approved domains for notifications and configure which recipients Metabase suggests.

+ +

Determine frequency and timing

+ +

Tell Metabase how often it should send the dashboard:

+ +
    +
  • Hourly
  • +
  • Daily
  • +
  • Weekly
  • +
  • Monthly
  • +
+ +

And what time of day to send the dashboard.

+ +

Send email now

+ +

A button that sends an email to all subscribers each time you touch it.

+ +

Don’t send if there aren’t results

+ +

If there are no results, you can tell Metabase to skip sending the email.

+ +

Set filter values for when this gets sent

+ +
+
+ + + + + + + +

Dashboard subscription filter customization is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Here you can set filters to apply when Metabase sends the subscription.

+ +

Attach results

+ +

Tell Metabase if it should attach results to the email as a file, in addition to displaying the table in the email body.

+ +

If you’ve added filters to your dashboard and set default values for those filters, Metabase will apply those default values to your subscriptions, filtering the results of all questions that are connected to those filters when the subscriptions are sent. To learn more, check out dashboard filters.

+ +

File format

+ +

You can choose between the following file formats:

+ +
    +
  • .csv
  • +
  • .xlsx
  • +
  • .json
  • +
+ +

Use unformatted values in attachments

+ +

If you check this box, Metabase will drop any visualization settings applied to the questions’ results (e.g., date formatting) and send only the raw, unformatted results.

+ +

Questions to attach

+ +

Here you can specify which questions Metabase should attach results for.

+ +

The attached files will include up to 2000 rows by default. If you’re self-hosting Metabase, you can adjust this row limit by setting the environment variable MB_UNAGGREGATED_QUERY_ROW_LIMIT. To change this row limit on your Metabase Cloud instance, you can contact us and request a different row limit.

+ +

Slack subscription options

+ +

For Slack subscriptions, you can set up a subscription for a channel (like #general), or for a single person via their Slack username.

+ +
+

Note that Slack username can be different from Slack display name.

+
+ +

slack subscription options

+ +
+

If you rename the subscribed channel in Slack, you’ll need to update the subscription to point to the new Slack channel name.

+
+ +

You can specify how often Metabase sends a Slack message (hourly, daily, weekly, or monthly), and whether to send a message if the dashboard fails to return results.

+ +

Sending subscriptions to private channels

+ +

See Sending alerts and subscriptions to private Slack channels.

+ +

Adding multiple subscriptions

+ +

You can add multiple subscriptions to a single dashboard. To add a subscription, click on the + icon in the dashboard subscription panel.

+ +

Deleting a subscription

+ +

To remove a subscription from a dashboard, select the subscription you’d like to remove. At the bottom of the sidebar, select Delete this subscription. Follow the instructions on the modal that pops up to confirm you’d like to delete the subscription.

+ +

Viewing existing dashboard subscriptions

+ +
+
+ + + + + + + +

Usage analytics is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

You can view a list of all alerts and dashboard subscriptions that people have set up in your Metabase in Usage analytics collection. See Usage analytics.

+ +

Customize filter values for each dashboard subscription

+ +
+
+ + + + + + + +

Dashboard subscription filter customization is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

You can customize which filter values to apply to each dashboard subscription. That way you can send different groups of people an email (or Slack message) the contents of the dashboard with different filters applied. You only need to maintain one dashboard, which you can use to send results relevant to each subscriber.

+ +

Setting filter values

+ +

You can set values for each filter on the dashboard. If you have any dashboard filters with default values, you can override those defaults for a given subscription, or leave them as-is.

+ +

Here’s the sidebar where you can set the filter values:

+ +

Setting a filter value

+ +

The section to call out here is the Set filter values for when this gets sent. Here we’ve set “VT” as the value for the dashboard’s State filter to scope results to records from Vermont. We didn’t set a value for the Created_At filter, so the subscription will send the results without a filter applied. If you’ve set a default value for the filter, the subscription will list the value here.

+ +

How permissions work with dashboard subscriptions

+ +

See Notification permissions.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/data-modeling/field-types.html b/_site/docs/doc-update-detection/data-modeling/field-types.html new file mode 100644 index 000000000..444c71921 --- /dev/null +++ b/_site/docs/doc-update-detection/data-modeling/field-types.html @@ -0,0 +1,3213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Field types | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Field types

+ +

While data types indicate to a database how it should interpret the values in a field, field types or semantic types describe the meaning of a field. For example, a column’s data type could be type/text but the semantic type may be Email. Field types are just one example of metadata—information about data—that Admins can change in Metabase.

+ +

Field types dictate how Metabase displays its data, as well as the column’s special functionality, if any. By marking columns in a table as Latitude and Longitude, Metabase can use the columns to create pin and heat maps. Similarly, designating a column as a URL allows users to click on the link to visit that URL.

+ +

Overall Row

+ +
    +
  • Entity Key: The field in this table that uniquely identifies each row. Could be a product ID, serial number, etc.
  • +
  • Entity Name: Different from the entity key, the entity name represents what each row in the table is. For example, in a Users table, you might want to use a field containing usernames as the entity name.
  • +
  • Foreign Key: The column in this table that (usually) refers to the entity key of another table in order to connect data from different tables that are related. For example, in a Products table, you might have a Customer ID field that points to a Customers table, where Customer ID is the primary key.
  • +
+ +

Common

+ +

Common field types are text/varchar types.

+ +
    +
  • Category: If set to category, Metabase will know that it can use this field to group results when creating questions for automatic insights like X-rays.
  • +
  • Comment
  • +
  • Description
  • +
  • Title
  • +
+ +

Location

+ +

Marking fields as locations tell Metabase that it can use the field to display data on a map chart.

+ +
    +
  • City
  • +
  • Country
  • +
  • Latitude: Tells Metabase that the data could be plotted on a pin map.
  • +
  • Longitude: Did you know that you can use the moons of Jupiter to calculate longitude?
  • +
  • State
  • +
  • Zip Code
  • +
+ +

Financial

+ +

Financial field types tell Metabase to treat the field’s values as money. If you select any of the financial field types, Metabase will ask which currency you want to use. Metabase treats each of the following types as money, their differences are purely semantic.

+ +
    +
  • Cost
  • +
  • Currency
  • +
  • Discount
  • +
  • Gross margin
  • +
  • Income
  • +
  • Price
  • +
+ +

See Currency formatting options.

+ +

Numeric

+ +

Metabase will treat numeric field types as numbers.

+ +
    +
  • Percentage: Displays the number as a percentage by default.
  • +
  • Quantity: Displays the number as normal by default.
  • +
  • Score: Displays the number as normal by default.
  • +
  • Share: The same as percentage, so prefer “Percentage”.
  • +
+ +

See Number formatting options.

+ +

Profile

+ +

Fields that deal with people.

+ +
    +
  • Birthday. Date field.
  • +
  • Company: Text field.
  • +
  • Email: Displays as a mailto link.
  • +
  • Owner: Text field.
  • +
  • Subscription: Text field.
  • +
  • User: Text field.
  • +
+ +

Date and Time

+ +

Date and time field types tell Metabase the field contains datetime values, so it can use date pickers and display time series (e.g., a line chart).

+ +

If your database stores datetimes as a number or string, you can cast that column to a datetime.

+ +
    +
  • Cancelation date
  • +
  • Cancelation time
  • +
  • Cancelation timestamp
  • +
  • Creation date
  • +
  • Creation time
  • +
  • Creation timestamp
  • +
  • Deletion date
  • +
  • Deletion time
  • +
  • Deletion timestamp
  • +
  • Updated date
  • +
  • Updated time
  • +
  • Updated timestamp
  • +
  • Join date
  • +
  • Join time
  • +
  • Join timestamp
  • +
  • UNIX Timestamp (Milliseconds)
  • +
  • UNIX Timestamp (Seconds)
  • +
+ +

See Date formatting options.

+ +

Categorical

+ +
    +
  • Enum: An abbreviation for “enumerated type,” the value of an enum draws on a predefined list of options. An example of an enum would be a field for the months of the year. This list of twelve options is defined in the makeup of the column, and no options outside this list would be valid.
  • +
  • Product
  • +
  • Source: For example, the source of a visitor to your website (such as a search engine or other website).
  • +
+ +

URLs

+ +

Metabase can display fields with URLs as images or links.

+ +
    +
  • Avatar Image URL: Displays the field as an image in table and detail views.
  • +
  • Image URL: Displays the field as an image in table and detail views.
  • +
  • URL: Displays the field as a link.
  • +
+ +

Other

+ +
    +
  • Field containing JSON. See Working with JSON
  • +
  • No semantic type – Used for fields that don’t fall into any of the above field types.
  • +
+ +

Using field types in Metabase

+ +

Set column types in models to enable people to explore results with the query builder

+ +

You can set field types for models, which helps Metabase understand how to work with data in models built using SQL. If you set each column type in a SQL model, people will be able to explore that model using the query builder and drill-through menus.

+ +

With records that include integer entity keys, you can also configure text fields in models to surface individual records in search.

+ +

X-rays

+ +

When you X-ray a table, model, or entity, Metabase considers both the data type and the field type to display different charts that summarize that data.

+ +

Field Filters

+ +

Knowing what field types are and how they work is helpful when using field filters, as you can only create field filters for certain field types.

+ +

Editing types in the Table Metadata page

+ +

If you’re an administrator, you can edit field types using the Table Metadata page in the Admin Panel.

+ +

While data types themselves can’t be edited in Metabase, admins can manually cast certain data types to be read differently, like interpreting a numerical data type as a date format.

+ +
+

Metabase currently supports only casting to a datetime type in Metadata settings.

+
+ +

JSON unfolding

+ +

See Working with JSON.

+ +

Arrays

+ +

Metabase currently does not support array types with any database. You’ll only be able to use Is empty or Is not empty filters on columns containing arrays.

+ +

Further Reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/data-modeling/formatting.html b/_site/docs/doc-update-detection/data-modeling/formatting.html new file mode 100644 index 000000000..7fa6129d8 --- /dev/null +++ b/_site/docs/doc-update-detection/data-modeling/formatting.html @@ -0,0 +1,3101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Formatting defaults | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Formatting defaults

+ +

There are Metabase users around the world, each with different preferences for how dates, times, numbers, and currencies should be formatted and displayed. Metabase allows you to customize these formatting options at three different levels:

+ +
    +
  1. Global. Set global defaults in the Localization section in Admin -> Settings -> Localization.
  2. +
  3. Field. Set field (column) defaults in Admin -> Table Metadata. Field defaults override global defaults.
  4. +
  5. Question. Set formatting defaults for individual questions in the visualization settings of that question. Question defaults override global and field defaults.
  6. +
+ +

Field-level formatting

+ +

You can override the global defaults for a specific field by going to the Table Metadata section of the Admin Panel, selecting the database and table of the field in question, and clicking the gear icon on the far right of the screen next to that field to go to its options page, then clicking on the Formatting tab.

+ +

The options you’ll see here will depend on the field’s type. They’re generally the same options as in the global formatting settings, with a few additions:

+ +

Dates and Times

+ +
    +
  • Show the time: this lets you choose if this time field should be displayed by default without the time; with hours and minutes; with hours, minutes, and seconds; or additionally with milliseconds.
  • +
+ +

Numbers

+ +
    +
  • Show a mini bar chart: only applies to table visualizations. Displays a bar for each value to show large or small it is relative to the other values in the column.
  • +
  • Style: lets you choose to display the number as a plain number, a percent, in scientific notation, or as a currency.
  • +
  • Separator style: this gives you various options for how commas and periods are used to separate the number.
  • +
  • Number of decimal places: forces the number to be displayed with exactly this many decimal places.
  • +
  • Multiply by a number: multiplies this number by whatever you type here.
  • +
  • Add a prefix/suffix: lets you put a symbol, word, etc. before or after this number.
  • +
+ +

Currency

+ +

Currency field formatting settings include all the same options as in the global formatting section, as well as all the options that Number fields have.

+ +

See Currency formatting options.

+ +

Question-level formatting

+ +

Lastly, you can override all formatting settings in any specific saved question or dashboard card by clicking on the gear to open up the visualization options. To reset any overridden setting to the default, just click on the rotating arrow icon next to the setting’s label. This will reset the setting to the field-level setting if there is one; otherwise it will be reset to the global default.

+ +

Formatting options vary depending on the type of visualization:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/data-modeling/images/AddSegment.png b/_site/docs/doc-update-detection/data-modeling/images/AddSegment.png new file mode 100644 index 000000000..ca3e5390d Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/AddSegment.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/CreateSegment.png b/_site/docs/doc-update-detection/data-modeling/images/CreateSegment.png new file mode 100644 index 000000000..01dda9696 Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/CreateSegment.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/EditMessage.png b/_site/docs/doc-update-detection/data-modeling/images/EditMessage.png new file mode 100644 index 000000000..d789d4dcc Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/EditMessage.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/FinishedSegment.png b/_site/docs/doc-update-detection/data-modeling/images/FinishedSegment.png new file mode 100644 index 000000000..f20413fa0 Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/FinishedSegment.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/Segment.png b/_site/docs/doc-update-detection/data-modeling/images/Segment.png new file mode 100644 index 000000000..7d42b3898 Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/Segment.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/SegmentActions.png b/_site/docs/doc-update-detection/data-modeling/images/SegmentActions.png new file mode 100644 index 000000000..8761b49c7 Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/SegmentActions.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/column-settings.png b/_site/docs/doc-update-detection/data-modeling/images/column-settings.png new file mode 100644 index 000000000..b586ed96e Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/column-settings.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/common-metrics.png b/_site/docs/doc-update-detection/data-modeling/images/common-metrics.png new file mode 100644 index 000000000..de62e21fc Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/common-metrics.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/entity-picker-metrics-tab.png b/_site/docs/doc-update-detection/data-modeling/images/entity-picker-metrics-tab.png new file mode 100644 index 000000000..d4fb36f9a Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/entity-picker-metrics-tab.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/format-as-url.png b/_site/docs/doc-update-detection/data-modeling/images/format-as-url.png new file mode 100644 index 000000000..233f72989 Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/format-as-url.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/formula.png b/_site/docs/doc-update-detection/data-modeling/images/formula.png new file mode 100644 index 000000000..8087cdd4c Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/formula.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/metrics-built-on-other-metrics.png b/_site/docs/doc-update-detection/data-modeling/images/metrics-built-on-other-metrics.png new file mode 100644 index 000000000..70f5fdfcc Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/metrics-built-on-other-metrics.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/original-schema.png b/_site/docs/doc-update-detection/data-modeling/images/original-schema.png new file mode 100644 index 000000000..88561335b Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/original-schema.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/pinned-metrics.png b/_site/docs/doc-update-detection/data-modeling/images/pinned-metrics.png new file mode 100644 index 000000000..5b76103b6 Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/pinned-metrics.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/table-metadata.png b/_site/docs/doc-update-detection/data-modeling/images/table-metadata.png new file mode 100644 index 000000000..ea68179f9 Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/table-metadata.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/table-with-json-column.png b/_site/docs/doc-update-detection/data-modeling/images/table-with-json-column.png new file mode 100644 index 000000000..3a9e702c1 Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/table-with-json-column.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/turn-into-a-model.png b/_site/docs/doc-update-detection/data-modeling/images/turn-into-a-model.png new file mode 100644 index 000000000..edcde276b Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/turn-into-a-model.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/unfold-json-setting.png b/_site/docs/doc-update-detection/data-modeling/images/unfold-json-setting.png new file mode 100644 index 000000000..36a7f2f92 Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/unfold-json-setting.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/unfolded-fields.png b/_site/docs/doc-update-detection/data-modeling/images/unfolded-fields.png new file mode 100644 index 000000000..e6878fbc7 Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/unfolded-fields.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/images/unfolded-values.png b/_site/docs/doc-update-detection/data-modeling/images/unfolded-values.png new file mode 100644 index 000000000..b2a104a39 Binary files /dev/null and b/_site/docs/doc-update-detection/data-modeling/images/unfolded-values.png differ diff --git a/_site/docs/doc-update-detection/data-modeling/json-unfolding.html b/_site/docs/doc-update-detection/data-modeling/json-unfolding.html new file mode 100644 index 000000000..cfe90c3cf --- /dev/null +++ b/_site/docs/doc-update-detection/data-modeling/json-unfolding.html @@ -0,0 +1,3114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Working with JSON | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Working with JSON

+ +

Filtering JSON

+ +

In the query builder, Metabase can’t parse JSON in columns, so you can only filter by “Is empty” or “Not empty”.

+ +

JSON unfolding

+ +

With some databases, Metabase can unfold JSON columns into their component fields, which you can then filter on using the query builder.

+ +

Here is a table with a column that contains JSON.

+ +

A table with a JSON column

+ +

Metabase can unfold that JSON column so that each key in the JSON object gets its own column in the table. Here are the unfolded fields of the table with the JSON column pictured above:

+ +

Unfolded fields

+ +

And here are the values as seen in the table:

+ +

Unfolded values

+ +

This unfolding allows you to filter for values found in the original JSON object.

+ +

Metabase will prefix the unfolded column names with the name of the original column that contained the JSON. You can change the column names in Admin settings > Table metadata, or by creating a model and editing the column metadata.

+ +

Toggling JSON unfolding for a database

+ +

If you notice a hit to performance from this JSON unfolding, we recommend turning it off.

+ +

To turn off JSON unfolding for a database:

+ +
    +
  1. Click on the Gear in the upper right.
  2. +
  3. Select Admin settings
  4. +
  5. Visit the Databases tab.
  6. +
  7. Select the relevant database.
  8. +
  9. Click Show advanced options.
  10. +
  11. Toggle Allow unfolding of JSON columns.
  12. +
  13. Scroll down and click the Save changes button.
  14. +
  15. Click Sync database schema.
  16. +
  17. Click Re-scan field values.
  18. +
+ +

Toggling JSON unfolding for a specific column

+ +

If performance degrades, or you’d rather keep the JSON contained in the original column, you can turn off unfolding for individual fields in their settings.

+ +
    +
  1. Click on the Gear in the upper right.
  2. +
  3. Select Admin settings.
  4. +
  5. Visit the Table metadata tab.
  6. +
  7. Select the database that contains the field you want to update.
  8. +
  9. Select the table that contains the field.
  10. +
  11. Select the field containing the original JSON
  12. +
  13. Scroll to the Unfold JSON option and select Yes or No. If the column was unfolded, Metabase will have hidden this JSON columnn from view, so if you want the JSON column to be visible again, you’ll need to change the column’s visibility to Everywhere.
  14. +
  15. Scroll down and click on the Re-scan this field.
  16. +
+ +

Unfolded JSON setting

+ +

For JSON unfolding to work, the column’s data type must be JSON

+ +

For example, if you upload a CSV with JSON in it, you might need to update the data/type in the database. Note that you can’t edit the data type via Metabase; you can only change its field type. So even if the field type in Metabase is Field containing JSON, if the data/type isn’t JSON, Metabase won’t give you the option to unfold the column. You’ll need to change the column type in the database itself.

+ +

Databases that support JSON unfolding

+ + + +

A note on BigQuery: Metabase supports the STRUCT data type in BigQuery, but it won’t unfold JSON stored in BigQuery as the JSON type. If your data is stored in the STRUCT type in BigQuery, you can query the table’s nested fields. Some background here: BigQuery differs from other databases in that nested fields are part of the table definition itself. So when Metabase syncs with your BigQuery database, it’ll be able to get metadata about any of your tables, including tables with nested fields. Querying nested fields, however, doesn’t extend to arrays (REPEATED (STRUCT)) in BigQuery.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/data-modeling/legacy-metrics.html b/_site/docs/doc-update-detection/data-modeling/legacy-metrics.html new file mode 100644 index 000000000..2c387b17a --- /dev/null +++ b/_site/docs/doc-update-detection/data-modeling/legacy-metrics.html @@ -0,0 +1,3054 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Legacy metrics | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Legacy metrics

+ +

Metabase upgraded metrics starting in version 51.

+ +

If you’re upgrading from Metabase 50 or earlier, all of your existing metrics will be migrated to the new metrics, which you can find in the Migrated Metrics V1 collection with curate access only for admins. You can leave the metrics there, or move them into different collections.

+ +

What’s new with metrics

+ +
    +
  • Anyone can create a new metric.
  • +
  • Metrics can be stored (and pinned) to collections.
  • +
  • If you have curate access to the collection, you can edit a metric in that collection.
  • +
  • You can explore metrics in your Metabase in the data browser.
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/data-modeling/metadata-editing.html b/_site/docs/doc-update-detection/data-modeling/metadata-editing.html new file mode 100644 index 000000000..ce522ed8d --- /dev/null +++ b/_site/docs/doc-update-detection/data-modeling/metadata-editing.html @@ -0,0 +1,3333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Table metadata admin settings | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Table metadata admin settings

+ +

Metabase lets you add and edit metadata to your tables and columns so that you can manage your org’s business logic as it changes. Go to the Table Metadata tab in your Admin settings to:

+ + + +
+

The Table Metadata admin settings only affect the way data’s displayed and interpreted in Metabase. None of the settings will change the data in your database.

+
+ +

Table settings

+ +

Click on a table name in the left sidebar to view the table’s settings in Metabase.

+ +

If you’ve got more than one database connected to Metabase, click on the database name (for example, “Sample Database”) and select another database from the dropdown menu. Once you select a database, the tables in that database will appear in the sidebar.

+ +

Table metadata

+ + + +

Table display name

+ +

To edit a table’s display name in Metabase, click into the box that contains the current table name. Changes will be saved automatically once you click out of the box.

+ +

Table description

+ +

To add a table description, click into the box below the table name. Descriptions are displayed in Metabase’s data reference to help people find the right table for their use case.

+ +

Table visibility

+ +

Queryable tables are visible across all of Metabase.

+ +

Hidden tables won’t show up in the query builder or data reference. But this is not a security feature: hidden tables can still be used in SQL questions if someone writes SELECT * FROM hidden_table from the SQL editor. To prevent people from writing queries against specific tables, see data permissions.

+ +

Tip: To hide all of the tables in a database (say, if you’ve migrated to a new database), click on the hidden eye icon beside “# queryable tables” in the left sidebar.

+ +

Original schema

+ +

To remind yourself of column names and data types as they’re stored in your database, click Original schema (below Visibility).

+ +

Original schema

+ +

Column (field) settings

+ +

Select a database and click on a table’s name in the sidebar to bring up basic column display settings:

+ + + +

For extra column settings, click on the gear icon at the right of a column’s settings box:

+ +

Column settings

+ + + +

Column name

+ +

To change the global display name of a column in Metabase, click on the name of the column. For example, you could display “auth.user” as “User” to make the column more readable. People can use models to give columns a display name that’s local to the model.

+ +

Column description

+ +

To add a description, click into the box below the column name. Descriptions are displayed in the data reference to help people interpret the column’s values. You should consider adding a description if your column contains:

+ +
    +
  • abbreviations or codes
  • +
  • zeroes, nulls, or blank values
  • +
  • placeholder values, like 9999-99-99
  • +
+ +

Column visibility

+ +

Everywhere: by default, users can see all of the columns in a table.

+ +

Only in detail views will hide lengthy text from question results. This setting is applied by default if a column’s values have an average length of more than 50 characters. For example, you could use this setting on a column like “Customer Comments” if you already have a column for “Customer Rating”.

+ +

Do not include columns won’t show up in the query builder or data reference. You can set “do not include” on sensitive columns (such as PII) or irrelevant columns. But this visibility option is a simple omit/hide option; it’s not a security feature. These columns are still accessible for people with native query privileges; they can write SELECT hidden_column FROM table or SELECT * from table in the SQL editor and they’ll be able to view these fields and their values. To prevent people from viewing certain columns, see data sandboxing.

+ +

Column order

+ +

Metabase defaults to the column order defined in your database schema. To reorder the column display order in question results and menus manually, click on the grab bar to the right of each column, and drag the column to a new position.

+ +

To sort the columns automatically, click on the sort icon at the top right of the first column’s settings box. The sorting options are:

+ +
    +
  • Database. (Default) The order of columns as they appear in the database.
  • +
  • Alphabetical. A, B, C… however the alphabet works.
  • +
  • Custom. You choose the order. Metabase will automatically switch the sort order to “Custom” if you rearrange any of the columns.
  • +
  • Smart. Metabase chooses for you.
  • +
+ +

Field type

+ +

To change the field type of a column, click on the Type dropdown menu in a column’s setting box. You can also use the Type dropdown to label a column as an entity key (primary key) or foreign key in Metabase (with no consequence to your database).

+ +

Casting to a specific data type

+ +

If you want Metabase to treat a text or number column as a datetime column:

+ +
    +
  1. Go to Admin settings > Table Metadata.
  2. +
  3. Find your database and table.
  4. +
  5. Click on the gear icon at the right of a column’s settings box.
  6. +
  7. Scroll to Cast to a specific data type
  8. +
  9. Select a casting option.
  10. +
+ +
+

Metabase currently supports only casting to a datetime type in Cast to a specific data type. If you need to cast to a different type (like float), you can create a SQL question that casts the data and save it as a model, or create a view directly in your database.

+
+ +

Text to datetime casting options:

+ +
    +
  • ISO8601->Date
  • +
  • ISO8601->Datetime
  • +
  • ISO8601->Time
  • +
+ +

Numeric to datetime casting options:

+ +
    +
  • UNIXMicroSeconds->DateTime
  • +
  • UNIXMilliSeconds->DateTime
  • +
  • UNIXNanoSeconds->DateTime
  • +
  • UNIXSeconds->DateTime
  • +
+ +

Casting is different from setting the field type. For example, say you have a “Created At” column with a string data type in your database. You’ll need to cast “Created At” to one of the datetime types above if you want to do things like:

+ +
    +
  • Create relative date filters, such as “Created At = Last week”.
  • +
  • Use “Created At” with formulas like datetimeAdd.
  • +
+ +
+

Casting data types from the Table Metadata admin settings won’t affect the original data types in your database.

+
+ +

Changing the filter widget

+ +

To change a column’s filter widget:

+ +
    +
  1. Go to Admin settings > Table Metadata.
  2. +
  3. Find your database and table.
  4. +
  5. Click on the gear icon at the right of a column’s settings box.
  6. +
  7. Scroll to Filtering on this field.
  8. +
  9. Select a filter widget option.
  10. +
+ +

Filter widget options

+ +

The default behavior for the Is filter for the field.

+ +
    +
  • Search box: Display a search box and suggest autocompletions for values in that column that match the search term(s).
  • +
  • A list of all values: Display a search box, as well as a list of checkboxes for values in a dropdown menu that people can select as search terms.
  • +
  • Plain input box: Display a search box, but do NOT suggest autocompletions.
  • +
+ +

Changing a search box filter to a dropdown filter

+ +

The dropdown filter widget can be finicky, because Metabase needs to run a scan to get the list of values for the dropdown menu.

+ +
    +
  1. Go to Admin settings > Table Metadata.
  2. +
  3. Find your database and table.
  4. +
  5. Scroll to your column.
  6. +
  7. In the column’s settings box, set Type to “Category”.
  8. +
  9. Set Filtering on this field to “A list of all values”.
  10. +
+ +

When you change a default filter to a dropdown filter, you’ll trigger a database query that gets the first 1,000 distinct values (ordered ascending) for that column. Metabase will cache the first 100kB of text to display in the dropdown menu. If you have columns with more than 1,000 distinct values, or columns with text-heavy data, we recommend setting Filtering on this field to “Search box” instead.

+ +

Remapping column values

+ +

Say you have a column with the values 1, 2, and 3, and you want to map each number to the values “low”, “medium” and “high”. This kind of mapping can be done on columns that have numeric or foreign key field types.

+ +

Remapping numbers

+ +
    +
  1. Go to Admin settings > Table Metadata.
  2. +
  3. Find your database and table.
  4. +
  5. Click gear icon at the right of a column’s settings box.
  6. +
  7. Scroll to Display values.
  8. +
  9. Select “Custom mapping” from the dropdown menu.
  10. +
  11. Enter the display values under Mapped values.
  12. +
+ +

Remapping foreign keys

+ +
    +
  1. Go to Admin settings > Table Metadata.
  2. +
  3. Find your database and table.
  4. +
  5. Click gear icon at the right of a column’s settings box.
  6. +
  7. Scroll to Display values.
  8. +
  9. Select “Use foreign key” from the dropdown menu.
  10. +
  11. Select a column name from the second dropdown menu.
  12. +
+ + + +
    +
  1. Go to Admin settings > Table Metadata.
  2. +
  3. Find your database and table.
  4. +
  5. Click on the gear icon at the right of a column’s settings box.
  6. +
  7. Select Formatting from the sidebar.
  8. +
  9. From Display as, select Link.
  10. +
  11. Optional: set display text under Link text.
  12. +
  13. Enter the URL in the Link URL field.
  14. +
  15. Optional: create a dynamic URL by adding the column name as a {{parameter}}.
  16. +
+ +

Format as URL

+ +

For example, if you set the Link URL for an “Adjective” column to:

+ +
https://www.google.com/search?q={{adjective}}
+
+ +

When someone clicks on the value “askew” in the “Adjective” column, they’ll be taken to the Google search URL:

+ +
https://www.google.com/search?q=askew
+
+ +

Refresh or discard cached values

+ +

To update the values in your filter dropdown menus, refresh or reset the cached values. Cache actions include:

+ +
    +
  • Re-scan this table or field to run a manual scan for new or updated column values. If possible, re-scan the table during off-peak hours, as scans can slow down your database.
  • +
  • Discard cached field values to clear cached values and stop them from showing up in your filter widgets.
  • +
+ +

Table cache actions

+ +
    +
  1. Go to Admin settings > Table Metadata.
  2. +
  3. Find your database and table.
  4. +
  5. Click the gear icon at the top right (below Exit admin).
  6. +
  7. Select a cache action.
  8. +
+ +

Column cache actions

+ +
    +
  1. Go to Admin settings > Table Metadata.
  2. +
  3. Find your database and table.
  4. +
  5. Click the gear icon at the right of a column’s settings box.
  6. +
  7. Scroll to Cached field values.
  8. +
  9. Select a cache action.
  10. +
+ +

Unfold JSON

+ +

If Metabase supports JSON unfolding for your database, you can decide whether to unfold JSON into component fields, where each JSON key becomes a column. You can turn this off if performance is slow.

+ +
    +
  1. Go to Admin settings > Table Metadata.
  2. +
  3. Find your database and table.
  4. +
  5. Click the gear icon at the right of a column’s settings box.
  6. +
  7. Scroll to Unfold JSON.
  8. +
  9. Toggle JSON unfolding.
  10. +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/data-modeling/metrics.html b/_site/docs/doc-update-detection/data-modeling/metrics.html new file mode 100644 index 000000000..87deaac2f --- /dev/null +++ b/_site/docs/doc-update-detection/data-modeling/metrics.html @@ -0,0 +1,3135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Metrics | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Metrics

+ +

Create metrics to define the official way to calculate important numbers for your team.

+ +

Metrics are like pre-defined calculations: create your aggregations once, save them as metrics, and use them whenever you need to analyze your data.

+ +

For example, you may want to create a metric that calculates revenue, so people can refer to revenue in their own questions. That way you standardize how revenue is calculated (so you don’t end up with five different calculations for the revenue).

+ +

Using metrics

+ +

You can:

+ + + +

Metrics in the query builder

+ +

When asking questions in the query builder, you can find metrics that your team created in the summarization section under Common metrics. You can pick multiple metrics and they will be calculated independently and joined automatically along the chosen dimensions.

+ +

Common metrics

+ +

You can also pick a metric as a data source when creating a new question. If the metric has a time dimension, Metabase will include the time dimension as a grouping. You can change the groupings to break out the metric by other dimensions.

+ +

Metrics tab in the entity picker

+ +

You can use custom expressions to combine multiple metrics, or perform calculations on top of metrics.

+ +

Creating a metric

+ +

You can create a metric by clicking on the + New menu and selecting Metric.

+ +

Select your starting data. You can start from a model, metric, table, or saved question.

+ +

You can only use the query builder to define a metric.

+ +

The metric editor is similar to the regular query builder, with two key differences:

+ +
    +
  • The aggregation section is called Formula
  • +
  • The group by section is called the Default time dimension. You can only group by a single time dimension.
  • +
+ +

Formula

+ +

Only the data and formula steps are required to define a metric. You can join and filter data before the formula step, and set a default time dimension to group by.

+ +

Metric formula

+ +

The formula is the core of the metric. It’s the thing you are aggregating, and it’s required when defining a metric.

+ +

You can build metrics on top of existing metrics.

+ +

Metric built on top of other metrics

+ +

Metric default time dimension

+ +

You can optionally set a default time dimension for the metric. Metabase will use this default time dimension when the metric is opened or displayed on a card in a collection or dashboard. In the image below that shows two pinned metrics at the top of a collection, the left metric lacks a default time dimension, so Metabase displays the metric as a number chart. The right metric has a default time dimension, so Metabase displays it as a line chart.

+ +

Pinned metrics

+ +

Setting a time dimension doesn’t lock the metric to that specific dimension. If someone uses the metric in a question or dashboard, they’ll be able to group by other time dimensions and granularities as well.

+ +

For example, you could calculate revenue and set a default time dimension of Created At by month, but if someone added that metric to a dashboard, they could group revenue by a different time granularity (e.g., by quarter). This is just an FYI so that you don’t name a metric “Monthly Revenue” and think that by setting a default time dimension to “month”, Metabase will prevent people from slicing revenue by other time granularities.

+ +

Editing a metric

+ +

To edit a metric, click on the three dot menu () and select Edit metric definition. Editing a metric requires curate access to the metric’s collection.

+ +

Do your thing, and save your changes.

+ +

When you click on a metric, Metabase will assume that you’re using that metric as the starting point for a new question. You can save any changes you make as a new question, but these changes won’t affect the metric’s definition.

+ +

Metric permissions

+ +

Like questions, models, and dashboards, whether a group can view or edit a metric depends on collection permissions. By “view” we mean the ability to see the metric in a collection, or see the metric as an option when building a query with the metric’s data source. If a metric is used in another question, whether a group can view the question depends on the question’s collection, not the metric’s collection.

+ +

By “editing” a metric, we mean editing the metric’s query definition.

+ +

These collection permissions also interact with the group’s data permissions, which define whether the group can view or query the metric’s source data.

+ +

Verifying a metric

+ +

See content verification.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/data-modeling/model-persistence.html b/_site/docs/doc-update-detection/data-modeling/model-persistence.html new file mode 100644 index 000000000..537a9d990 --- /dev/null +++ b/_site/docs/doc-update-detection/data-modeling/model-persistence.html @@ -0,0 +1,3140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Model persistence | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Model persistence

+ +
+

Currently available for PostgreSQL, MySQL, and Redshift.

+
+ +

Metabase can persist the results of your models so that your models (and the questions based on those models) load faster.

+ +

Metabase will store model results in tables in a bespoke schema in your data warehouse (not the Metabase application database). When people ask questions based on your models, Metabase will use the tables with the stored results instead of re-running the model’s query.

+ +
+

Model persistence doesn’t work with data sandboxing or impersonation.

+
+ +

Turn on model persistence in Metabase

+ +

To persist models for faster loading, you’ll need to turn on model persistence for:

+ +
    +
  1. Your Metabase
  2. +
  3. Individual databases
  4. +
  5. (Optional) individual models
  6. +
+ +

Turn on model persistence for your Metabase

+ +

To turn on model persistence for your Metabase, go to Admin settings > Performance > Model persistence.

+ +

You can set models to refresh based on one of the default frequencies (every 1 hour, 2 hours, etc.), or select the Custom option to use cron syntax to specify your own update frequency.

+ +

The cron scheduler uses the Report Timezone if selected. Otherwise the scheduler will use the System Timezone (which defaults to GMT in Metabase Cloud).

+ +

We recommend scheduling your models to refresh on a frequency that makes sense with how often your source tables update with new data.

+ +

If someone changes the query definition of a model, any question based on that model will re-run the model’s query until the next scheduled model refresh.

+ +

Turn on model persistence for each database

+ +

Once you’ve turned on model persistence for your Metabase, you’ll need to set it up for each specific database, as Metabase will need to create a schema in your data warehouse to store the persisted models.

+ +
    +
  1. +

    Go to Admin settings > Databases > [your database] > Turn model persistence on. If the credentials you’ve given Metabase to connect to your database are permissive, Metabase should do all the work for you: Metabase will check if the schema already exists, or otherwise attempt to create it. If the connection’s credentials lack the necessary permissions to create the schema in your database, you’ll need to create the schema in the database yourself.

    +
  2. +
  3. +

    To manually create the schema in your data warehouse, click on the info icon to get the schema name.

    +
  4. +
  5. +

    Create the schema in your database—make sure you use the exact schema name from step 1. For example, if you’re running PostgreSQL as your data warehouse, you’d create the schema by running CREATE SCHEMA IF NOT EXISTS schema_name, with schema_name being whatever Metabase showed you in the info icon.

    +
  6. +
  7. +

    Ensure that the credentials Metabase uses to connect to your data warehouse can manage and write to that schema.

    +
  8. +
+ +

Turn on model persistence for individual models

+ +
+
+ + + + + + + +

Individual model persistence is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

You can also toggle persistence on or off for individual models. When viewing a model, click on the in the upper right and select Edit settings. Toggle Persist model data on (you’ll need Curate access to the model’s collection to do this).

+ +

Toggling persistence for individual models is useful for models with data that updates at different frequencies than the schedule you set for other models in that database, or for models that are used more or less than other models in that database.

+ +

Refreshing a model’s persisted results

+ +

To refresh a model’s results, go to the model and click on the three-dot menu () and select Edit settings. In the info sidebar that opens, you’ll see a note about when Metabase last refreshed the model’s results, and an icon to refresh the results.

+ +

View model persistence logs

+ +

You can view the logs for model persistence by clicking on the gear icon in the upper right and selecting Admin settings > Tools > Model caching logs. See Admin tools.

+ +

Difference between persisted models and caching

+ +

Persisted models differ from cached results:

+ +
    +
  • Models are persisted in your data warehouse; cached results are stored in the application database. Metabase stores cached results in its application database. Metabase persists models in your connected data warehouse as tables.
  • +
  • Metabase refreshes model results and invalidates cached results. Metabase will refresh results of models according to the schedule you set. That is, Metabase will re-run the model’s query and store the results in your data warehouse. For cached results of saved questions and dashboards, Metabase won’t run the queries automatically; it will cache results when people view the question or dashboard, and invalidate the cached results according to the caching policy you set.
  • +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/data-modeling/models.html b/_site/docs/doc-update-detection/data-modeling/models.html new file mode 100644 index 000000000..65d04a530 --- /dev/null +++ b/_site/docs/doc-update-detection/data-modeling/models.html @@ -0,0 +1,3222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Models | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Models

+ +

Models are a fundamental building block in Metabase. Models curate data from another table or tables from the same database to anticipate the kinds of questions people will ask of the data. You can think of them as derived tables, or a special kind of saved question meant to be used as the starting point for new questions. You can base a model on a SQL or query builder question, which means you can include custom, calculated columns in your model.

+ +

Models:

+ +
    +
  • Let you update column descriptions and customize metadata to create great starting points for exploration.
  • +
  • Show up higher in search results and get highlighted when other users start new questions to promote reuse.
  • +
  • Live in collections to keep them separate from messy database schemas.
  • +
  • Can surface individual records in search results.
  • +
  • Can be persisted for faster loading.
  • +
+ +

For a deep dive on why and how to use models, check out our Learn article on models.

+ +

How to use models

+ +

You can use models to:

+ +
    +
  • Create, uh, models, with model here meaning an intuitive description of some concept in your business that you codify as a set of columns. An example model could be a “customer”, which is a table that pulls together customer information from multiple tables and adds computed columns, like adding a lifetime value (LTV) column. This model represents the measures and dimensions that you think are relevant to your understanding of your customers.
  • +
  • Let people explore the results of SQL queries with the query builder (provided you set the column types).
  • +
  • Create summary tables that pull in or aggregate data from multiple tables.
  • +
  • Clean up tables with unnecessary columns and rows filtered out.
  • +
+ +

The idea with models is to give other people a good “starting point table” that makes it easier to answer any questions they have about the subject being modeled.

+ +

Create a model

+ +

First, search for models that already exist. If you can’t find one that meets your needs, you can create a model:

+ + + +

Models you create are automatically pinned to the current collection.

+ +

Create a model from scratch

+ +
    +
  1. In the upper right, click New + > Model.
  2. +
  3. Choose either the query builder or a native query (if you want to use SQL). The advantage of using the query builder is that Metabase will be able to fill out some of the metadata for you; if you use SQL, you’ll have to fill out that metadata manually.
  4. +
  5. Select your data.
  6. +
  7. Create and save your query.
  8. +
+ +

Create a model from a saved question

+ +
    +
  1. Ask a question using either the query builder or the SQL editor, or select an existing saved question that you want to convert to a model.
  2. +
  3. Save the question.
  4. +
  5. Click on the > Turn this into a model.
  6. +
+ +

Turn a saved question into a model

+ +

Model details

+ +

To view a model’s details, visit the model and click on the info button in the upper right. Here you’ll see several tabs:

+ +
    +
  • Overview: Includes the description, Creator and Last Editor, and the list of fields included in the model. As well as the model’s Entity ID.
  • +
  • History: Lists changes to the model, and by whom.
  • +
  • Relationships: Lists which questions use the model, and which tables the model is linked to.
  • +
  • Actions: Lists actions created based on the model.
  • +
  • Insights: Info about the model’s usage. Only visible to admins on a Pro or Enterprise plan.
  • +
+ +

Add metadata to columns in a model

+ +

Metadata is the secret sauce of models. When you write a SQL query, Metabase can display the results, but it can’t “know” what kind of data it’s returning (like it can with questions built using the query builder). What this means in practice is that people won’t be able explore the results with the query builder, because Metabase doesn’t understand what the results are. With models, however, you can tell Metabase what kind of data is in each returned column so that Metabase can still do its query magic. Metadata will also make filtering nicer by showing the correct filter widget, and it will help Metabase to pick the right visualization for the results.

+ +

If you only set one kind of metadata, set the Column type to let Metabase know what kind of data it’s working with.

+ +

Display name

+ +

What people will see as the column’s name.

+ +

Description

+ +

A place to write helpful context for the column.

+ +

Database column this maps to

+ +

For models based on SQL queries, you can tell Metabase if the column has the same type as an existing database column.

+ +

Column type

+ +

You can set the column type. The default is “No special type”.

+ +

If your model is based on a SQL query and you want people to be able to explore the results with the query builder, you’ll need to set the column type for each column in your model.

+ +

This column should appear in…

+ +

You can specify whether a column should appear in the table view, or just in a detail view (when you click on the entity/primary key for the row).

+ +
    +
  • Table and detail views
  • +
  • Detail views only
  • +
+ +

Display as

+ +
    +
  • Text
  • +
  • Link (it’s a URL people should be able to click on)
  • +
+ +

Surface individual records in search by matching against this column

+ +

For string fields in records with integer entity keys, Metabase will give you the option make the values in that field show up when people search your Metabase. Essentially, Metabase will index these values and make them available to Metabase’s search engine. This option is handy when people often want to jump straight to an individual record in your model.

+ +

For example, if you have a model with accounts, you could turn on this option for a column listing the account’s name or email so that people can quickly search for specific accounts in the model from anywhere in your Metabase. When people click on a record in the search results, Metabase will jump straight to the model and the object detail for that record.

+ +

There are some limitations to this indexing:

+ +
    +
  • The indexed field must be a text/string type.
  • +
  • The record containing the field must have an integer entity key.
  • +
  • To keep your search speedy, Metabase will only index 5000 unique values from that field, so this option isn’t the best choice to turn on for tables with a ton of records.
  • +
+ +

Edit a model’s query

+ +

You can edit a model’s query by clicking on the down arrow next to the model’s name and clicking on Edit query definition. When you’re doing editing, be sure to save your changes. Unlike questions, which prompt you to save as a new question, any changes here will overwrite the existing model. If you want to create a new model from an existing model, select Duplicate this model from the model sidebar (the icon of two overlapping squares).

+ +

Start a question from a model

+ +

See asking questions.

+ +

Refer to a model in the SQL query editor

+ +

You can refer to a model in a SQL query just like you can refer to a saved question:

+ +

+SELECT * FROM {{#1-customer-model}}
+
+
+ +

Or as a common table expression (CTE):

+ +

+WITH model AS {{#3807-invoice-model}}
+SELECT *
+FROM model;
+
+
+ +

Simply typing {{#}} will allow you to search for models (for example, you could type in {{#customer}} to search models, questions, and tables with the word “customer” in the title.

+ +

You can also use the data reference sidebar to browse the models available. To open the data reference sidebar, click on the book icon.

+ +

Model version history

+ +

For questions, dashboards, and models, Metabase keeps a version history for the previous fifteen versions of that item. You can view changes and revert to previous versions.

+ +

See History.

+ +

Delete a model

+ +

You can move outdated or unneeded models to trash, or delete them permanently. Deleting a model will affect questions that use it as a data source.

+ +

See Deleting and restoring items.

+ +

Verifying a model

+ +

See content verification.

+ +

Model persistence

+ +

See Model persistence

+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/data-modeling/segments-and-metrics.html b/_site/docs/doc-update-detection/data-modeling/segments-and-metrics.html new file mode 100644 index 000000000..10f36aa6c --- /dev/null +++ b/_site/docs/doc-update-detection/data-modeling/segments-and-metrics.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/data-modeling/segments.html b/_site/docs/doc-update-detection/data-modeling/segments.html new file mode 100644 index 000000000..2745bfb66 --- /dev/null +++ b/_site/docs/doc-update-detection/data-modeling/segments.html @@ -0,0 +1,3077 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Segments | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Segments

+ +

Metabase allows admins to create segments so people can quickly and easily reference them in the query builder. Just head over to the Admin Panel and select Table Metadata from the top menu.

+ +

Creating a Segment

+ +

A segment is just a special named filter or set of filters. You can create these to make sure that there is an official definition of a subset of customers, users, or products that everyone on your team can refer to consistently. For example, you might create a segment called “Active Users” that contains all the filters that are needed to correctly select active users.

+ +

To start, select the Segments tab, followed by the New segment button on the right side of the screen. Choose the appropriate table and filters for your new segment and add a title and description. When you’re done, this segment will be accessible from the filter list in the query builder when viewing this table (the segment will not be automatically applied to the table).

+ +

Add a segment

+ +

Now you’ll be looking at the segment builder, which is a limited version of the query builder, with only the option to add filters. Add your filter(s) as you would in the query builder, and then give your segment a name and a description (these will be visible in the query builder filter dropdown after you’ve saved). If you want to test out your segment in the query builder before you save it, just click the Preview button, which will open a new query builder window with your segment applied.

+ +

Creating a segment

+ +

Once you’re done, click Save changes. Now your new segment will appear in the segments list of your table.

+ +

Finished segment

+ +

If you exit the Admin Panel and try asking a new question, then click on the button to add a filter, you’ll see your segment at the top of the list.

+ +

Segment in dropdown

+ +

Editing and retiring segments

+ +

You can edit and retire segments from the Table Metadata screen in the Admin Panel. Select the table with the segment you’re looking for, and click the ellipsis (…) icon to the right of that segment.

+ +

Segment Actions

+ +

When editing a segment, you’ll be required to leave a note about why you’re changing it, just so everyone can understand why things are different. If any user is the creator of a saved question or dashboard that utilized the segment you’ve edited, they’ll receive an email letting them know that things have changed, along with the explanation that you write in this box.

+ +

Edit message

+ +

Retiring a segment will make it no longer selectable from the query builder. However, it won’t break existing saved questions that depend on that segment.

+ +

Lastly, you can also view the revision history for each segment from the actions list.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/data-modeling/start.html b/_site/docs/doc-update-detection/data-modeling/start.html new file mode 100644 index 000000000..9b18f8be1 --- /dev/null +++ b/_site/docs/doc-update-detection/data-modeling/start.html @@ -0,0 +1,3075 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Data modeling overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Data modeling overview

+ +

Metabase provides tools for organizing your data and making it easier for people to understand.

+ +

Models

+ +

Models curate data from another table or tables from the same database to anticipate the kinds of questions people will ask of the data. You can think of them as derived tables, or a special kind of saved question meant to be used as the starting point for new questions.

+ +

Model persistence

+ +

Persist model results for faster loading times.

+ +

Metrics

+ +

Create metrics to define the official way to calculate important numbers for your team.

+ +

Table metadata admin settings

+ +

Guide people to the right data by adding display names, hiding outdated tables, configuring filter types, and more.

+ +

Field types

+ +

Field types dictate how Metabase displays its data, as well as the column’s special functionality, if any.

+ +

Setting default formatting for your data

+ +

Define formatting and display defaults for numbers, currencies, datetimes, and more.

+ +

Working with JSON

+ +

Metabase can unfold JSON columns into their component fields, which you can then filter on using the query builder.

+ +

Segments

+ +

Admins can define segments to create official filters for your data.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connecting.html b/_site/docs/doc-update-detection/databases/connecting.html new file mode 100644 index 000000000..d548316d5 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connecting.html @@ -0,0 +1,3123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Adding and managing databases | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Adding and managing databases

+ +

Connect Metabase to your data sources.

+ +

Adding a database connection

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Fill out the fields for that database, and click Save changes at the bottom.

+ +

The connection settings differ database to database. For the list of connection settings available for your database, click on the link to your database below.

+ +

Connecting to supported databases

+ +

The databases listed below have official drivers maintained by the Metabase team. Customers on Pro and Enterprise will get official support. For each database, Metabase supports the oldest supported version through the latest stable version.

+ + + +

If you don’t see your database listed here, see Community drivers.

+ +

As of version 46.6.4, Metabase no longer supports H2 connections. But Metabase still ships with an H2 database to include an embedded application database, as well as to provide some sample data out of the box.

+ +

Connecting to databases hosted by a cloud provider

+ +

For provider-specific connection details, like connecting to a PostgreSQL data warehouse on RDS:

+ + + +

Granting database privileges

+ +

For Metabase to connect, query, or write to your database, you must give Metabase a database user account with the correct database privileges. See Database roles, users, and privileges.

+ +

Syncing and scanning databases

+ +

See Syncing and scanning.

+ +

Deleting databases

+ +

Caution: Deleting a database is irreversible! All saved questions and dashboard cards based on the database will be deleted as well!

+ +

Go to Admin settings > Databases > your database and click Remove this database.

+ +

Restoring the Sample Database

+ +

If you’ve deleted the Metabase Sample Database, go to Admin settings > Databases and click Bring the Sample Database back.

+ +

Troubleshooting

+ + + +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/athena.html b/_site/docs/doc-update-detection/databases/connections/athena.html new file mode 100644 index 000000000..2d972b9e0 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/athena.html @@ -0,0 +1,3261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Amazon Athena | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Amazon Athena

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Connection and sync

+ +

After connecting to a database, you’ll see the “Connection and sync” section that displays the current connection status and options to manage your database connection.

+ +

Here you can sync the database schema and rescan field values, and edit connection details.

+ +

Edit connection details

+ +

You can edit these settings at any time (and remember to save your changes).

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Region

+ +

The AWS region where your database is hosted, for Amazon Athena. For example, you might enter us-east-1.

+ +

Workgroup

+ +

AWS workgroup. For example: primary. See documentation on workgroups.

+ +

S3 Staging directory

+ +

This S3 staging directory must be in the same region you specify above.

+ +

Access key

+ +

Part of IAM credentials for AWS. Metabase will encrypt these credentials.

+ +

If you’re running Metabase on AWS and want to use AWS Default Credentials Chain, leave the Access and Secret keys blank.

+ +

See also our notes on connecting to Athena.

+ +

Secret Key

+ +

Part of IAM credentials for AWS. Metabase will encrypt these credentials.

+ +

Additional Athena connection string options

+ +

You can specify additional options via a string, e.g., UseResultsetStreaming=0;LogLevel=6.

+ +

Include User ID and query hash in queries

+ +

This can be useful for auditing and debugging, but prevents databases from caching results and may increase your costs. Enable this feature if you need to track which users are running specific queries.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Notes on connecting to Athena

+ +

If you use other AWS services, we recommend that you create a special AWS Service Account that only has the permissions required to run Athena, and input the IAM credentials from that account to connect Metabase to Athena.

+ +

See Identity and access management in Athena.

+ +

Connecting using AWS Default Credentials Chain

+ +

If you’re running Metabase on AWS and want to use AWS Default Credentials Chain, leave the Access and Secret keys blank.

+ + + +

In both cases, the Athena driver will automatically fetch session credentials based on which IAM role you’ve configured.

+ +

Permissions and IAM Policies

+ +

Most issues that we see when people attempt to connect to AWS Athena involve permissions. Querying AWS Athena requires permissions to:

+ +
    +
  • AWS Athena.
  • +
  • AWS Glue.
  • +
  • The S3 bucket where Athena results are stored.
  • +
  • The resources that Athena is querying against (i.e., the S3 bucket(s) Athena is querying).
  • +
  • If you’re using AWS Lake Formation, then you also need to grant AWS Lake Formation permissions through the AWS Console (AWS Lake Formation > Permissions > Data Lake Permissions > Grant data lake permissions; the role Metabase uses needs SELECT and DESCRIBE table permissions).
  • +
+ +

Example IAM Policy

+ +

This policy provides read-only permissions for data in S3. You’ll need to specify any S3 buckets that you want Metabase to be able to query from as well as the S3 bucket provided as part of the configuration where results are written to.

+ +

There may be additional permissions required for other Athena functionality, like federated queries. For details, check out the Athena docs.

+ +
{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Sid": "Athena",
+      "Effect": "Allow",
+      "Action": [
+        "athena:BatchGetNamedQuery",
+        "athena:BatchGetQueryExecution",
+        "athena:GetNamedQuery",
+        "athena:GetQueryExecution",
+        "athena:GetQueryResults",
+        "athena:GetQueryResultsStream",
+        "athena:GetWorkGroup",
+        "athena:ListDatabases",
+        "athena:ListDataCatalogs",
+        "athena:ListNamedQueries",
+        "athena:ListQueryExecutions",
+        "athena:ListTagsForResource",
+        "athena:ListWorkGroups",
+        "athena:ListTableMetadata",
+        "athena:StartQueryExecution",
+        "athena:StopQueryExecution",
+        "athena:CreatePreparedStatement",
+        "athena:DeletePreparedStatement",
+        "athena:GetPreparedStatement"
+      ],
+      "Resource": "*"
+    },
+    {
+      "Sid": "Glue",
+      "Effect": "Allow",
+      "Action": [
+        "glue:BatchGetPartition",
+        "glue:GetDatabase",
+        "glue:GetDatabases",
+        "glue:GetPartition",
+        "glue:GetPartitions",
+        "glue:GetTable",
+        "glue:GetTables",
+        "glue:GetTableVersion",
+        "glue:GetTableVersions"
+      ],
+      "Resource": "*"
+    },
+    {
+      "Sid": "S3ReadAccess",
+      "Effect": "Allow",
+      "Action": ["s3:GetObject", "s3:ListBucket", "s3:GetBucketLocation"],
+      "Resource": [
+        "arn:aws:s3:::bucket1",
+        "arn:aws:s3:::bucket1/*",
+        "arn:aws:s3:::bucket2",
+        "arn:aws:s3:::bucket2/*"
+      ]
+    },
+    {
+      "Sid": "AthenaResultsBucket",
+      "Effect": "Allow",
+      "Action": [
+        "s3:PutObject",
+        "s3:GetObject",
+        "s3:AbortMultipartUpload",
+        "s3:ListBucket",
+        "s3:GetBucketLocation"
+      ],
+      "Resource": ["arn:aws:s3:::bucket2", "arn:aws:s3:::bucket2/*"]
+    }
+  ]
+}
+
+ +

If Metabase also needs to create tables, you’ll need additional AWS Glue permissions. The "Resource": "*" key-value pair gives the account Delete and Update permissions to any table:

+ +
{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Sid": "VisualEditor0",
+      "Effect": "Allow",
+      "Action": [
+        "glue:BatchCreatePartition",
+        "glue:UpdateDatabase",
+        "glue:DeleteDatabase",
+        "glue:CreateTable",
+        "glue:CreateDatabase",
+        "glue:UpdateTable",
+        "glue:BatchDeletePartition",
+        "glue:BatchDeleteTable",
+        "glue:DeleteTable",
+        "glue:CreatePartition",
+        "glue:DeletePartition",
+        "glue:UpdatePartition",
+        "glue:GetCatalogImportStatus"
+      ],
+      "Resource": "*"
+    }
+  ]
+}
+
+

Model features

+ +

There aren’t (yet) any model features available for Athena.

+ +

Danger zone

+ +

See Danger Zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/aws-rds.html b/_site/docs/doc-update-detection/databases/connections/aws-rds.html new file mode 100644 index 000000000..6d03f5dc6 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/aws-rds.html @@ -0,0 +1,3064 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Connecting to AWS's Relational Database Service (RDS) | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Connecting to AWS’s Relational Database Service (RDS)

+ +

RDS offers several databases that Metabase officially supports, including PostgreSQL, MySQL, MariaDB, Oracle, and SQL server.

+ +

Here’s how to get connection information for databases on Amazon’s RDS:

+ +
    +
  1. Go to your AWS Management Console. +
      +
    • Need help finding that? Visit https://**My_AWS_Account_ID**.signin.aws.amazon.com/console. Be sure to insert your own AWS Account ID, though!
    • +
    +
  2. +
  3. Go to Database > RDS > Instances.
  4. +
  5. Select the database you want to connect to Metabase.
  6. +
  7. Get the information you’ll need to connect Metabase to your RDS: +
      +
    • Hostname. This is listed as the Endpoint parameter.
    • +
    • Port. Find the port parameter under Security and Network.
    • +
    • Username. Find this under Configuration Details.
    • +
    • Database Name. Find this under Configuration Details.
    • +
    • Password. Ask your database administrator for the password.
    • +
    +
  8. +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/bigquery.html b/_site/docs/doc-update-detection/databases/connections/bigquery.html new file mode 100644 index 000000000..abf98e781 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/bigquery.html @@ -0,0 +1,3231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Google BigQuery | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Google BigQuery

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Prerequisites

+ +

You’ll need to have a Google Cloud Platform account with a project you would like to use in Metabase. Consult the Google Cloud Platform documentation for how to create and manage a project. This project should have a BigQuery dataset for Metabase to connect to.

+ +

Google Cloud Platform: creating a service account and JSON file

+ +

You’ll first need a service account JSON file that Metabase can use to access your BigQuery dataset. Service accounts are intended for non-human users (such as applications like Metabase) to authenticate (who am I?) and authorize (what can I do?) their API calls.

+ +

To create the service account JSON file, follow Google’s documentation on setting up a service account for your BigQuery dataset. Here’s the basic flow:

+ +
    +
  1. +

    Create service account. From your Google Cloud Platform project console, open the main sidebar menu on the left, go to the IAM & Admin section, and select Service account. The console will list existing service accounts, if any. At the top of the screen, click on + CREATE SERVICE ACCOUNT.

    +
  2. +
  3. +

    Fill out the service account details. Name the service account, and add a description (the service account ID will populate once you add a name). Then click the Create button.

    +
  4. +
  5. +

    Grant the service account access to this project. You’ll need to add roles to the service account so that Metabase will have permission to view and run queries against your dataset. Make sure you add the following roles to the service account:

    + +
      +
    • BigQuery Data Viewer
    • +
    • BigQuery Metadata Viewer
    • +
    • BigQuery Job User (distinct from BigQuery User)
    • +
    +
  6. +
+ +

For more information on roles in BigQuery, see Google Cloud Platform’s documentation.

+ +
    +
  1. Create key. Once you have assigned roles to the service account, click on the Create Key button, and select JSON for the key type. The JSON file will download to your computer.
  2. +
+ +
+

You can only download the key once. If you delete the key, you’ll need to create another service account with the same roles.

+
+ +

Connection and sync

+ +

After connecting to a database, you’ll see the “Connection and sync” section that displays the current connection status and options to manage your database connection.

+ +

Here you can sync the database schema and rescan field values, and edit connection details.

+ +

Edit connection details

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Project ID

+ +

Each BigQuery dataset will have a Project ID. You can find this ID via the Google Cloud Console. If you’re not sure where to find the Project ID, see Google’s documentation on getting information on datasets.

+ +
+

When entering the Project ID, omit the Project ID prefix. For example, if your ID is project_name:project_id, only enter project_id.

+
+ +

Service account JSON file

+ +

The JSON file contains the credentials your Metabase application will need to access BigQuery datasets, as defined by the roles you added to the service account. If you need to add additional roles, you have to create another service account, download the JSON file, and upload the file to Metabase.

+ +

Datasets

+ +

You can specify which BigQuery datasets you want to sync and scan. Options are:

+ +
    +
  • All
  • +
  • Only these…
  • +
  • All except…
  • +
+ +
+

A BigQuery dataset is similar to a schema. Make sure to enter your dataset names (like marketing), not your table names (marketing.campaigns).

+
+ +

Let’s say you have three datasets: foo, bar, and baz.

+ +

To sync all three datasets, select Only these… and enter:

+ +
foo,bar,baz
+
+ +

To sync datasets based on a string match, use the * wildcard:

+ +
    +
  • To sync bar and baz, select Only these… and enter the string b*.
  • +
  • To sync foo only, select All except… and enter the string b*.
  • +
+ +

Note that only the * wildcard is supported; you can’t use other special characters or regexes.

+ +

Use the Java Virtual Machine (JVM) timezone

+ +

We suggest you leave this off unless you’re doing manual timezone casting in many or most of your queries with this data.

+ +

Include User ID and query hash in queries

+ +

This can be useful for auditing and debugging, but prevents BigQuery from caching results and may increase your costs.

+ +

Alternate hostname

+ +

If you want to use a different hostname to connect to BigQuery. Format: https://<hostname>:<port>. If you’re using a proxy service to connect to BigQuery (e.g. a privacy proxy that anonymizes PII), you should configure this field to the proxy hostname or IP. Remember to set the complete URI with protocol and port number.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Connecting Metabase to Google Drive data sources

+ +

You can connect Metabase to Google Drive data sources via BigQuery. There is some setup involved, but basically what you’ll be doing is creating a dataset in BigQuery and adding an external table to that dataset that points to a Google Sheet. Useful for uploading CSVs to Google Sheets, and then analyzing and visualizing the data with Metabase.

+ +

To connect to a data source stored in Google Drive (like a Google Sheet), first make sure you’ve completed the steps above, including:

+ +
    +
  • creating a project in Google Cloud Platform,
  • +
  • adding a BigQuery dataset, and
  • +
  • creating a service account.
  • +
+ +

Share your Google Drive source with the service account

+ +

While viewing your Drive file, (e.g., a Google Sheet with an uploaded CSV file), click the Share button in the top right. In the text box labeled Add people or groups, paste in the email of your service account, which you can find on the Service Accounts page in the Google Cloud Console.

+ +

That email address will look something like service-account-name@your-project-name.iam.gserviceaccount.com, with the your service account and project names filled in accordingly.

+ +

Choose Viewer from the dropdown, uncheck the Notify people option, and click Share.

+ +

Create an external table in BigQuery that points to your Google Drive source

+ +

If you don’t already have a BigQuery dataset, create one.

+ +

Next, using the Google Cloud Console, create an external table within your BigQuery dataset that points to your Google Sheet.

+ +

Be sure to specify the correct Drive URI and file format.

+ +

If you haven’t already, connect your Metabase to your BigQuery.

+ +

Once you’ve completed these steps, you’ll be able to ask questions and create dashboards in Metabase using a Google Drive source as your data.

+ +

Using Legacy SQL

+ +

As of version 0.30.0, Metabase tells BigQuery to interpret SQL queries as Standard SQL (GoogleSQL). If you prefer using Legacy SQL instead, you can tell Metabase to do so by including a #legacySQL directive at the beginning of your query, for example:

+ +
#legacySQL
+SELECT *
+FROM [my_dataset.my_table]
+
+ +

Troubleshooting

+ +

If you’re having trouble with your BigQuery connection, you can check out this troubleshooting guide that covers BigQuery issues, this one on data warehouse connections, or visit Metabase’s discussion forum to see if someone has encountered and resolved a similar issue.

+ +

Model features

+ +

There aren’t (yet) any model features available for BigQuery.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/clickhouse.html b/_site/docs/doc-update-detection/databases/connections/clickhouse.html new file mode 100644 index 000000000..4261dacb1 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/clickhouse.html @@ -0,0 +1,3141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ClickHouse | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

ClickHouse

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Connection and Sync

+ +

After connecting to a database, you’ll see the “Connection and sync” section that displays the current connection status and options to manage your database connection.

+ +

Here you can sync the database schema and rescan field values, and edit connection details.

+ +

Edit connection details

+ +

To access or modify your database connection settings, click the Edit connection details button.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address (e.g., 98.137.149.56) or its domain name (e.g., name.database.com).

+ +

Port

+ +

The database port (e.g., 8123).

+ +

Username

+ +

The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of privileges.

+ +

Password

+ +

The password for the username that you use to connect to the database.

+ +

Databases

+ +

Include all of the database you want to be able to query in Metabase. Separate databases with the space character, e.g., db1 db2 db3.

+ +

Scan all databases

+ +

Scan all tables from all available ClickHouse databases except the system ones.

+ +

Use a secure connection (SSL)

+ +

See SSL certificates.

+ +

Use an SSH-tunnel

+ +

If a direct connection to your database isn’t possible, you may want to use an SSH tunnel. See SSH tunneling.

+ +

Disable system wide proxy settings

+ +

System-wide proxy settings are disabled by default. You can disable them with this toggle.

+ +

ClickHouse settings (comma-separated)

+ +

Here you can add a string to specify additional ClickHouse settings. Separate settings with a comma, like so:

+ +
allow_experimental_analyzer=1,max_result_rows=100
+
+ +

Max open HTTP connections in the JDBC driver (default: 100)

+ +

You can limit the number of HTTP connections in the JDBC driver used to connect Metabase to ClickHouse.

+ +

Additional JDBC connection string options

+ +

You can append options to the JDBC connection string. Separate options with &, like so:

+ +
connection_timeout=1000&socket_timeout=300000
+
+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Model features

+ +

There aren’t (yet) any model features for ClickHouse.

+ +

Danger zone

+ +

See Danger zone.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/databricks.html b/_site/docs/doc-update-detection/databases/connections/databricks.html new file mode 100644 index 000000000..18065a34b --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/databricks.html @@ -0,0 +1,3150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Databricks | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Databricks

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database. Then select Databricks.

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Edit connection details

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address, or its domain name (e.g., xxxxxxxxxx.cloud.databricks.com or adb-xxxxx.azuredatabricks.net). This is the value of your Databrick’s compute resource’s Server Hostname.

+ +

See Compute settings for the Databricks JDBC Driver.

+ +

HTTP path

+ +

This is the Databrick’s compute resources HTTP Path value. This value is often a SQL warehouse endpoint in the format /sql/1.0/endpoints/abcdef1234567890. See Connect to a SQL warehouse.

+ +

Additionally, see Compute settings for the Databricks JDBC Driver.

+ +

Authentication

+ +

There are two ways to authenticate with Databricks. You can use a personal access token (PAT) or a service principal using OAuth (OAuth M2M).

+ +

The Databricks driver supports both options. Use the toggle to select the authentication method you want to use.

+ +

Personal access token authentication

+

See Personal Access Token (PAT).

+ +

Authenticate access with a service principal using OAuth (OAuth M2M)

+ +

See Authenticate access with a service principal using OAuth.

+ +

Catalog

+

For now, you can only select one catalog. Metabase doesn’t support multi-catalog connections. If you want to use more than one catalog in Metabase, you can set up multiple connections, each selecting a different catalog.

+ +

You can’t sync Databricks’s legacy catalogs, however, including the samples or hive_metastore catalogs.

+ +

Schemas

+ +

You can specify which schemas you want to sync and scan. Options are:

+ +
    +
  • All
  • +
  • Only these…
  • +
  • All except…
  • +
+ +

For the Only these and All except options, you can input a comma-separated list of values to tell Metabase which schemas you want to include (or exclude). For example:

+ +
foo,bar,baz
+
+ +

You can use the * wildcard to match multiple schemas.

+ +

Let’s say you have three schemas: foo, bar, and baz.

+ +
    +
  • If you have Only these… set, and enter the string b*, you’ll sync with bar and baz.
  • +
  • If you have All except… set, and enter the string b*, you’ll just sync foo.
  • +
+ +

Note that only the * wildcard is supported; you can’t use other special characters or regexes.

+ +

Additional JDBC connection string options

+ +

You can append options to the connection string that Metabase uses to connect to your database. E.g., IgnoreTransactions=0.

+ +

See Compute settings for the Databricks JDBC Driver.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any summarizations or filters in the query builder.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Model features

+ +

There aren’t (yet) any model features available for Databricks.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/druid.html b/_site/docs/doc-update-detection/databases/connections/druid.html new file mode 100644 index 000000000..095267dcd --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/druid.html @@ -0,0 +1,3122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Druid | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Druid

+ +
+

Prefer the Druid JDBC connection.

+
+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Edit connection details

+ +

Fill out the fields for that database, and click Save changes at the bottom. You can edit these settings at any time. Just remember to save your changes.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address, or its domain name (e.g., esc.mydatabase.com).

+ +

Broker node port

+ +

The database port (e.g, 8082).

+ +

Use an SSH tunnel

+ +

See our guide to SSH tunneling.

+ +

Allow unfolding of JSON columns

+ +
+

Only available for the Druid JDBC connection.

+
+ +

This enables unfolding of JSON columns into their component fields.

+ +

See JSON unfolding.

+ +

Authentication

+ +
+

Only available for the Druid JDBC connection.

+
+ +

Toggle on to enable basic authentication with a username and password.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Model features

+ +

There aren’t (yet) any model features available for Druid.

+ +

Danger zone

+ +

See Danger Zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/h2.html b/_site/docs/doc-update-detection/databases/connections/h2.html new file mode 100644 index 000000000..69161b4c0 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/h2.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/databases/connections/mariadb.html b/_site/docs/doc-update-detection/databases/connections/mariadb.html new file mode 100644 index 000000000..6a9f2d876 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/mariadb.html @@ -0,0 +1,3152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +MariaDB | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

MariaDB

+ +
+

This page covers connecting to MariaDB as a data warehouse. For using MariaDB as Metabase’s application database, see Configuring the Metabase application database.

+
+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

MariaDB shares a driver with MySQL, so select the MySQL driver.

+ +

Supported versions

+ +

Metabase supports the oldest supported version of Maria DB through the latest stable version. See MariaDB Server releases.

+ +

Edit connection details

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address, or its domain name (e.g., esc.mydatabase.com).

+ +

Port

+ +

The database port. E.g., 3306.

+ +

Username

+ +

The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of privileges.

+ +

Password

+ +

The password for the username that you use to connect to the database.

+ +

Use a secure connection (SSL)

+ +

You can paste your server’s SSL certification chain.

+ +

Use an SSH tunnel

+ +

See our guide to SSH tunneling.

+ +

Unfold JSON Columns

+ +

JSON folding is not supported for MariaDB databases.

+ +

Additional JDBC connection string options

+ +

You can append options to the connection string that Metabase uses to connect to your database.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any summarize) or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Database syncing

+ +

If you’ve selected Choose when syncs and scans happen > ON, you’ll be able to set:

+ +
    +
  • The frequency of the sync: hourly (default) or daily.
  • +
  • The time to run the sync, in the timezone of the server where your Metabase app is running.
  • +
+ +

Scanning for filter values

+ +

Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database.

+ +

If you’ve selected Choose when syncs and scans happen > ON, you’ll see the following options under Scanning for filter values:

+ +
    +
  • Regularly, on a schedule allows you to run scan queries at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often.
  • +
  • Only when adding a new filter widget is a great option if you want scan queries to run on demand. Turning this option ON means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question.
  • +
  • Never, I’ll do this manually if I need to is an option for databases that are either prohibitively large, or which never really have new values added. Use the Re-scan field values button to run a manual scan and bring your filter values up to date.
  • +
+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Syncing records that include JSON

+ +

JSON schema inference doesn’t work with MariaDB, due to implementation differences between MySQL and MariaDB.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/mongodb.html b/_site/docs/doc-update-detection/databases/connections/mongodb.html new file mode 100644 index 000000000..0490d1503 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/mongodb.html @@ -0,0 +1,3194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +MongoDB | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

MongoDB

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Supported versions

+ +

Metabase supports the oldest supported version of MongoDB through the latest stable version. See MongoDB Software Lifecycle Schedules.

+ +

Connecting to MongoDB

+ +

There are two ways to connect to MongoDB:

+ +
    +
  1. Using the Metabase fields to input your connection details.
  2. +
  3. Pasting your connection string.
  4. +
+ +

Using Metabase fields

+ +

The default way to connect to MongoDB is to fill out your connection details in the fields Metabase provides:

+ +
    +
  • Host
  • +
  • Database name
  • +
  • Port
  • +
  • Username
  • +
  • Password
  • +
  • Authentication Database (optional)
  • +
  • Additional connection string options (optional)
  • +
+ +

You’ll also have the option to Use a secure connection (SSL). Enable SSL and paste the contents of the server’s SSL certificate chain in the input text box. This option is available for this method of connection only (i.e. you cannot include a certificate when connecting with a connection string).

+ +

Advanced settings for direct connection

+ +
    +
  • Use DNS SRV when connecting Using this option requires that provided host is a FQDN. If connecting to an Atlas cluster, you might need to enable this option. If you don’t know what this means, leave this disabled.
  • +
+ +

Using a connection string

+ +

If you’d prefer to connect to MongoDB using a connection string, click on Paste a connection string. The Metabase user interface will update with a field to paste your connection string.

+ +

Metabase currently does NOT support the following connection string parameters:

+ +
    +
  • tlsCertificateKeyFile
  • +
  • tlsCertificateKeyFilePassword
  • +
  • tlsCAFile
  • +
+ +

If you need to use a certificate, connect via the default method and enable Use a secure connection(SSL).

+ +

Settings common to both connection options

+ +
    +
  • Use an SSH tunnel: Some database installations can only be accessed by connecting through an SSH bastion host. This option also provides an extra layer of security when a VPN is not available. Enabling this is usually slower than a direct connection.
  • +
  • Rerun queries for simple exploration: When this is on, Metabase will automatically run queries when users do simple explorations with the Summarize and Filter buttons when viewing a table or chart. You can turn this off if querying this database is slow. This setting doesn’t affect drill-throughs or SQL queries.
  • +
  • Choose when syncs and scans happen: See syncs and scans.
  • +
  • Periodically refingerprint tables: This setting — disabled by default — enables Metabase to scan for additional field values during syncs allowing smarter behavior, like improved auto-binning on your bar charts.
  • +
+ +

Connecting to a MongoDB Atlas cluster

+ +

Whitelist IP addresses

+ +

If you are using Metabase Cloud, you’ll need to whitelist Metabase Cloud IP addresses in your Atlas cluster. If you are using self-hosted Metabase, you’ll need to whitelist the IP of your Metabase instance.

+ +
    +
  1. Log into your Atlas cluster
  2. +
  3. Go to Network Access
  4. +
  5. Add the IP addresses that your Metabase uses to connect.
  6. +
+ +

Connect Metabase to your Atlas cluster

+ +
+

The connection string provided in Atlas “Connect” interface does not include the database. Metabase requires you to provide a database name when connecting, so you’ll need to edit the connection string to add the database name.

+
+ +
    +
  1. +

    Log into your Atlas account

    +
  2. +
  3. +

    Select the cluster you want to connect to, and click Connect.

    + +

    Your cluster screengrab

    +
  4. +
  5. +

    Select Drivers.

    +
  6. +
  7. +

    Copy the connection string from Add your connection string into your application code section.

    + +

    Connect screengrab

    +
  8. +
  9. In Metabase, go to Admin -> Databases, and click the Add database button.
  10. +
  11. Select MongoDB from the dropdown, and enter a Display name for this database.
  12. +
  13. Click on “Paste the connection string” and paste your connection string.
  14. +
  15. +

    Edit the connection string to include the name of the database after /:

    + +
    mongodb+srv://metabot:metapass@my-test-cluster.a5ej7.mongodb.net/DATABASE_NAME?retryWrites=true&w=majority&appName=my-test-cluster
    +
    +
  16. +
+ +

If you’re using Metabase fields to input connection information for your Atlas cluster instead of using the connection string, you might need to turn on Use DNS SRV when connecting.

+ +

See more information about Advanced options.

+ +

Configuring SSL via the command line

+ +

You can enter a self-signed certificate via the Metabase UI (though not when using a connection string), or you can use the command line to add a self-signed certificate.

+ +
cp /usr/lib/jvm/default-jvm/jre/lib/security/cacerts ./cacerts.jks
+keytool -import -alias cacert -storepass changeit -keystore cacerts.jks -file my-cert.pem
+
+ +

Then, start Metabase using the store:

+ +
java -Djavax.net.ssl.trustStore=cacerts.jks -Djavax.net.ssl.trustStorePassword=changeit -jar metabase.jar
+
+ +

Learn more about configuring SSL with MongoDB.

+ +

How Metabase syncs data in MongoDB

+ +

Because MongoDB contains unstructured data, Metabase takes a different approach to syncing your database’s metadata. To get a sense of the schema, Metabase will query the first and last 500 documents (most of the calculation is done in MongoDB). This sampling helps Metabase do things like differentiate datetime fields from string fields, and provide people with pre-populated filters. The reason Metabase only scans a sample of the documents is because scanning every document in every collection on every sync would put too much strain on your database. And while the sampling does a pretty good job keeping Metabase up to date, it can also mean that new fields can sometimes fall through the cracks, leading to visualization issues, or even fields failing to appear in your results. For more info, check out our troubleshooting guide.

+ +

General connectivity concerns

+ +
    +
  • Connect using DNS SRV, which is the recommended method for newer Atlas clusters.
  • +
  • Have you checked your cluster host whitelist? When testing a connection but seeing failure, have you tried setting the IP whitelist to 0.0.0.0/0? Whitelisting this address allows connections from any IP addresses. If you know the IP address(es) or CIDR block of clients, use that instead.
  • +
  • Connect to the secondary server. When connecting to a cluster, always use the ?readPreference=secondary argument in the connection string, which allows Metabase to read from a secondary server instead of consuming resources from the primary server.
  • +
+ +

I added fields to my database but don’t see them in Metabase

+ +

Metabase may not sync all of your fields. Since any document in a MongoDB collection can contain any number of fields, the only way to get 100% coverage of all fields would be to scan every single document in every single collection. The reason Metabase doesn’t do a full scan is because it would put too much strain on your database.

+ +

Instead, Metabase gets a sample of the fields in a collection by scanning a sample of 1000 documents in each collection (the first 500 documents and the last 500 documents in each collection).

+ +

If you’re not seeing all of the fields show up for a collection in Metabase, one workaround is to include all possible keys in the first document of the collection, and give those keys null values. That way, Metabase will be able to recognize the correct schema for the entire collection.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ +

See our troubleshooting guide for troubleshooting your connection.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/mysql.html b/_site/docs/doc-update-detection/databases/connections/mysql.html new file mode 100644 index 000000000..058d07ba3 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/mysql.html @@ -0,0 +1,3239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +MySQL | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

MySQL

+ +
+

This page covers connecting to MySQL as a data warehouse. For using MySQL as Metabase’s application database, see Configuring the Metabase application database.

+
+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Supported versions

+ +

Metabase supports the oldest supported version through the latest stable version. See MySQL end-of-life dates.

+ +

Edit connection details

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address, or its domain name (e.g., esc.mydatabase.com).

+ +

Port

+ +

The database port. E.g., 3306.

+ +

Username

+ +

The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of privileges.

+ +

Password

+ +

The password for the username that you use to connect to the database.

+ +

Use a secure connection (SSL)

+ +

You can paste your server’s SSL certification chain.

+ +

Use an SSH tunnel

+ +

See our guide to SSH tunneling.

+ +

Unfold JSON Columns

+ +

For MySQL databases, Metabase can unfold JSON columns into component fields to yield a table where each JSON key becomes a column. JSON unfolding is on by default, but you can turn off JSON unfolding if performance is slow.

+ +

If you turn on JSON unfolding, you can also toggle the unfolding for individual columns in table metadata.

+ +

Additional JDBC connection string options

+ +

You can append options to the connection string that Metabase uses to connect to your database.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Connecting to MySQL 8+ servers

+ +

Metabase uses the MariaDB connector to connect to MySQL servers. The MariaDB connector lacks support for MySQL 8’s default authentication plugin. In order to connect, you’ll need to change the plugin used by the Metabase user:

+ +
mysql_native_password`: `ALTER USER 'metabase'@'%' IDENTIFIED WITH mysql_native_password BY 'thepassword';
+
+ +

Unable to log in with correct credentials

+ +

How to detect this: Metabase fails to connect to your MySQL server with the error message “Looks like the username or password is incorrect”, but you’re sure that the username and password is correct. You may have created the MySQL user with an allowed host other than the host you’re connecting from.

+ +

For example, if the MySQL server is running in a Docker container, and your metabase user was created with CREATE USER 'metabase'@'localhost' IDENTIFIED BY 'thepassword';, the localhost will be resolved to the Docker container, and not the host machine, causing access to be denied.

+ +

You can identify this issue by looking in the Metabase server logs for the error message:

+ +
Access denied for user 'metabase'@'172.17.0.1' (using password: YES).
+
+ +

Note the host name 172.17.0.1 (in this case a Docker network IP address), and using password: YES at the end.

+ +

You’ll see the same error message when attempting to connect to the MySQL server with the command-line client: mysql -h 127.0.0.1 -u metabase -p.

+ +

How to fix this: Recreate the MySQL user with the correct host name:

+ +
CREATE USER 'metabase'@'172.17.0.1' IDENTIFIED BY 'thepassword';
+
+ +

Otherwise, if necessary, a wildcard may be used for the host name:

+ +
CREATE USER 'metabase'@'%' IDENTIFIED BY 'thepassword';
+
+ +

That user’s permissions will need to be set:

+ +
GRANT SELECT ON targetdb.* TO 'metabase'@'172.17.0.1';
+FLUSH PRIVILEGES;
+
+ +

Remember to drop the old user:

+ +
DROP USER 'metabase'@'localhost';
+
+ +

If you can’t connect to the database, but the user, host, and password are correct, try adding trustServerCertificate=true to the additional JDBC options. This option will tell the Metabase driver to trust the server certificate even though it lacks a root certificate, and it should establish a secure connection.

+ +

Syncing records that include JSON

+ +

Metabase will infer the JSON “schema” based on the keys in the first five hundred rows of a table. MySQL JSON fields lack schema, so Metabase can’t rely on table metadata to define which keys a JSON field has. To work around the lack of schema, Metabase will get the first five hundred records and parse the JSON in those records to infer the JSON’s “schema”. The reason Metabase limits itself to five hundred records is so that syncing metadata doesn’t put unnecessary strain on your database.

+ +

The problem is that, if the keys in the JSON vary record to record, the first five hundred rows may not capture all the keys used by JSON objects in that JSON field. To get Metabase to infer all the JSON keys, you’ll need to add the additional keys to the JSON objects in the first five hundred rows.

+ +

Raising a MySQL Docker container of MySQL 8+

+ +

If you are spinning up a new MySQL container, and:

+ +
    +
  • you want Metabase to connect to the container without having to manually create the user or change the authentication mechanism,
  • +
  • or you’re facing a RSA public key is not available client side (option serverRsaPublicKeyFile not set) error,
  • +
+ +

Use the ['--default-authentication-plugin=mysql_native_password'] modifiers when you run the container, like so:

+ +
    +
  • +

    a simple docker run: docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=xxxxxx mysql:8.xx.xx --default-authentication-plugin=mysql_native_password

    +
  • +
  • +

    or in docker-compose:

    +
  • +
+ +
mysql:
+  image: mysql:8.xx.xx
+  container_name: mysql
+  hostname: mysql
+  ports:
+    - 3306:3306
+  environment:
+    - "MYSQL_ROOT_PASSWORD=xxxxxx"
+    - "MYSQL_USER=metabase"
+    - "MYSQL_PASSWORD=xxxxxx"
+    - "MYSQL_DATABASE=metabase"
+  volumes:
+    - $PWD/mysql:/var/lib/mysql
+  command: ["--default-authentication-plugin=mysql_native_password"]
+
+ +

Limitations with Vitess-based databases

+ +
    +
  • +

    When querying Vitess databases (like Planetscale), you should add a LIMIT clause inside each subquery.

    + +

    The reason: typically, Metabase applies limits (e.g., 2000 or 10000 rows) to the final query results. But due to a known bug in Vitess, Vitess might apply these limits to subqueries, which can lead to unexpected results (for example, not all rows of results will be displayed within Metabase). The workaround is to add limits to each of your subqueries.

    +
  • +
  • +

    You may want to check in with the vendor that’s hosting the platform, as Vitess can run into issues returning metadata from the information schema. Metabase needs this metadata to populate its application database; if Metabase can’t get that metadata, fields may not appear (or appear empty).

    +
  • +
+ +

Model features

+ +

Choose whether to enable features related to Metabase models. These features will often require that the database user account, the one you use to connect to your database, has both read and write privileges.

+ +

Model actions

+ +

Turn this setting on to allow actions from models created from this data to be run. Actions are able to read, write, and possibly delete data. Your database user will need write permissions.

+ +

Model persistence

+ +

We’ll create tables with model data and refresh them on a schedule you define. To enable model persistence, you need to grant this connection’s credentials read and write permissions on a schema Metabase provides.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/oracle.html b/_site/docs/doc-update-detection/databases/connections/oracle.html new file mode 100644 index 000000000..b33b4360d --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/oracle.html @@ -0,0 +1,3176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Oracle | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Oracle

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Supported versions

+ +

Metabase supports the oldest supported version through the latest stable version. See Oracle’s Release Schedule of Current Database Releases.

+ +

Edit connection details

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address, or its domain name (e.g., esc.mydatabase.com).

+ +

Port

+ +

The database port. E.g., 1521.

+ +

Oracle system ID (SID)

+ +

Usually something like ORCL or XE. Optional if using service name.

+ +

Oracle service name

+ +

Optional TNS alias.

+ +

Username

+ +

The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of privileges.

+ +

Password

+ +

The password for the username that you use to connect to the database.

+ +

Use a secure connection (SSL)

+ +

You can use both client and server authentication (known as mutual authentication).

+ +

Connecting to Oracle Cloud Autonomous Database

+ +

If you’ve configured your database to require mutual TLS (mTLS), you’ll need a wallet. To download your wallet:

+ +
    +
  1. Go to your Oracle Autonomous Database.
  2. +
  3. Go to the database’s details.
  4. +
  5. Click on DB connection.
  6. +
  7. Download the wallet.
  8. +
  9. Create a password for the keyfile.
  10. +
  11. Copy the keystore.jks file to wherever you store your Metabase configuration data.
  12. +
  13. Use JAVA_OPTS to let Metabase know about the keystore’s location and password (for more info on keystores, see the next section).
  14. +
  15. In Metabase, on the data connection page, enter your host, port, and service_name. You can find these values in the tsnnames.ora file.
  16. +
+ +

Client authentication with a keystore

+ +

To configure the server (the Oracle server) to authenticate the identity of the client (Metabase), you need to +configure a keystore file that includes the client’s private key.

+ +

You’ll import the client’s private key into the keystore (rather than a root CA into a truststore file). Add the following JVM options for Metabase:

+ +
-Djavax.net.ssl.keyStore=/path/to/keystore.jks
+-Djavax.net.ssl.keyStoreType=JKS \
+-Djavax.net.ssl.keyStorePassword=<keyStorePassword>
+
+ +

You can define these with the JAVA_OPTS environment variable, like so:

+ +
JAVA_OPTS: "-Djavax.net.ssl.keyStore=/scripts/keystore.jks -Djavax.net.ssl.keyStoreType=JKS -Djavax.net.ssl.keyStorePassword=<keyStorePassword>"
+
+ +

With this done, the Oracle server will authenticate Metabase using the private key when Metabase tries to connect over SSL.

+ +

Server authentication with a truststore

+ +

To configure the client (Metabase) to authenticate the identity of the server (the Oracle server), you may need to +configure a truststore file that includes the server’s root CA, so that the JVM running Metabase trusts its +certificate chain. Refer to the +Oracle documentation on using keytool to manage key and truststore files, importing certificates, etc.

+ +

For more information on setting up a truststore for AWS RDS Oracle instances, see the +instructions provided by Amazon.

+ +

If you need to connect to other databases using SSL, instead of creating a new truststore, you’ll probably want to add the RDS CA to your existing truststore file (likely called cacerts).

+ +

Supported Oracle database and Oracle driver versions

+ +
    +
  • Driver version: the minimum Oracle driver version should be 19c, regardless of which Java version or Oracle database version you have.
  • +
  • Database version: the minimum database version should be version 19c, as Oracle no longer supports database versions before 19.
  • +
+ +

Downloading the Oracle JDBC Driver JAR

+ +

You can download a JDBC driver from Oracle’s JDBC driver downloads page.

+ +

We recommend using the ojdbc8.jar JAR.

+ +

Adding the Oracle JDBC Driver JAR to the Metabase plugins directory

+ +

In your Metabase directory (the directory where you keep and run your metabase.jar), create a directory called plugins (if it doesn’t already exist.

+ +

Move the JAR you just downloaded (ojdbc8.jar) into the plugins directory, and restart Metabase. Metabase will automatically make the Oracle driver available when it starts back up.

+ +

When running from a JAR

+ +

By default, the plugins directory is called plugins, and lives in the same directory as the Metabase JAR.

+ +

For example, if you’re running Metabase from a directory called /app/, you should move the Oracle JDBC driver JAR to /app/plugins/:

+ +
# example directory structure for running Metabase with Oracle support
+/app/metabase.jar
+/app/plugins/ojdbc8.jar
+
+ +

When running from Docker

+ +

The process for adding plugins when running via Docker is similar, but you’ll need to mount the plugins directory. Refer to instructions here for more details.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/postgresql.html b/_site/docs/doc-update-detection/databases/connections/postgresql.html new file mode 100644 index 000000000..38a4d3d9b --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/postgresql.html @@ -0,0 +1,3257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +PostgreSQL | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

PostgreSQL

+ +
+

This page covers connecting to PostgreSQL as a data warehouse. For using PostgreSQL as Metabase’s application database, see Configuring the Metabase application database.

+
+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Fill out the fields for that database, and click Save changes at the bottom.

+ +

Supported versions

+ +

Metabase supports the oldest supported version of PostgreSQL through the latest stable version. See PostgreSQL versions.

+ +

Connection and sync

+ +

After connecting to a database, you’ll see the “Connection and sync” section that displays the current connection status and options to manage your database connection.

+ +

Here you can sync the database schema and rescan field values, and edit connection details.

+ +

Edit connection details

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address, or its domain name (e.g., esc.mydatabase.com).

+ +

Port

+ +

The database port. E.g., 5432.

+ +

Database name

+ +

The name of the database you’re connecting to.

+ +

Username

+ +

The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of privileges.

+ +

Password

+ +

The password for the username that you use to connect to the database.

+ +

Use an authentication provider

+ +
+
+ + + + + + + +

Authenticating with a provider is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Instead of a password, you can authenticate with a supported provider.

+ +

Only for self-hosted Pro and Enterprise plans.

+ +

Azure Managed Identity

+ +

To use Azure Managed Identity, you’ll need to input your client ID.

+ +

Oauth

+ +

To use Oauth as a provider, you’ll need to input your:

+ +
    +
  • Auth token URL
  • +
  • Auth token request headers (a JSON map)
  • +
+ +

Schemas

+ +

You can specify which schemas you want to sync and scan. Options are:

+ +
    +
  • All
  • +
  • Only these…
  • +
  • All except…
  • +
+ +

For the Only these and All except options, you can input a comma-separated list of values to tell Metabase which schemas you want to include (or exclude). For example:

+ +
foo,bar,baz
+
+ +

You can use the * wildcard to match multiple schemas.

+ +

Let’s say you have three schemas: foo, bar, and baz.

+ +
    +
  • If you have Only these… set, and enter the string b*, you’ll sync with bar and baz.
  • +
  • If you have All except… set, and enter the string b*, you’ll just sync foo.
  • +
+ +

Note that only the * wildcard is supported; you can’t use other special characters or regexes.

+ +

Use a secure connection (SSL)

+ +

Metabase automatically tries to connect to databases with SSL first, then without if that doesn’t work. If it’s possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we highly recommend keeping SSL turned on to keep your data secure.

+ +

SSL Mode

+ +

PostgreSQL databases support different levels of security with their connections, with different levels of overhead.

+ +

SSL Mode options include:

+ +
    +
  • allow
  • +
  • prefer
  • +
  • require
  • +
  • verify-ca
  • +
  • verify-full
  • +
+ +

See the PostgreSQL docs for a table about the different SSL Modes, and select the option that works for you.

+ +

SSL root certificate (PEM)

+ +

If you set the SSL Mode to either “verify-ca” or “verify-full”, you’ll need to specify a root certificate (PEM). You have the option of using a Local file path or an Uploaded file path. If you’re on Metabase Cloud, you’ll need to select Uploaded file path and upload your certificate.

+ +

Authenticate client certificate

+ +

Toggle on to bring up client certificate options.

+ +

SSL Client Certificate (PEM)

+ +

You have the option of using a Local file path or an Uploaded file path. If you’re on Metabase Cloud, you’ll need to select Uploaded file path and upload your certificate.

+ +

SSL Client Key (PKCS-8/DER)

+ +

Again, you have the option of using a Local file path or an Uploaded file path. If you’re on Metabase Cloud, you’ll need to select Uploaded file path and upload your certificate. You’ll also need to input your SSL Client Key Password.

+ +

The private key must be PKCS8 and stored in DER format.

+ +

If you instead have a PEM SSL client key, you can convert that key to the PKCS-8/DER format using openssl. The command would look something like:

+ +
openssl pkcs8 -topk8 -inform PEM -outform DER -in client-key.pem -out client-key.der -nocrypt
+
+ +

Note: if you’re using GCP and you managed to issue client certificates, everything will be given in PEM format, you only need to transform the client-key.pem into a client-key.der for the “SSL Client Key”

+ +

Use an SSH tunnel

+ +

See our guide to SSH tunneling.

+ +

Unfold JSON Columns

+ +

For PostgreSQL databases, Metabase can unfold JSON columns into component fields to yield a table where each JSON key becomes a column. JSON unfolding is on by default, but you can turn off JSON unfolding if performance is slow.

+ +

If you turn on JSON unfolding, you can also toggle the unfolding for individual columns in table metadata.

+ +

Additional JDBC connection string options

+ +

You can append options to the connection string that Metabase uses to connect to your database. Use the format:

+ +
options=-c%20key=value
+
+ +

PostgreSQL connection URIs expect percent-encoding for whitespaces and symbols.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Model features

+ +

Choose whether to enable features related to Metabase models. These features will often require that the database user account, the one you use to connect to your database, has both read and write privileges.

+ +

Model actions

+ +

Turn this setting on to allow actions from models created from this data to be run. Actions are able to read, write, and possibly delete data. Your database user will need write permissions.

+ +

Model persistence

+ +

We’ll create tables with model data and refresh them on a schedule you define. To enable model persistence, you need to grant this connection’s credentials read and write permissions on a schema Metabase provides.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/presto.html b/_site/docs/doc-update-detection/databases/connections/presto.html new file mode 100644 index 000000000..adecd749e --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/presto.html @@ -0,0 +1,3144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Presto | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Presto

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Fill out the fields for that database, and click Save changes at the bottom.

+ +

Edit connection details

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address, or its domain name (e.g., esc.mydatabase.com).

+ +

Port

+ +

The database port. E.g., 8080.

+ +

Catalog

+ +

Presto catalogs contain schemas and reference data sources via a connector.

+ +

Schema (optional)

+ +

Only add tables to Metabase that come from a specific schema.

+ +

Username

+ +

The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of privileges.

+ +

Password

+ +

The password for the username that you use to connect to the database.

+ +

Use a secure connection (SSL)

+ +

Metabase automatically tries to connect to databases with SSL first, then without if that doesn’t work. If it’s possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we highly recommend keeping SSL turned on to keep your data secure.

+ +

Use SSL certificate?

+ +

Metabase supports both keystores and truststores.

+ +

Keystore

+ +

You can specify a local file path, or upload a keystore. You’ll also need to input your keystore password.

+ +

Truststore

+ +

You can specify a local file path, or upload a truststore. You’ll also need to input your truststore password.

+ +

Authenticate with Kerberos

+ +

Kerberos settings include:

+ +
    +
  • Kerberos principal (e.g., service/instance@REALM)
  • +
  • Kerberos coordinator service (e.g., presto)
  • +
  • You can use a canonical hostname.
  • +
  • Kerberos credential cache file (e.g., /tmp/kerbo-credential-cache)
  • +
  • Kerberos keytab file (e.g., /path/to/kerberos.keytab)
  • +
  • Kerberos configuration file (e.g., /etc/krb5.conf)
  • +
  • Presto coordinator Kerberos service principal pattern (e.g., ${SERVICE}@${HOST}.${SERVICE}
  • +
+ +

Additional JDBC connection string options

+ +

You can append options to the connection string that Metabase uses to connect to your database.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/redshift.html b/_site/docs/doc-update-detection/databases/connections/redshift.html new file mode 100644 index 000000000..373aba4e7 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/redshift.html @@ -0,0 +1,3158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Amazon Redshift | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Amazon Redshift

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Connection and sync

+ +

After connecting to a database, you’ll see the “Connection and sync” section that displays the current connection status and options to manage your database connection.

+ +

Here you can sync the database schema and rescan field values, and edit connection details.

+ +

Edit connection details

+ +

To access or modify your database connection settings, click the Edit connection details button.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address, or its domain name (e.g., esc.mydatabase.com).

+ +

Port

+ +

The database port. E.g., 3306.

+ +

Database name

+ +

The name of the database you want to connect to.

+ +

Schemas

+ +

Here you can specify which schemas you want to sync and scan. Options are:

+ +
    +
  • All
  • +
  • Only these…
  • +
  • All except…
  • +
+ +

For the Only these and All except options, you can input a comma-separated list of values to tell Metabase which schemas you want to include (or exclude). For example:

+ +
foo,bar,baz
+
+ +

You can use the * wildcard to match multiple schemas.

+ +

Let’s say you have three schemas: foo, bar, and baz.

+ +
    +
  • If you have Only these… set, and enter the string b*, you’ll sync with bar and baz.
  • +
  • If you have All except… set, and enter the string b*, you’ll just sync foo.
  • +
+ +

Note that only the * wildcard is supported; you can’t use other special characters or regexes.

+ +

Username

+ +
+

In order for sync and scan to work, make sure this database user account has access to the information_schema.

+
+ +

The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of privileges.

+ +

Password

+ +

The password for the username that you use to connect to the database.

+ +

Use an SSH tunnel

+ +

See our guide to SSH tunneling.

+ +

Additional JDBC connection string options

+ +

You can append options to the connection string that Metabase uses to connect to your database.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Model features

+ +

Choose whether to enable features related to Metabase models. These will often require a write connection.

+ +

Model persistence

+ +

You can enable model persistence to allow Metabase to create tables with model data and refresh them on a schedule. This requires write permissions to a designated schema.

+ +

Check out Model persistence.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/snowflake.html b/_site/docs/doc-update-detection/databases/connections/snowflake.html new file mode 100644 index 000000000..24f326bf7 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/snowflake.html @@ -0,0 +1,3188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Snowflake | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Snowflake

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Account or hostname

+ +

You have the option of using an account name or hostname. Your hostname is your database’s IP address or its domain name (e.g., database.example.com).

+ +

If your URL includes your database’s region, you can connect using an account name, otherwise connect using a hostname.

+ +

AWS

+ +

Connect with an account name.

+ +

Enter your Account identifier with the region that your Snowflake cluster is running on. E.g., xxxxxxxxx.us-east-3.aws. For example, if you’re running Snowflake on AWS and your account URL is https://az12345.ca-central-1.snowflakecomputing.com:

+ +
    +
  • <account_identifier>: az12345.ca-central-1.
  • +
  • <cloud_platform>: aws.
  • +
+ +

You’d enter az12345.ca-central-1.aws as the account name in Metabase.

+ +

Not all regions require the cloud platform identifier. If you’re in us-west-2, you would enter az12345 as the account name. For the requirements per region, see the official Snowflake’s documentation.

+ +

app.snowflake.com

+ +

Connect with a host name.

+ +

You can get your host name by going to Admin > Accounts. The Account name will be under Accounts. Click on the account you want to use, and click on the link icon to copy the host URL: that’s your host name. In the image below, Metabot is discreetly covering sensitive info. The “Copy account URL” link on the right is what you’re looking for:

+ +

Snowflake copy account URL

+ +

Learn more about Account Identifiers in Snowflake.

+ +

Username

+ +

The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of privileges.

+ +

On your app.snowflake.com account page, you can find Users and roles under Admin > Users & Roles.

+ +

Password

+ +

The password for the username that you use to connect to the database.

+ +

RSA private key (PEM)

+ +

Not required. You have the option of using a Local file path or an Uploaded file path. If you’re on Metabase Cloud, you’ll need to select Uploaded file path and upload your certificate.

+ +

Warehouse

+ +

Snowflake warehouse. If the user lacks a default warehouse, you’ll need to enter the warehouse to connect to.

+ +

On app.snowflake.com, you can find warehouses under Admin > Warehouses.

+ +

Database name (case sensitive)

+ +

The name of the database you want to connect to in Snowflake. On app.snowflake.com you can find databases under Data > Databases.

+ +

Schemas (optional)

+ +

You can specify which schemas you want to sync and scan. If no schema is passed, then all schema available to that user and role will be listed as folders in Metabase.

+ +

Schema options include:

+ +
    +
  • All
  • +
  • Only these…
  • +
  • All except…
  • +
+ +

For the Only these and All except options, you can input a comma-separated list of values to tell Metabase which schemas you want to include (or exclude). For example:

+ +
FOO,BAR,BAZ
+
+ +

You can use the * wildcard to match multiple schemas.

+ +

Let’s say you have three schemas: FOO, BAR, and BAZ.

+ +
    +
  • If you have Only these… set, and enter the string B*, you’ll sync with bar and baz.
  • +
  • If you have All except… set, and enter the string B*, you’ll just sync foo.
  • +
+ +

Note that only the * wildcard is supported; you can’t use other special characters or regexes.

+ +

Role (optional)

+ +

Specify a role to override the database user’s default role. For example, if the database user METABASE has the roles:

+ +
    +
  • Default role APPLICATION.
  • +
  • Additional role ANALYTICS.
  • +
+ +

You can enter ANALYTICS in the Role field to ensure that the METABASE user connects to Snowflake using the ANALYTICS role by default.

+ +

Use an SSH tunnel

+ +

See our guide to SSH tunneling.

+ +

Additional JDBC connection string options

+ +

Some databases allow you to append options to the connection string that Metabase uses to connect to your database.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Model features

+ +

There aren’t (yet) any model features available for Snowflake.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/sparksql.html b/_site/docs/doc-update-detection/databases/connections/sparksql.html new file mode 100644 index 000000000..cec7ede1a --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/sparksql.html @@ -0,0 +1,3129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SparkSQL | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SparkSQL

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Settings

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address, or its domain name (e.g., esc.mydatabase.com).

+ +

Port

+ +

The database port. E.g., 10000

+ +

Username

+ +

The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of privileges.

+ +

Password

+ +

The password for the username that you use to connect to the database.

+ +

Use an SSH tunnel

+ +

See our guide to SSH tunneling.

+ +

Additional JDBC connection string options

+ +

You can append options to the connection string that Metabase uses to connect to your database.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when Metabase syncs and scans

+ +

Turn this option ON to manage the queries that Metabase uses to stay up to date with your database. For more information, see Syncing and scanning databases.

+ +

Database syncing

+ +

If you’ve selected Choose when syncs and scans happen > ON, you’ll be able to set:

+ +
    +
  • The frequency of the sync: hourly (default) or daily.
  • +
  • The time to run the sync, in the timezone of the server where your Metabase app is running.
  • +
+ +

Scanning for filter values

+ +

Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database.

+ +

If you’ve selected Choose when syncs and scans happen > ON, you’ll see the following options under Scanning for filter values:

+ +
    +
  • Regularly, on a schedule allows you to run scan queries at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often.
  • +
  • Only when adding a new filter widget is a great option if you want scan queries to run on demand. Turning this option ON means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question.
  • +
  • Never, I’ll do this manually if I need to is an option for databases that are either prohibitively large, or which never really have new values added. Use the Re-scan field values now button to run a manual scan and bring your filter values up to date.
  • +
+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/sql-server.html b/_site/docs/doc-update-detection/databases/connections/sql-server.html new file mode 100644 index 000000000..09a92b6bb --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/sql-server.html @@ -0,0 +1,3150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SQL Server | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SQL Server

+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Supported versions

+ +

Metabase supports the oldest supported version of SQL Server through the latest stable version. See SQL Server end of support options.

+ +

Settings

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address, or its domain name (e.g., esc.mydatabase.com).

+ +

Port

+ +

The database port. E.g., 1433. To use Dynamic Ports, leave this field empty.

+ +

Database name

+ +

The name of the database you’re connecting to.

+ +

Database instance name

+ +

If you’re running multiple databases on the same host, you can include the instance name here.

+ +

Username

+ +

The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of privileges.

+ +

Password

+ +

The password for the username that you use to connect to the database.

+ +

Use a secure connection (SSL)

+ +

Metabase automatically tries to connect to databases with SSL first, then without if that doesn’t work. If it’s possible to connect to your database with an SSL connection, Metabase will make that the default setting for your database. If you prefer to connect without this layer of security, you can always change this setting later, but we highly recommend keeping SSL turned on to keep your data secure.

+ +

Use an SSH tunnel

+ +

See our guide to SSH tunneling.

+ +

Additional JDBC connection string options

+ +

You can append options to the connection string that Metabase uses to connect to your database.

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Database syncing

+ +

If you’ve selected Choose when syncs and scans happen > ON, you’ll be able to set:

+ +
    +
  • The frequency of the sync: hourly (default) or daily.
  • +
  • The time to run the sync, in the timezone of the server where your Metabase app is running.
  • +
+ +

Scanning for filter values

+ +

Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database.

+ +

If you’ve selected Choose when syncs and scans happen > ON, you’ll see the following options under Scanning for filter values:

+ +
    +
  • Regularly, on a schedule allows you to run scan queries at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often.
  • +
  • Only when adding a new filter widget is a great option if you want scan queries to run on demand. Turning this option ON means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question.
  • +
  • Never, I’ll do this manually if I need to is an option for databases that are either prohibitively large, or which never really have new values added. Use the Re-scan field values button to run a manual scan and bring your filter values up to date.
  • +
+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Connecting to Azure SQL

+ +

To connect to Azure SQL, you’ll need to set the port to 1433.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/sqlite.html b/_site/docs/doc-update-detection/databases/connections/sqlite.html new file mode 100644 index 000000000..8f2a48203 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/sqlite.html @@ -0,0 +1,3115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SQLite | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SQLite

+ +
+

SQLite isn’t available for Metabase Cloud.

+
+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

Fill out the fields for that database, and click Save changes at the bottom.

+ +

Settings

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Filename

+ +

The location of the SQLite database (the absolute path).

+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when Metabase syncs and scans

+ +

Turn this option ON to manage the queries that Metabase uses to stay up to date with your database. For more information, see Syncing and scanning databases.

+ +

Database syncing

+ +

If you’ve selected Choose when syncs and scans happen > ON, you’ll be able to set:

+ +
    +
  • The frequency of the sync: hourly (default) or daily.
  • +
  • The time to run the sync, in the timezone of the server where your Metabase app is running.
  • +
+ +

Scanning for filter values

+ +

Metabase can scan the values present in each field in this database to enable checkbox filters in dashboards and questions. This can be a somewhat resource-intensive process, particularly if you have a very large database.

+ +

If you’ve selected Choose when syncs and scans happen > ON, you’ll see the following options under Scanning for filter values:

+ +
    +
  • Regularly, on a schedule allows you to run scan queries at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often.
  • +
  • Only when adding a new filter widget is a great option if you want scan queries to run on demand. Turning this option ON means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question.
  • +
  • Never, I’ll do this manually if I need to is an option for databases that are either prohibitively large, or which never really have new values added. Use the Re-scan field values button to run a manual scan and bring your filter values up to date.
  • +
+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Danger zone

+ +

See Danger zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/starburst.html b/_site/docs/doc-update-detection/databases/connections/starburst.html new file mode 100644 index 000000000..5358b55c2 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/starburst.html @@ -0,0 +1,3134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Starburst | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Starburst

+ +
+

This driver also works for connections to a Trino database.

+
+ +

To add a database connection, click on the gear icon in the top right, and navigate to Admin settings > Databases > Add a database.

+ +

You can edit these settings at any time. Just remember to save your changes.

+ +

Connection and Sync

+ +

After connecting to a database, you’ll see the “Connection and sync” section that displays the current connection status and options to manage your database connection.

+ +

Here you can sync the database schema and rescan field values, and edit connection details.

+ +

Edit connection details

+ +

To access or modify your database connection settings, click the Edit connection details button.

+ +

Display name

+ +

The display name for the database in the Metabase interface.

+ +

Host

+ +

Your database’s IP address (e.g., 98.137.149.56) or its domain name (e.g., name.database.com).

+ +

Port

+ +

The database port (e.g., 8080).

+ +

Catalog

+ +

Starburt catalogs contain schemas and reference data sources via a connector.

+ +

Schema (optional)

+ +

Only add tables that come from a specific schema.

+ +

Username

+ +

The database username for the account that you want to use to connect to your database. You can set up multiple connections to the same database using different user accounts to connect to the same database, each with different sets of privileges.

+ +

Password

+ +

The password for the username that you use to connect to the database.

+ +

Use a secure connection (SSL)

+ +

See SSL certificates.

+ +

Role (optional)

+ +

Specify a role to override the database user’s default role.

+ +

Optimize prepared statements

+ +

Requires Starburst Galaxy, Starburst Enterprise (version 420-e or higher), or Trino (version 418 or higher).

+ +

Additional JDBC connection string options

+ +

You can append options to the JDBC connection string. Separate options with &, like so:

+ +
connection_timeout=1000&socket_timeout=300000
+
+ +

Re-run queries for simple explorations

+ +

Turn this option OFF if people want to click Run (the play button) before applying any Summarize or filter selections.

+ +

By default, Metabase will execute a query as soon as you choose an grouping option from the Summarize menu or a filter condition from the drill-through menu. If your database is slow, you may want to disable re-running to avoid loading data on each click.

+ +

Choose when syncs and scans happen

+ +

See syncs and scans.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

Turn this option ON to scan a sample of values every time Metabase runs a sync.

+ +

A fingerprinting query examines the first 10,000 rows from each column and uses that data to guesstimate how many unique values each column has, what the minimum and maximum values are for numeric and timestamp columns, and so on. If you leave this option OFF, Metabase will only fingerprint your columns once during setup.

+ +

Model features

+ +

There aren’t (yet) any model features for ClickHouse.

+ +

Danger zone

+ +

See Danger zone.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/connections/vertica.html b/_site/docs/doc-update-detection/databases/connections/vertica.html new file mode 100644 index 000000000..cd501014c --- /dev/null +++ b/_site/docs/doc-update-detection/databases/connections/vertica.html @@ -0,0 +1,3083 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Working with Vertica in Metabase | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Working with Vertica in Metabase

+ +

Starting in v0.20.0, Metabase provides a driver for connecting to Vertica databases. Under the hood, Metabase uses Vertica’s JDBC driver; +due to licensing restrictions, we can’t include it as part of Metabase. Luckily, downloading it yourself and making it available to Metabase +is straightforward and only takes a few minutes.

+ +

Downloading the Vertica JDBC Driver JAR

+ +

You can download the JDBC driver from Vertica’s JDBC driver downloads page. +Head to this page, log in to your account, accept the license agreement, and download vertica-jdbc-8.0.0-0.jar (for Vertica DB version 8.0) +or whatever driver version most closely matches the version of Vertica you’re running.

+ +

It’s very important to make sure you use the correct version of the JDBC driver; version +8.0 of the driver won’t work with Vertica version 7.2; version 7.2 of the driver won’t work with Vertica version 7.1, and so forth. If in doubt, +consult Vertica’s documentation to find the correct version of the JDBC driver for your version of Vertica.

+ +

Adding the Vertica JDBC Driver JAR to the Metabase Plugins Directory

+ +

Metabase will automatically make the Vertica driver available if it finds the Vertica JDBC driver JAR in the Metabase plugins directory when it starts up. +All you need to do is create the directory, move the JAR you just downloaded into it, and restart Metabase.

+ +

When running from a JAR

+ +

By default, the plugins directory is called plugins, and lives in the same directory as the Metabase JAR.

+ +

For example, if you’re running Metabase from a directory called /app/, you should move the Vertica JDBC driver JAR to /app/plugins/:

+ +
# example directory structure for running Metabase with Vertica support
+/app/metabase.jar
+/app/plugins/vertica-jdbc-8.0.0-0.jar
+
+ +

When running from Docker

+ +

The process for adding plugins when running via Docker is similar, but you’ll need to mount the plugins directory. Refer to instructions here for more details.

+ +

Model features

+ +

There aren’t (yet) any model features for Vertica.

+ +

Danger zone

+ +

See Danger zone.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/danger-zone.html b/_site/docs/doc-update-detection/databases/danger-zone.html new file mode 100644 index 000000000..75a872cd2 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/danger-zone.html @@ -0,0 +1,3069 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Danger zone | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Danger Zone

+ +

The Danger zone section of the database connection is the destructive section. Here you can discard field values for that database, or remove the database entirely.

+ +

But since of course you’re making backups of your Metabase application database, it’s not that destructive. But these changes are permanent in Metabase. The only way to get your stuff back is if you restore your Metabase application database from a backup. If you’re on Metabase Cloud, backups are handled for you.

+ +

To access the Danger Zone section for a database connection:

+ +
    +
  1. Click on the gear icon in the top right of Metabase.
  2. +
  3. Go to Admin settings > Databases.
  4. +
  5. Find the database you want to modify and click on it.
  6. +
  7. Scroll down to the bottom of the database’s settings page to find the “Danger Zone” section.
  8. +
+ +

Discard saved field values

+ +

This option allows you to clear all saved field values that were collected during syncs and fingerprinting. This will remove the cached information about your database’s fields, but won’t affect your actual database data or connection settings.

+ +

Remove this database

+ +
+

If you’re trying to migrate from a development DB to a production one, you don’t need to do this. You can just +edit your connection details.

+
+ +

This will delete the database connection (not your database and its data). But deleting the connection will also delete all of the questions, models, metrics, segments. You’ll have to check a bunch of boxes to even do this to make you know what you’re doing.

+ +

This action is irreversible in Metabase. If you accidentally delete a database connection, the only way to get your stuff back is to restore your Metabase from the last backup of your application database.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/encrypting-details-at-rest.html b/_site/docs/doc-update-detection/databases/encrypting-details-at-rest.html new file mode 100644 index 000000000..45a47ed83 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/encrypting-details-at-rest.html @@ -0,0 +1,3104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Encrypting your database connection | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Encrypting your database connection

+ +

Metabase stores connection information for the various databases you add in the Metabase application database. To prevent bad actors from being able to access these details if they were to gain access to the application DB, Metabase can automatically encrypt them with AES256 + SHA512 when they are saved, and decrypt them on-the-fly whenever they are needed.

+ +

Creating an encryption key

+ +
    +
  1. Generate a secret key that is at least 16 characters (longer is even better!). We recommend using a secure random key generator, such as openssl. +
    +

    You cannot decrypt connection details without this key. If you lose (or change) the key, you’ll have to reset all of the connection details that have been encrypted with that key in the Admin Panel.

    +
    +
  2. +
  3. Set your secret key as the environment variable MB_ENCRYPTION_SECRET_KEY. On self-hosted Pro and Enterprise plans plans, you can set also set this using the config file.
  4. +
+ +

Example commands for creating and adding a key

+ +
    +
  1. You can use openssl to generate a cryptographically-secure, randomly-generated 32-character key. +
    openssl rand -base64 32
    +
    +
  2. +
  3. Copy the key to your clipboard. It should look something like this: +
    IYqrSi5QDthvFWe4/WdAxhnra5DZC3RKx3ZSrOJDKsM=
    +
    +
  4. +
  5. Set the key as an environment variable and start Metabase as usual. +
    MB_ENCRYPTION_SECRET_KEY="IYqrSi5QDthvFWe4/WdAxhnra5DZC3RKx3ZSrOJDKsM=" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
    +
    +
  6. +
+ +

Once you set the MB_ENCRYPTION_SECRET_KEY value, Metabase will automatically encrypt and store the connection details for each new database that you add. To encrypt existing connections, see the next section.

+ +

Encrypting an existing connection

+ +

If you added databases before setting the MB_ENCRYPTION_SECRET_KEY value, you can encrypt the connection details by going to each one of those databases in Admin settings > Databases and clicking on the Save button. Existing databases with unencrypted details will continue to work normally.

+ +

Rotating an encryption key

+ +
    +
  1. We recommend that you backup your data before doing a key rotation.
  2. +
  3. Stop running your Metabase app.
  4. +
  5. Run the CLI command rotate-encryption-key. +
      +
    • Set the current encryption key as MB_ENCRYPTION_SECRET_KEY.
    • +
    • Set the new encryption key as a parameter.
    • +
    +
  6. +
+ +

Example command for rotating a key

+ +
MB_ENCRYPTION_SECRET_KEY=your-current-key java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar rotate-encryption-key new-key
+
+ +

Disabling an encryption key

+ +

To disable an encryption key, follow the steps to rotate an encryption key, but use an empty string ("") as the new key.

+ +

Example command for disabling a key

+ +
MB_ENCRYPTION_SECRET_KEY="your-current-key" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar rotate-encryption-key ""
+
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/images/atlas-connect.png b/_site/docs/doc-update-detection/databases/images/atlas-connect.png new file mode 100644 index 000000000..34cc366d7 Binary files /dev/null and b/_site/docs/doc-update-detection/databases/images/atlas-connect.png differ diff --git a/_site/docs/doc-update-detection/databases/images/connection-string.png b/_site/docs/doc-update-detection/databases/images/connection-string.png new file mode 100644 index 000000000..ff8b72ec6 Binary files /dev/null and b/_site/docs/doc-update-detection/databases/images/connection-string.png differ diff --git a/_site/docs/doc-update-detection/databases/images/snowflake-copy-account-url.png b/_site/docs/doc-update-detection/databases/images/snowflake-copy-account-url.png new file mode 100644 index 000000000..f77a9bdc4 Binary files /dev/null and b/_site/docs/doc-update-detection/databases/images/snowflake-copy-account-url.png differ diff --git a/_site/docs/doc-update-detection/databases/images/upload-icon.png b/_site/docs/doc-update-detection/databases/images/upload-icon.png new file mode 100644 index 000000000..671f9367a Binary files /dev/null and b/_site/docs/doc-update-detection/databases/images/upload-icon.png differ diff --git a/_site/docs/doc-update-detection/databases/images/upload-to-collection.png b/_site/docs/doc-update-detection/databases/images/upload-to-collection.png new file mode 100644 index 000000000..b09e7882b Binary files /dev/null and b/_site/docs/doc-update-detection/databases/images/upload-to-collection.png differ diff --git a/_site/docs/doc-update-detection/databases/ssh-tunnel.html b/_site/docs/doc-update-detection/databases/ssh-tunnel.html new file mode 100644 index 000000000..031a1e73f --- /dev/null +++ b/_site/docs/doc-update-detection/databases/ssh-tunnel.html @@ -0,0 +1,3141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SSH tunneling | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SSH tunneling

+ +

Metabase can connect to some databases by first establishing a connection to a server in between Metabase and a data warehouse, then connecting to the data warehouse using that connection as a bridge. This makes connecting to some data warehouses possible in situations that would otherwise prevent the use of Metabase.

+ +

When to use SSH tunneling

+ +

In general, there are two basic use cases for an SSH tunnel:

+ +
    +
  • When a direct connection is impossible.
  • +
  • When a direct connection is forbidden due to a security policy.
  • +
+ +

Sometimes when a data warehouse is inside an enterprise environment, direct connections are blocked by security devices such as firewalls and intrusion prevention systems. Bastion hosts offer the option to first connect to a computer on the edge of the protected network, then, from that bastion host computer, establish a second connection to the data warehouse within the internal network, essentially patching these two connections together. Using the SSH tunneling feature, Metabase can automate this process.

+ +
+

Metabase Cloud does not currently support VPN connections to databases. To connect to databases in private networks, you can instead use SSH tunneling.

+
+ +

How to use SSH tunneling

+ +

When connecting though a bastion host:

+ +
    +
  • Answer yes to the “Use an SSH-tunnel for database connections” parameter.
  • +
  • Enter the hostname for the data warehouse as it is seen from inside the network in the Host parameter.
  • +
  • Enter the data warehouse port as seen from inside the network into the Port parameter.
  • +
  • Enter the external name of the bastion host as seen from the outside of the network (or wherever you are) into the SSH tunnel host parameter.
  • +
  • Enter the SSH port as seen from outside the network into the SSH tunnel port parameter. This is usually 22, regardless of which data warehouse you are connecting to.
  • +
+ +

For authentication, you have two options:

+ +
    +
  • +

    Using a username and password:

    + +
      +
    • In the SSH tunnel username and SSH tunnel password fields, enter the username and password you use to log in to the bastion host.
    • +
    +
  • +
  • +

    Using SSH key (PKI authentication):

    + +
      +
    • Select SSH Key for the SSH authentication option.
    • +
    • Paste the contents of your SSH private key into the SSH private key field.
    • +
    • If your key has a passphrase, enter it into the Passphrase for the SSH private key field.
    • +
    +
  • +
+ +

If you’re unable to connect test your SSH credentials by connecting to the SSH server/Bastion Host using ssh directly:

+ +
ssh <SSH tunnel username>@<SSH tunnel host> -p <SSH tunnel port>
+
+ +

Another common case where direct connections are impossible is when connecting to a data warehouse that is only accessible locally and does not allow remote connections. In this case you will be opening an SSH connection to the data warehouse, then from there connecting back to the same computer.

+ +
    +
  • Answer yes to the “Use an SSH-tunnel for database connections” parameter.
  • +
  • Enter localhost in the Host parameter. This is the name the server.
  • +
  • Enter the same value in the Port parameter that you would use if you where sitting directly at the data warehouse host system.
  • +
  • Enter the external name of the data warehouse, as seen from the outside of the network (or wherever you are) into the SSH tunnel host parameter.
  • +
  • Enter the SSH port as seen from outside the network into the SSH tunnel port parameter. This is usually 22, regardless of which data warehouse you are connecting to.
  • +
  • Choose your authentication method as described above (username and password or SSH key).
  • +
+ +

If you have problems connecting, verify the SSH host port and password by connecting manually using ssh or PuTTY on older windows systems.

+ +

Disadvantages of indirect connections

+ +

While using an SSH tunnel makes it possible to use a data warehouse that is otherwise inaccessible, it’s almost always preferable to use a direct connection when possible.

+ +

There are several inherent limitations to connecting through a tunnel:

+ +
    +
  • If the enclosing SSH connection is closed because you put your computer to sleep or change networks, all established connections will be closed as well. This can cause delays resuming connections after suspending your laptop.
  • +
  • It’s almost always slower. The connection has to go through an additional computer.
  • +
  • Opening new SSH connections takes longer.
  • +
  • Multiple operations over the same SSH tunnel can block each other. This can increase latency.
  • +
  • The number of connections through a bastion host is often limited by organizational policy.
  • +
  • Some organizations have IT security policies forbidding using SSH tunnels to bypass security perimeters.
  • +
+ +

Running SSH directly

+ +

The SSH tunneling feature in Metabase exists as a convenient wrapper around SSH, and automates the common cases of connecting through a tunnel. It also makes connections possible with systems that don’t give shell access. Metabase uses a built-in SSH client that doesn’t depend on the installed system’s SSH client. This allows connections from systems where you can’t run SSH manually. It also means that Metabase can’t take advantage of authentication services provided by the system, such as Windows Domain Authentication or Kerberos Authentication.

+ +

If you need to connect using a method not enabled by Metabase, you can often accomplish this by running SSH directly:

+ +
ssh -Nf -L input-port:internal-server-name:port-on-server username@bastion-host.domain.com
+
+ +

This allows you to use the full array of features included in SSH. If you find yourself doing this often, please let us know so we can see about making your process more convenient through Metabase.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/ssl-certificates.html b/_site/docs/doc-update-detection/databases/ssl-certificates.html new file mode 100644 index 000000000..165114b88 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/ssl-certificates.html @@ -0,0 +1,3134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SSL certificate | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SSL certificate

+ +

If you’d like to connect your Metabase Cloud or self-hosted instance to a database, you can secure the connection using Secure Socket Layer (SSL) encryption with a certificate.

+ +

Why you’d want to do this:

+ +
    +
  • You’re using Metabase Cloud and want to ensure the identity of the data warehouse you’re connecting to (e.g., PostgreSQL, MySQL).
  • +
  • You’re self-hosting Metabase and want to ensure the identity of a data warehouse hosted by an external provider. You can also use this method to ensure you’re using the strictest connection parameters when connecting to your application database.
  • +
+ +

If you’re using Metabase Cloud, the application database is handled for you, so you’d only need to secure connections to data warehouses that you add to your Metabase.

+ +

Prerequisites

+ +

A database that allows a JDBC connection, as you’ll need to use a connection string to specify the certificate you want to use.

+ +

Step 1: Download the root certificate from your provider

+ +

If you’re running Metabase via a Docker container, you should already have the certificates for AWS and Azure.

+ +

You’ll find the certificates in the /app/certs/ directory in Metabase’s Docker image:

+ +
    +
  • AWS RDS: /app/certs/rds-combined-ca-bundle.pem
  • +
  • Azure certificate: /app/certs/DigiCertGlobalRootG2.crt.pem
  • +
+ +

If you need a different certificate, you can build your own Docker image. Visit your external provider’s page for your database and find a link to download the root certificate for connecting to your database.

+ +

Step 2: Save the certificate

+ +

Self-hosted

+ +

Save the downloaded certificate in the same directory where you keep your metabase.jar file. Technically you can store the certificate wherever, but keeping it in the same directory as your metabase.jar file is a best practice. You’ll specify the certificate’s path in your connection string.

+ +

Metabase Cloud

+ +

You’ll need to complete Step 3: Add your database first.

+ +

Once you’ve done that, you can go to Admin > Databases and select your database. Find the section named SSL Client Certificate and click Select a file to upload your downloaded certificate.

+ +

Step 3: Add your database

+ +

For example, let’s say you want to secure a connection to a PostgreSQL database. Follow the instructions in the app to add the database. For more on setting up a database connection, check out our docs for adding a database.

+ +

Step 4: Toggle on the “Use a secure connection (SSL)” option

+ +

If your database supports a JDBC connection, Metabase will provide you with a field to input additional parameters to your connection string. Metabase will use parameters in the connection string to establish a secure connection.

+ +

Step 5: Add additional connection string options

+ +

You’ll need to specify the location of the certificate on the server that’s running Metabase.

+ +

For example, when connecting to a PostgreSQL database, you’ll need to add two parameters:

+ +
    +
  • sslmode. You can see the full list of options in PostgreSQL’s documentation. We recommend you use verify-full; it’s the most secure, and overhead is minimal.
  • +
  • sslrootcert. Here you’ll specify the file path for the certificate.
  • +
+ +

You’ll add an ampersand (&) to separate each parameter. For example, In the Add additional connection string options field, you’d add something like:

+ +
sslmode=verify-full&sslrootcert=/path/to/certificate.pem
+
+ +

Replace /path/to/certifcate.pem with the full path for the certificate you downloaded from your provider.

+ +

You can learn more about SSL support for PostgreSQL.

+ +

Securing connection to application database using environment variables

+ +

If you’re self-hosting Metabase, you can secure the connection to your application database using environment variables.

+ +

The environment variable to use is MB_DB_CONNECTION_URI.

+ +

You’ll need to include the full connection string here, including the db host, port, db name and user info, as well as the additional connection parameters to include the certificate. For example,

+ +
jdbc:postgresql://db.example.com:port/mydb?user=dbuser&password=dbpassword&ssl=true&sslmode=verify-full&sslrootcert=/path/to/certificate.pem
+
+ +

Both can be provided to support mutual authentication scenarios.

+ +

Truststores and keystores

+ +

With some databases, like PostgreSQL and Oracle, you can secure connections using truststores and keystores.

+ +

Truststores

+ +

If a truststore is provided to verify credentials, the client (your Metabase) can authenticate the server (the database) and ensure its identity is what’s expected.

+ +

Keystores

+ +

If a keystore is used to provide credentials, then the server (the database server) can request the client (your Metabase) authenticate itself using that keystore. Keystores are used less frequently, and in some cases it’s impossible to use a keystore (Amazon’s RDS forbids keystores, for example). But you may want to use a keystore if you’re hosting on prem.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/start.html b/_site/docs/doc-update-detection/databases/start.html new file mode 100644 index 000000000..c43f471ae --- /dev/null +++ b/_site/docs/doc-update-detection/databases/start.html @@ -0,0 +1,3069 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Databases overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Databases overview

+ +

Adding and managing databases

+ +

Connect to and manage your databases.

+ +

Database users, roles, and privileges

+ +

Bundling your privileges into roles based on use cases makes it easier to manage privileges in the future.

+ +

Syncing and scanning databases

+ +

Metabase runs different types of queries to stay up to date with your database.

+ +

Encrypting your database connection

+ +

Learn how to encrypt your database connection credentials at rest.

+ +

SSH tunneling

+ +

Metabase can connect to some databases by first establishing a connection to a server in between Metabase and a data warehouse, then connecting to the data warehouse using that connection as a bridge.

+ +

SSL certificate

+ +

You can connect your Metabase Cloud or self-hosted instance to a database using Secure Socket Layer (SSL) encryption with a certificate.

+ +

Uploading data

+ +

You can set Metabase up so you can upload CSV files to a database.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/sync-scan.html b/_site/docs/doc-update-detection/databases/sync-scan.html new file mode 100644 index 000000000..2b36cb18b --- /dev/null +++ b/_site/docs/doc-update-detection/databases/sync-scan.html @@ -0,0 +1,3226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Syncing and scanning databases | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Syncing and scanning databases

+ +

Metabase periodically runs different types of queries to stay up to date with your database’s metadata. Knowing stuff about your data helps Metabase do things like display the right chart for the results automatically, and populate dropdown menus in filter widgets.

+ +

There are a couple of things Metabase does:

+ +
    +
  • Syncs get updated schemas to display in the Data Browser.
  • +
  • Scans take samples of column values to populate filter dropdown menus and suggest helpful visualizations. Metabase doesn’t store complete tables from your database.
  • +
  • Fingerprinting takes an additional sample of column values to help with smart behavior, such as auto-binning for bar charts.
  • +
+ +

Initial sync, scan, and fingerprinting

+ +

When Metabase first connects to your database, Metabase performs a sync to determine the metadata of the columns in your tables and automatically assign each column a semantic type.

+ +

You can follow the progress of these queries from Admin > Troubleshooting > Logs.

+ +

Once the queries are done running, you can view and edit the synced metadata from Admin settings > Table Metadata. For more info, see editing metadata.

+ +

Choose when syncs and scans happen

+ +

By default, Metabase does a lightweight hourly sync and an intensive daily scan of field values. If you have a large database, you might want to choose when syncs and scans happen:

+ +

Database syncing

+ +

If you’ve selected Choose when syncs and scans happen > ON, you’ll be able to set:

+ +
    +
  • The frequency of the sync: hourly (default) or daily.
  • +
  • The time to run the sync, in the timezone of the server where your Metabase app is running.
  • +
+ +

Scanning for filter values

+ +

Metabase can scan and cache the values present in a field so it can display things like checkbox filters in dashboards and questions. Metabase will only scan fields that people are actually using in your Metabase. So if people are using a filter widget on a dashboard, Metabase will scan and cache values from that field to include in dropdown menus. If people stop using the filter widget for a couple of weeks, Metabase will stop scanning and caching those values.

+ +

If you’ve selected Choose when syncs and scans happen > ON, you’ll see the following options under Scanning for filter values:

+ +
    +
  • Regularly, on a schedule allows you to run scan queries at a frequency that matches the rate of change to your database. The time is set in the timezone of the server where your Metabase app is running. This is the best option for a small database, or tables with distinct values that get updated often.
  • +
  • Only when adding a new filter widget is a great option if you want scan queries to run on demand. Turning this option ON means that Metabase will only scan and cache the values of the field(s) that are used when a new filter is added to a dashboard or SQL question.
  • +
  • Never, I’ll do this manually if I need to is an option for databases that are either prohibitively large, or which never really have new values added. Use the Re-scan field values button to run a manual scan and bring your filter values up to date.
  • +
+ +

Manually syncing tables and columns

+ +
    +
  1. Go to Admin settings > Databases > your database.
  2. +
  3. Click Sync database schema.
  4. +
+ +

Manually scanning column values

+ +

To scan values from all the columns in a table:

+ +
    +
  1. Go to Admin settings > Table Metadata > your database.
  2. +
  3. Select the table that you want to bring up to date with your database.
  4. +
  5. Click the gear icon at the top of the page.
  6. +
  7. Click Re-scan this table.
  8. +
+ +

To scan values from a specific column:

+ +
    +
  1. Go to Admin settings > Table Metadata > your database.
  2. +
  3. Select the table.
  4. +
  5. Find the column you want bring up to date with your database.
  6. +
  7. Click the gear icon in the panel for that column.
  8. +
  9. Click Re-scan this field.
  10. +
+ +

Clearing cached values for a table or field

+ +

To clear the scanned field values for a table:

+ +
    +
  1. Go to Admin settings > Table Metadata.
  2. +
  3. Select the database and table.
  4. +
  5. Click the gear icon in the upper right.
  6. +
  7. Click Discard cached field values.
  8. +
+ +

You can also tell Metabase to forget the cached values for individual fields by clicking the gear icon on a field and clicking on Discard cached field values.

+ +

Disabling syncing and scanning for specific tables

+ +

To prevent Metabase from running syncs and scans against a specific table, change the table visibility to Hidden:

+ +
    +
  1. Go to Admin settings > Table Metadata > your database.
  2. +
  3. Hover over the table name in the sidebar.
  4. +
  5. Click the eye icon.
  6. +
+ +
+

Hiding a table will also prevent it from showing up in the query builder and data reference. People can still query hidden tables from the SQL editor.

+
+ +

Syncing and scanning using the API

+ +

Metabase syncs and scans regularly, but if the database administrator has just changed the database schema, or if a lot of data is added automatically at specific times, you may want to write a script that uses the Metabase API to force a sync or scan. Our API provides two ways to initiate a sync or scan of a database:

+ +
    +
  1. Using a session token: the /api/database/:id/sync_schema or api/database/:id/rescan_values endpoints. These endpoints do the same things as going to the database in the Admin Panel and choosing Sync database schema or Re-scan field values respectively. To use these endpoints, you have to authenticate with a user ID and pass a session token in the header of your request.
  2. +
  3. Using an API key: /api/notify/db/:id. We created this endpoint so that people could notify their Metabase to sync after an ETL operation finishes. To use this endpoint, you must pass an API key by defining the MB_API_KEY environment variable.
  4. +
+ +

How database syncs work

+ +

A Metabase sync is a query that gets a list of updated table and view names, column names, and column data types from your database:

+ +
SELECT
+    TRUE
+FROM
+    "your_schema"."your_table_or_view"
+WHERE
+    1 <> 1
+LIMIT 0
+
+ +

This query runs against your database during setup, and again every hour by default. This scanning query is fast with most relational databases, but can be slower with MongoDB and some community-built database drivers. Syncing can’t be turned off completely, otherwise Metabase wouldn’t work.

+ +

How database scans work

+ +

A Metabase scan is a query that caches the column values for filter dropdowns by looking at the first 1,000 distinct records from each table, in ascending order:

+ +
SELECT
+    "your_table_or_view"."column" AS "column"
+FROM
+    "your_schema"."your_table_or_view"
+GROUP BY
+    "your_table_or_view"."column"
+ORDER BY
+    "your_table_or_view"."column" ASC
+LIMIT 1000
+
+ +

For each record, Metabase only stores the first 100 kilobytes of text, so if you have data with 1,000 characters each (like addresses), and your column has more than 100 unique addresses, Metabase will only cache the first 100 values from the scan query.

+ +

Cached column values are displayed in filter dropdown menus. If people type in the filter search box for values that aren’t in the first 1,000 distinct records or 100kB of text, Metabase will run a query against your database to look for those values on the fly.

+ +

A scan is more intensive than a sync query, so it only runs once during setup, and again once a day by default. If you disable scans entirely, you’ll need to bring things up to date by running manual scans.

+ +

To reduce the number of tables and fields Metabase needs to scan in order to stay current with your connected database, Metabase will only scan values for fields that someone has queried in the last fourteen days.

+ +

Periodically refingerprint tables

+ +
+

Periodic refingerprinting will increase the load on your database.

+
+ +

By default, Metabase only runs fingerprinting queries when you first connect your database.

+ +

Turn this setting on if you want Metabase to use larger samples of column values when making suggestions in the UI:

+ +
    +
  1. Go to Admin > Databases > your database.
  2. +
  3. Click on Edit connection details.
  4. +
  5. Expand Show advanced options.
  6. +
  7. Turn on Periodically refingerprint tables.
  8. +
+ +

How database fingerprinting works

+ +

The fingerprinting query looks at the first 10,000 rows from a given table or view in your database:

+ +
SELECT
+    *
+FROM
+    "your_schema"."your_table_or_view"
+LIMIT 10000
+
+ +

Metabase uses the results of this query to provide better suggestions in the Metabase UI (such as filter dropdowns and auto-binning). +To avoid putting strain on your database, Metabase only runs fingerprinting queries the first time you set up a database connection. To change this default, you can turn ON Periodically refingerprint tables.

+ +

Further reading

+ +

Metabase doesn’t do any caching or rate limiting during the sync and scan process. If your data appears to be missing or out of date, check out:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/uploads.html b/_site/docs/doc-update-detection/databases/uploads.html new file mode 100644 index 000000000..604a36329 --- /dev/null +++ b/_site/docs/doc-update-detection/databases/uploads.html @@ -0,0 +1,3249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Setting up data uploads | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Setting up data uploads

+ +

This page covers how admins can set up data uploads so people can upload CSVs to your Metabase. For how to upload data once this is set up, check out Uploading data.

+ +

Upload CSV data to a collection in Metabase

+ +

Uploading CSV data is best suited for ad hoc analysis of spreadsheet data. If you have a lot of data, or will need to update or add to that data regularly, we recommend setting up a way to load that data into a database directly, then connecting Metabase to that database.

+ +

Managing upload settings

+ +

To manage upload settings, admins can hit cmd/ctrl + K and search for “Settings - Uploads”, or click on the gear icon in the upper right and click through Admin settings > Settings > Uploads.

+ +

Databases that support uploads

+ + + +

Setting up uploads

+ +

There are a few things admins need to do to support CSV uploads:

+ + + +

Connect to a database using a database user account with write access

+ +

To upload data to Metabase, an admin will need to connect your Metabase to a database that supports uploads using a database user account that has write access to that database.

+ +

You can also upload data to the Sample Database included with Metabase (an H2 database), though we don’t recommend using the Sample Database for any data that you want to keep around.

+ +

For more, check out:

+ + + +

Select the database and schema that you want to store the data in

+ +

If Metabase is connected to a database using a database user account with write access, Admins can enable uploads by:

+ +
    +
  • Clicking on the gear icon in the upper right on the home page and navigating to Admin settings > Settings > Uploads.
  • +
  • Selecting the database Metabase should use to store the data.
  • +
+ +

When people upload a CSV to a collection, Metabase will:

+ +
    +
  • Create a table to store that data in the database and schema that the Admin selected to store uploads.
  • +
  • Create a model that wraps the uploaded table, and save that model to the collection the person uploaded the CSV data to.
  • +
+ +

Specify a prefix for Metabase to prepend to the uploaded tables

+ +

Admins can optionally specify a string of text to add in front of the table that Metabase creates to store the uploaded data.

+ +

Add people to a group with data access to the upload schema

+ +

In order to upload CSVs, a person must be in a group with View data access of “Can view” and Create queries of Query builder access or higher to the schema you’ve selected to store your uploaded data. See groups and data permissions.

+ +

Primary key auto-generation

+ +

When you upload a CSV, Metabase will create an a unique primary key column, called _mb_row_id, as the first (left-most) column of the uploaded CSV table. This _mb_row_id column will contain automatically generated integers. Metabase will also ignore any columns in the upload that have a name that will be in the database with the same name as the auto-generated primary key column (e.g., _MB row-ID in the CSV will be _mb_row_id or _MB_ROW_ID in the database).

+ +

If you don’t want this autogenerated ID column, you can always remove the column from the model Metabase created. Visit the model, click on the info i icon, then Model details. From the model details page, click the Edit definition button. In the Data section of the query builder, click on the down arrow next to the table, deselect the added ID column, and save your changes.

+ +

Data type errors

+ +

Metabase will try to guess what the data type is for each column, but if some entries are not like the others, Metabase may not guess the type correctly. For example, if you have a column that starts with integers like 100, 130, 140, then later on a float 105.5, Metabase may reject the upload. To fix this, you’ll need to use spreadsheet software to adjust the formatting so that all the integers are formatted as floats (e.g., 100.00, 130.00, 140.00 and so on) before uploading.

+ +

File size limit

+ +

CSV files cannot exceed 50 MB in size.

+ +
+

While Metabase limits uploads to 50 MB, the server you use to run your Metabase may impose a lower limit. For example, the default client upload limit for NGINX is 1 MB. So you may need to change your server settings to allow uploads up to 50 MB. People on Metabase Cloud don’t have to worry about this.

+
+ +

If you have a file larger than 50 MB, the workaround here is to split the data into multiple files and append those files to an existing model. Each file that you upload to Metabase must have a header row (the names of the columns), so if you’re splitting one file into multiple files, you’ll need to add header rows to each file.

+ +

Date formats

+ +

For now, Metabase only recognizes dates and datetimes from strings in uploaded CSVs with the following formats:

+ +

Dates

+ +

Represents the year, month, and day without time information.

+ +

Format: yyyy-MM-dd

+ +

Example: 2023-01-01

+ +

Datetimes

+ +

Represents the year, month, day, hour. Minutes, seconds, and fractional seconds are optional.

+ +

Format: yyyy-MM-ddTHH:mm:ss.SSS. The “T” separator could also be a space (“ “).

+ +

Examples:

+ +
    +
  • 2023-01-01 00
  • +
  • 2023-01-01 00:00:00.000
  • +
  • 2023-01-01T00:00:00.000
  • +
  • 2023-01-01 00:00:00.0000000
  • +
+ +

Datetimes with offsets

+ +

Represents the datetime with an offset from Coordinated Universal Time (UTC). Minutes and seconds in the offset are optional.

+ +

Formats:

+ +

Datetime formats:

+ +
    +
  • yyyy-MM-ddTHH:mm.
  • +
  • yyyy-MM-ddTHH:mm:ss.
  • +
  • yyyy-MM-ddTHH:mm:ss.SSS (and any number of S’s).
  • +
+ +

The “T” separator could also be a space (“ “).

+ +

Offsets:

+ +
    +
  • Z (for UTC)
  • +
  • +HH or -HH
  • +
  • +HH:mm or -HH:mm
  • +
  • +HH:mm:ss or -HH:mm:ss
  • +
+ +

Examples:

+ +
    +
  • 2023-01-01 00:00:00+00:00:00
  • +
  • 2023-01-01T00:00:00+00:00:00
  • +
+ +

Deleting models and tables created by uploads

+ +

Deleting models created by uploads

+ +
+
+ + + + + + + +

Deleting uploaded tables is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

You can move a model to Trash by clicking on the three dots in the upper right and selecting Move to Trash.

+ +

For deleting models completely, see Deleting items permanently.

+ +

Deleting tables created by uploads

+ +
+
+ + + + + + + +

Deleting uploaded tables is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

To delete tables created by uploads, go to Admin settings > Settings > Uploads.

+ +

Under Manage uploads, Metabase will list the tables underlying the models.

+ +

When you delete the table, Metabase will give you the option to Also send all models and questions based on this table to the trash.

+ +

Note on uploading data to a MySQL database

+ +

For speeding up uploads to a MySQL database, we recommend that you set a local_infile to ON. You’ll need to set this local_infile in MySQL, not Metabase. The command-line format is --local-infile=ON.

+ +

If local_infile is disabled (set to OFF), Metabase will automatically fall back to uploading CSVs in a much slower way.

+ +

For more context, check out:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/databases/users-roles-privileges.html b/_site/docs/doc-update-detection/databases/users-roles-privileges.html new file mode 100644 index 000000000..ff4cea70c --- /dev/null +++ b/_site/docs/doc-update-detection/databases/users-roles-privileges.html @@ -0,0 +1,3269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Database users, roles, and privileges | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Database users, roles, and privileges

+ +

We recommend creating a metabase database user with the following database roles:

+ + + +

Bundling your privileges into roles based on use cases makes it easier to manage privileges in the future (especially in multi-tenant situations). For example, you could:

+ +
    +
  • Use the same analytics role for other BI tools in your data stack that need read-only access to the analytics tables in your database.
  • +
  • Revoke the write access for metabase_model_persistence without affecting the write access for metabase_actions.
  • +
+ +

Minimum database privileges

+ +

In order to view and query your tables in Metabase, you’ll have to give Metabase’s database user:

+ +
    +
  • CONNECT to your database.
  • +
  • SELECT privileges to any schemas or tables that you want to use in Metabase.
  • +
+ +

To organize these privileges (and make maintenance easier down the line):

+ +
    +
  • Create a database role called analytics.
  • +
  • Create a database user called metabase.
  • +
  • Add metabase to the analytics role.
  • +
  • Add privileges to the analytics role.
  • +
+ +

For example, if you’re using a Postgres database, you’d log in as an admin and run the SQL statements:

+ +
-- Create a role named "analytics".
+CREATE ROLE analytics WITH LOGIN;
+
+-- Add the CONNECT privilege to the role.
+GRANT CONNECT ON DATABASE "your_database" TO analytics;
+
+-- Create a database user named "metabase".
+CREATE USER metabase WITH PASSWORD "your_password";
+
+-- Give the role to the metabase user.
+GRANT analytics TO metabase;
+
+-- Add query privileges to the role (options 1-4):
+
+-- Option 1: Uncomment the line below to let users with the analytics role query ALL DATA (In Postgres 14 or higher. See [Predefined Roles](https://www.postgresql.org/docs/current/predefined-roles.html#PREDEFINED-ROLES)).
+-- GRANT pg_read_all_data TO analytics;
+
+-- Option 2: Uncomment the line below to let users with the analytics role query anything in the DATABASE.
+-- GRANT USAGE ON DATABASE "your_schema" TO analytics;
+-- GRANT SELECT ON DATABASE "your_schema"  TO analytics;
+
+-- Option 3: Uncomment the line below to let users with the analytics role query anything in a specific SCHEMA.
+-- GRANT USAGE ON SCHEMA "your_schema" TO analytics;
+-- GRANT SELECT ON ALL TABLES IN SCHEMA "your_schema" TO analytics;
+
+-- Option 4: Uncomment the line below to let users with the analytics role query anything in a specific TABLE.
+-- GRANT USAGE ON SCHEMA "your_schema" TO analytics;
+-- GRANT SELECT ON "your_table" IN SCHEMA "your_schema" TO analytics;
+
+ +

Depending on how you use Metabase, you can also additonally grant:

+ +
    +
  • TEMPORARY privileges to create temp tables.
  • +
  • EXECUTE privileges to use stored procedures or user-defined functions.
  • +
+ +

Remember that when you grant privileges to a role, all users with that role will get those privileges.

+ +

Grant all database privileges

+ +

If you don’t want to structure your database privileges yet:

+ +
    +
  • Create a metabase database user.
  • +
  • Give metabase all privileges to the database.
  • +
+ +
-- Create a database user named "metabase".
+CREATE USER metabase WITH PASSWORD "your_password";
+
+-- Give the user read and write privileges to anything in the database.
+GRANT ALL PRIVILEGES ON "database" TO metabase;
+
+ +

This is a good option if you’re connecting to a local database for development or testing.

+ +

Privileges to enable actions

+ +

Actions let Metabase write back to specific tables in your database.

+ +

In addition to the minimum database privileges, you’ll need to grant write access to any tables used with actions:

+ +
    +
  • Create a new role called metabase_actions.
  • +
  • Give the role INSERT, UPDATE, and DELETE privileges to any tables used with Metabase actions.
  • +
  • Give the metabase_actions role to the metabase user.
  • +
+ +
-- Create a role to bundle database privileges for Metabase actions.
+CREATE ROLE metabase_actions WITH LOGIN;
+
+-- Grant write privileges to the TABLE used with Metabase actions.
+GRANT INSERT, UPDATE, DELETE ON "your_table" IN SCHEMA "your_schema" TO metabase_actions;
+
+-- Grant role to the metabase user.
+GRANT metabase_actions TO metabase;
+
+ +

Privileges to enable model persistence

+ +

Model persistence lets Metabase save query results to a specific schema in your database. Metabase’s database user will need the CREATE privilege to set up the dedicated schema for model caching, as well as write access (INSERT, UPDATE, DELETE) to that schema.

+ +

In addition to the minimum database privileges:

+ +
    +
  • Create a new role called metabase_model_persistence.
  • +
  • Give the role CREATE access to the database.
  • +
  • Give the role INSERT, UPDATE, and DELETE privileges to the schema used for model persistence.
  • +
  • Give the metabase_model_persistence role to the metabase user.
  • +
+ +
-- Create a role to bundle database privileges for Metabase model persistence.
+CREATE ROLE metabase_model_persistence WITH LOGIN;
+
+-- If you don't want to give CREATE access to your database,
+-- add the schema manually before enabling modeling persistence.
+GRANT CREATE ON "database" TO metabase_model_persistence;
+
+-- Grant write privileges to the SCHEMA used for model persistence.
+GRANT USAGE ON "your_schema" TO metabase_model_persistence;
+GRANT INSERT, UPDATE, DELETE ON "your_model's_table" IN SCHEMA "your_schema" TO metabase_model_persistence;
+
+-- Grant role to the metabase user.
+GRANT metabase_model_persistence TO metabase;
+
+ +

Privileges to enable uploads

+ +

You can upload CSVs to supported databases. Metabase’s database user should have write access (INSERT, UPDATE, DELETE) to the schema where you want to store the uploads.

+ +

You’ll first need to create a schema to store uploads (or use an existing schema) and tell Metabase that you want to use that schema to store uploads.

+ +

In addition to the minimum database privileges:

+ +
    +
  • Create a new role called metabase_uploads.
  • +
  • Give the role INSERT, UPDATE, and DELETE privileges to the schema where you want to store uploads.
  • +
  • Give the metabase_uploads role to the metabase user.
  • +
+ +
-- Create a role to bundle database privileges for uploads.
+CREATE ROLE metabase_uploads WITH LOGIN;
+
+-- Grant write privileges to the SCHEMA used for uploads.
+GRANT USAGE ON "your_schema" TO metabase_uploads;
+GRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA "your_schema" TO metabase_uploads;
+
+-- Grant role to the metabase user.
+GRANT metabase_uploads TO metabase;
+
+ +

Multi-tenant permissions

+ +

If you’re setting up multi-tenant permissions for customers who need SQL access, you can create one database connection per customer. That means each customer will connect to the database using their own database user.

+ +

Let’s say you have customers named Tangerine and Lemon:

+ +
    +
  • Create new database users metabase_tangerine and metabase_lemon.
  • +
  • Create a customer_facing_analytics role with the CONNECT privilege.
  • +
  • Create roles to bundle privileges specific to each customer’s use case. For example: +
      +
    • tangerine_queries to bundle read privileges for people to query and create stored procedures against the Tangerine schema.
    • +
    • lemon_queries to bundle read privileges for people to query tables in the Lemon schema.
    • +
    • lemon_actions to bundle the write privileges needed to create actions on a Lemonade table in the Lemon schema.
    • +
    +
  • +
  • Add each user to their respective roles.
  • +
+ +
-- Create one database user per customer.
+CREATE USER metabase_tangerine WITH PASSWORD "orange";
+CREATE USER metabase_lemon WITH PASSWORD "yellow";
+
+-- Create a role to bundle privileges for all customers.
+CREATE ROLE customer_facing_analytics;
+GRANT CONNECT ON DATABASE "citrus" TO customer_facing_analytics;
+GRANT customer_facing_analytics TO metabase_tangerine, metabase_lemon;
+
+-- Create a role to bundle analytics read access for customer Tangerine.
+CREATE ROLE tangerine_queries;
+GRANT USAGE ON SCHEMA "tangerine" TO tangerine_queries;
+GRANT SELECT, EXECUTE ON ALL TABLES IN SCHEMA "tangerine" TO tangerine_queries;
+GRANT tangerine_queries TO metabase_tangerine;
+
+-- Create a role to bundle analytics read access for customer Lemon.
+CREATE ROLE lemon_queries;
+GRANT USAGE ON SCHEMA "lemon" TO lemon_queries;
+GRANT SELECT ON ALL TABLES IN SCHEMA "lemon" TO lemon_queries;
+GRANT lemon_queries TO metabase_lemon;
+
+-- Create a role to bundle privileges to Metabase actions for customer Lemon.
+CREATE ROLE lemon_actions;
+GRANT INSERT, UPDATE, DELETE ON TABLE "lemonade" IN SCHEMA "lemon" TO lemon_actions;
+GRANT lemon_actions TO metabase_lemon;
+
+ +

We recommend bundling privileges into roles based on use cases per customer. That way, you can reuse common privileges across customers while still being able to grant or revoke granular privileges per customer. For example:

+ +
    +
  • If customer Tangerine needs to query the Tangerine schema from another analytics tool, you can use the tangerine_queries role when setting up that tool.
  • +
  • If customer Lemon decides that they don’t want to use Metabase actions anymore (but they still want to ask questions), you can simply revoke or drop the lemon_actions role.
  • +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide-drivers.html b/_site/docs/doc-update-detection/developers-guide-drivers.html new file mode 100644 index 000000000..588a91bca --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide-drivers.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/developers-guide.html b/_site/docs/doc-update-detection/developers-guide.html new file mode 100644 index 000000000..085fd984b --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/developers-guide/api-changelog.html b/_site/docs/doc-update-detection/developers-guide/api-changelog.html new file mode 100644 index 000000000..a3a3c4a0e --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/api-changelog.html @@ -0,0 +1,3196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +API changelog | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Breaking changes to the API interface

+ +

Metabase 0.54.0

+ +
    +
  • +

    The alert system has been migrated from the legacy pulse infrastructure to the new notification system. This migration includes the following changes:

    + +
      +
    • The majority of /api/alert endpoints have been removed in favor of the new /api/notification endpoints. For backward compatibility, these endpoints will remain available until the next release: +
        +
      • GET /api/alert
      • +
      • GET /api/alert/:id
      • +
      • DELETE /api/alert/:id/subscription
      • +
      +
    • +
    • Developers should migrate to using the /api/notification endpoints. For reference: +
        +
      • An overview of the new notification system can be found at src/metabase/notification/README.md
      • +
      • Notification API documentation at /api/docs/#tag/apinotification
      • +
      • Interactive API documentation available at /api/docs endpoint
      • +
      +
    • +
    +
  • +
+ +

Metabase 0.53.0

+ +
    +
  • +

    POST /api/card/:card-id/query/:export-format

    + +

    Previously, request parameters (parameters, pivot-results?, and format-rows?) could be sent via query parameters or +as application/x-www-form-urlencoded form content. In Metabase 0.53.0, parameters must be sent as either:

    + +
      +
    • application/x-www-form-urlencoded form content
    • +
    • JSON-encoded in the request body
    • +
    + +

    Sending parameters as query parameters in the URL is no longer supported.

    +
  • +
+ +

Metabase 0.52.0

+ +
    +
  • POST /api/user/:id/send_invite has been removed.
  • +
  • +

    GET /:id/fields now includes the Table ID.

    +
  • +
  • APIs under /api/pulse and /api/alert will be removed in a future version as we’re tranitioning to a new architecture.
  • +
+ +

Metabase 0.51.0

+ +
    +
  • +

    GET /api/dashboard/:id/query_metadata

    + +

    New endpoint that combines responses for /api/field/:id, /api/database/:id, and /api/table/:id/query_metadata. +This should drastically cut down on the required number of requests to display a card.

    +
  • +
  • +

    GET /api/card/:id/query_metadata

    + +

    New endpoint that combines responses for /api/field/:id, /api/database/:id, and /api/table/:id/query_metadata. +This should drastically cut down on the required number of requests to display a dashboard.

    +
  • +
  • +

    /api/legacy-metric

    + +

    The /api/legacy-metric endpoints have been removed.

    +
  • +
  • +

    POST /api/session/pulse/unsubscribe and POST /api/session/pulse/unsubscribe/undo have been moved to POST /api/pulse/unsubscribe and POST /api/pulse/unsubscribe/undo respectively.

    +
  • +
+ +

Metabase 0.50.0

+ +
    +
  • +

    GET /api/collection/tree and GET /api/collection/:id/items +These API endpoints will always return official collections first, before other items in the collection.

    +
  • +
  • +

    PUT /api/dashboard/:id, PUT /api/card/:id, and PUT /api/collection/:id

    + +

    When setting archived to true, the Dashboard, Card, or Collection will be automatically moved to the Trash +collection, a special collection that holds all archived items.

    + +

    When setting archived to false, you may optionally also provide a collection_id (for Dashboards or Cards) or a +parent_id (for Collections). In this case, the entity will be re-parented to the specified Collection when it is +moved from the Trash. If a new collection_id or parent_id is not provided, the entity will be moved back to its +original location if possible. If this is not possible (for example, the original location is also in the Trash) an +error will occur.

    +
  • +
  • +

    /api/metric

    + +

    The /api/metric endpoints has been renamed to /api/legacy-metric to reflect that fact it will not be used for the new version of metrics. The new version uses the /api/card endpoints.

    +
  • +
  • +

    GET /api/permissions/graph and PUT /api/permissions/graph

    + +

    The data key has been removed from the permissions graph. The data key has been replaced with two new keys: view-data and create-queries. +Valid permission values for view-data are unrestricted, blocked, sandboxed or restricted. Valid permission values +for create-queries are query-builder-and-native, query-builder, and no.

    + +

    If you’re scripting permissions, you’ll need to update your scripts to reflect these breaking changes to the /api/permissions/graph endpoints. For more about the new data permissions of View data and Create queries, see our docs on data permissions. And here’s a page that talks about the change (and why we did it).

    +
  • +
  • +

    GET /api/transform/:db-id/:schema/:transform-name, which hasn’t been used internally by Metabase for ages, has +been removed.

    +
  • +
  • +

    POST /api/user/:id/send_invite is deprecated and will be removed in the next version.

    +
  • +
+ +

Metabase 0.49.5

+ +

NOTE: These endpoint changes were added in 0.49.3, and a bug in GET /api/embed/card/:token/query/:export-format was fixed in 0.49.5.

+ +
    +
  • POST /api/card/:card-id/query/:export-format
  • +
  • POST /api/:dashboard-id/dashcard/:dashcard-id/card/:card-id/query/:export-format
  • +
  • POST /api/dataset/:export-format
  • +
  • GET /api/embed/card/:token/query/:export-format
  • +
  • +

    GET /api/embed/dashboard/:token/dashcard/:dashcard-id/card/:card-id/:export-format

    + +

    The above endpoints now accept the format_rows query parameter. It is an optional boolean parameter that will default to true if not included in the request. +When format_rows is true, the export will have formatting applied such that the values match what they appear as in the app. +When format_rows is false, formatting is not applied and exports will behave as they did prior to 0.49.0.

    + +

    The value of format_rows has no effect when exporting xlsx files.

    +
  • +
+ +

Metabase 0.49.0

+ +
    +
  • +

    POST /api/card and PUT /api/card/:id

    + +

    The dataset key is deprecated and will be removed in a future version, most likely 50. In its place we have added a new key: type which is equivalent in that it distinguishes Models from Questions. type="model" is equivalent to dataset=true and type="question" is equivalent to dataset=false.

    +
  • +
  • +

    all endpoints that return data (e.g. exports in JSON, XLSX, CSV, endpoints that end in “/query”)

    + +

    Starting from v49, we respond to the API calls with values formatted according to the instance localization options

    +
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/build.html b/_site/docs/doc-update-detection/developers-guide/build.html new file mode 100644 index 000000000..5c9f80bdf --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/build.html @@ -0,0 +1,3214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Building Metabase | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Building Metabase

+ +

This doc will show you how you can build and run Metabase on your own computer so you can play around with it or test features in development. You can also run development branches of Metabase using a pre-built Docker image.

+ +

Install the prerequisites

+ +

If you’re using macOS, you’ll want to install Xcode Command Line Tools first, by running:

+ +
xcode-select --install
+
+ +

To complete any build of the Metabase code, you’ll need to install the following.

+ +
    +
  1. +

    Clojure (https://clojure.org) - install the latest release by following the guide depending on your OS

    +
  2. +
  3. +

    Java Development Kit JDK (https://adoptopenjdk.net/releases.html) - you need to install JDK 11 (more info on Java versions)

    +
  4. +
  5. +

    Node.js (http://nodejs.org/) - latest LTS release

    +
  6. +
  7. +

    Yarn package manager for Node.js - latest release of version 1.x - you can install it in any OS by running:

    +
  8. +
+ +
npm install --global yarn
+
+ +

On a most recent stable Ubuntu/Debian, all the tools above, with the exception of Clojure, can be installed by using:

+ +
sudo apt install openjdk-11-jdk nodejs && sudo npm install --global yarn
+
+ +

If you have multiple JDK versions installed in your machine, be sure to switch your JDK before building with:

+ +
sudo update-alternatives --config java
+
+ +

Then select Java 21 in the menu.

+ +

Running on M1 Apple computers

+ +

If you are developing on newer Apple M1 computers, please note that the current NodeJS LTS has native support for arm architecture. However, make sure you have Rosetta 2 installed before you attempt to build the frontend:

+ +
/usr/sbin/softwareupdate --install-rosetta (root permission not required)
+
+ +

or

+ +
/usr/sbin/softwareupdate --install-rosetta --agree-to-license (root permission required)
+
+ +

If you’re running Windows, use WSL

+ +

If you are developing on Windows, you should run Ubuntu on Windows Subsystem for Linux (WSL) and follow instructions for Ubuntu/Linux.

+ +

Developing with VS Code in a remote container

+ +

Alternatively, without the need to explicitly install the above dependencies, follow the guide on using Visual Studio Code and its remote container support.

+ +

Clone the Metabase repo

+ +

Once you’ve installed all the build tools, you’ll need to clone the Metabase repository from GitHub.

+ +
    +
  1. +

    Create a workspace folder (you can name it that or whatever you want), which will store the Metabase code files.

    +
  2. +
  3. +

    Open up your terminal app, and navigate to your workspace folder with:

    +
  4. +
+ +
cd ~/workspace
+
+ +

{:start=”3”} 3. Run the following command to “clone” Metabase into this folder, using the URL of the Metabase repository on GitHub:

+ +
git clone https://github.com/metabase/metabase
+
+ +

Choose the branch you want to run, and run it

+ +

This is the part that you’ll use over and over.

+ +

The “official” branch of Metabase is called master, and other feature development branches get merged into it when they’re approved. So if you want to try out a feature before then, you’ll need to know the name of that branch so you can switch over to it. Here’s what to do:

+ +

{:start=”4”} 4. Open up your terminal app

+ +
    +
  1. +

    Navigate to where you’re storing the Metabase code. If you followed this guide exactly, you’d get there by entering this command:

    + +
    cd ~/workspace/metabase
    +
    +
  2. +
  3. +

    “Pull” down the latest code by running:

    + +
    git pull
    +
    + +

    You should do this every time to make sure that you have all the latest Metabase branches and code on your computer. It’s also how you’ll get updates on a feature branch someone make changes to it.

    +
  4. +
  5. +

    Find the name of the branch you want to run by going to the “pull request” page for that feature on GitHub and copying the branch name from there. Here’s an example PR page, with the branch name +fix-native-dataset-drill-popover.

    +
  6. +
  7. +

    Switch to, or “check out,” that branch by running:

    + +
    git checkout <branch-name>
    +
    + +

    If we wanted to switch to the branch in the previous step, we’d run:

    + +
    git checkout fix-native-dataset-drill-popover
    +
    + +

    When you want to switch back to master, run:

    + +
    git checkout master
    +
    +
  8. +
+ +

Run Metabase

+ +

{:start=”9”} 9. Now we’ll start up the backend server of Metabase with:

+ +
clojure -M:run
+
+ +

When it’s done, you should see a message that says something like “Metabase initialization complete.” Keep this tab in your terminal app running, otherwise it’ll stop Metabase.

+ +
    +
  1. Open up another tab or window of your terminal app, and then “build” the frontend (all the UI) with this command:
  2. +
+ +
yarn build-hot
+
+ +

If you’re having trouble with this step, make sure you are using the LTS version of Node.js (http://nodejs.org/).

+ +

{:start=”11”} 11. In your web browser of choice, navigate to http://localhost:3000, where you should see Metabase!

+ +

This is the local “server” on your computer, and 3000 is the “port” that Metabase is running on. You can have multiple different apps running on different ports on your own computer. Note that if you share any URLs with others that begin with localhost, they won’t be able to access them because your computer by default isn’t open up to the whole world, for security.

+ +

To switch to a different branch or back to master, open up another Terminal tab, and repeat steps 6, 7, and 8. If Metabase wasn’t already running, you’ll need to complete steps 9 and 10 again too. If it was already running, the frontend will automatically rebuild itself. You can check its progress by switching to that tab in your Terminal — it usually takes something like 15 seconds, but will depend on your hardware.

+ +

Shutting down Metabase

+ +

If you want to make Metabase stop running, you can either quit your terminal program, or go to the tab with the backend running and hit Ctrl+C to stop the backend. Most of the time you don’t have to do this to switch branches, but there are some cases where the change or feature you’re trying to see is a change with the backend, and you may need to stop the backend with Ctrl+C and then restart it by completing step 9 again.

+ +

Building the Metabase Uberjar

+ +

The entire Metabase application is compiled and assembled into a single .jar file which can run on any modern JVM. There is a script which will execute all steps in the process and output the final artifact for you. You can pass the environment variable MB_EDITION before running the build script to choose the version that you want to build. If you don’t provide a value, the default is oss which will build the Community Edition.

+ +
./bin/build.sh
+
+ +

After running the build script simply look in target/uberjar for the output .jar file and you are ready to go.

+ +

Build a Metabase Uberjar in a containerized environment

+ +

If you want to build Metabase without installing Clojure, Java, and Node.js on your host machine, you can build the Uberjar inside a container by running:

+ +
DOCKER_BUILDKIT=1 docker build --output container-output/ .
+
+ +

Make sure that your Docker Daemon is running before executing the command. After running the command, you’ll find the Metabase JAR file at ./container-output/app/metabase.jar.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/clojure.html b/_site/docs/doc-update-detection/developers-guide/clojure.html new file mode 100644 index 000000000..24fd378d1 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/clojure.html @@ -0,0 +1,3055 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Working with Clojure | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Working with Clojure

+ +

Check out Clojure for the Brave and True. It’s free online.

+ +

If you don’t feel like reading a whole book, Mark Volkmann’s Clojure tutorial is another good starting point.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/code-reviews.html b/_site/docs/doc-update-detection/developers-guide/code-reviews.html new file mode 100644 index 000000000..f63d0dde9 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/code-reviews.html @@ -0,0 +1,3119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Code reviews | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Code reviews

+ +

The overall goal of a code review is to serve as a safety net for other people on our team and help them write better code, not to judge them or their code. When in doubt, assume that they have good intentions and BE NICE.

+ +

Goals

+ +
    +
  • Catch bugs
  • +
  • Catch non-obvious consequences of an approach - will this PR make future code harder to secure or more buggy.
  • +
  • For situations where things were coded without being discussed, a code review serves as a sanity check to make sure a correct approach is being taken
  • +
  • Point out implications of the PR for parts of Metabase that a PR doesn’t touch
  • +
  • Point out places where a good approach or style was used. Code reviews are not a hatefest. Unless a PR is completely horrific there should be an equal number of good and bad points brought up.
  • +
+ +

Mindset giving a code review

+ +

Your primary goal as a reviewer is to serve as a safety net and keep bad code from being merged. The definition of “bad” is highly subjective, context dependent and will change with product time and maturity.

+ +

When you find clear mistakes, take the time to note why you think they are mistakes.

+ +

If you see places where you don’t agree with an approach, speak up. However, also take the time to understand why the author made a certain choice. You should assume that the author made a good decision based on what they knew in the moment. You probably have a different set of knowledge and see different outcomes. Dig into these. They might see things you don’t and vice versa.

+ +

Look for tricks, techniques, or idioms you can steal. Your teammates are smart folks. Chances are they have tricks that you can learn from. Make a point of letting them know.

+ +

Mindset getting a code review

+ +

The reviewer is doing you a Solid. They are there to help you do the best work you can. The best of the best have coaches, editors and mentors. Your code reviewers should help you in the same way. In situations where they are more experienced, this can be direct mentoring. In situations where they are more junior, they have a fresh pair of eyes that might get you to question deeply held assumptions.

+ +

When a reviewer disagrees with an approach you took, seek to understand why. They might know things or see consequences you didn’t. While they might not have thought as deeply on the specific subject of the PR as you, they likewise probably are thinking about the impacts of the PR on areas you might not be paying attention to.

+ +

If someone slaps a strong :-1: on your PR, be especially patient. Dig into why they think the PR is flawed. Approach the conversation with an intent of making the PR better, not defending your approach. You get no points for being a better debater, but you do get points for shipping better code and a better product, no matter where the inspiration or ideas came from.

+ +

Process

+ +
    +
  • Every PR of significant complexity needs to be :+1:’d by at least one other engineer on the team (or @salsakran) to merge
  • +
  • Add people you think should review your PR to the PR’s assignees. The reviewer can remove themselves once they have reviewed it, or decided they aren’t an appropriate reviewer
  • +
  • Code that impacts other engineer’s work should be reviewed by those engineers
  • +
  • A :+1: is the default “I’m ok with this”
  • +
  • A :+0: (I made that up) is “I’m not thrilled with this, but other people saying “+1” means it can be merged
  • +
  • A :-1: is a hard veto. This should be used sparingly in run of the mill PRs, and only for things that are missing tests, flagrant violations of a style guide, or break assumptions another part of the code base depends on.
  • +
  • If you cut a major branch without discussing design, or talking through implications with other engineers whose work might be impacted, you should expect a :-1:, and not be hung up on reworking controversial sections.
  • +
  • Any PR that has a :-1: CANNOT be merged until it is resolved.
  • +
  • The owner of the PR and the person casting a :-1: should resolve the differences in approach.
  • +
  • If there’s an impasse, @salsakran casts a tie-breaking vote. Impasses should be rare.
  • +
+ +

Note that these :+1:, :+0:, and :-1:’s should be explicitly stated in a comment, and not a reaction on the main description of the PR on github. A change from :-1: to :+1: should also be stated explicitly on a comment.

+ +

Timing

+ +
    +
  • PRs for high priority issues should be code reviewed as soon as they are available.
  • +
  • PRs for issues in a milestone can wait a few days.
  • +
  • If there are no :+1:’s on a PR, it is the responsibility of the PR creator to follow up with others and get their code reviewed. To re-iterate, a PR needs to be :+1:’d to be merged, and if it has not been reviewed, it is on the opener of the PR to round up a reviewer.
  • +
  • If there’s a :-1: + no clear resolution, both the creator of the PR and the :-1: voter should plan on spending an hour over the next day or two to discuss the issue, and plan on how to resolve it.
  • +
  • In the event of no movement on a PR with a :-1: after a week, @salsakran will chime in.
  • +
+ +

How to improve the quality of the code review

+ +

For a summary of research on code reviews, check out How code review works (and doesn’t) in the real world.

+ +

What PR authors can do to get a better review

+ +
    +
  • Guide reviewers by commenting on the important sections of the code.
  • +
  • If you need someone’s expertise/opinion, tag that person.
  • +
  • Enhance PR descriptions by using Notes and Warnings - these can be effective tools if you want a certain piece of information to stand out.
  • +
+ +

What PR reviewers can do to give a better review

+ +
    +
  • Pay close attention to test files. Be aware of our tendency to assign lower significance to the test files and put a conscious effort to review them thoroughly.
  • +
  • Start with the file most important to the change, not the first file presented in an alphabetical order in the PR.
  • +
  • If you feel like you’re lacking the context, ask the author for more details/better description.
  • +
  • Unless the change is trivial, check out that branch and give Metabase a spin locally with the changes included. Make sure everything works as expected.
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/community-drivers.html b/_site/docs/doc-update-detection/developers-guide/community-drivers.html new file mode 100644 index 000000000..9d94211af --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/community-drivers.html @@ -0,0 +1,3161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Community drivers | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Community drivers

+ +
+

Community drivers are not supported on Metabase Cloud.

+
+ +

In addition to our Officially supported drivers, many people build and maintain drivers for database integrations.

+ +

How to use a Community driver

+ +

To use a Community driver on a self-hosted Metabase:

+ +
    +
  1. Download the latest jar file from the driver’s repository (see the repo’s Releases section for the JAR files).
  2. +
  3. Copy the JAR file into the plugins directory in your Metabase directory (the directory where you run the Metabase JAR).
  4. +
+ +

You can change the location of the plugins directory by setting the environment variable MB_PLUGINS_DIR.

+ +

Community drivers

+ +
+

You install these drivers at your own risk. The plugins run as part of your Metabase and will have access to anything your Metabase does. And since we can’t vet for them, we don’t make them available on Metabase Cloud.

+
+ +

Anyone can build a community driver. These are the currently known third-party database drivers for Metabase.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DatabaseGitHub StarsLast release (if available)
CSVGitHub starsGitHub (Pre-)Release Date
DatabendGitHub starsGitHub (Pre-)Release Date
DB2GitHub starsGithub (Pre-)Release Date
DremioGitHub starsGitHub (Pre-)Release Date
DuckDBGitHub starsGitHub (Pre-)Release Date
FireboltGitHub starsGitHub (Pre-)Release Date
FirebirdGitHub starsGitHub (Pre-)Release Date
GreptimeDBGitHub starsGitHub (Pre-)Release Date
HydraHydra connections use the official Postgres driver.Not applicable.
ImpalaGitHub starsGitHub (Pre-)Release Date
MaterializeGitHub starsGitHub (Pre-)Release Date
Neo4jGitHub starsGitHub (Pre-)Release Date
Netsuite SuiteAnalytics ConnectGitHub starsGitHub (Pre-)Release Date
PeakaGitHub starsGitHub (Pre-)Release Date
TeradataGitHub starsGitHub (Pre-)Release Date
+ +

If you don’t see a driver for your database, try looking in the comments of the issue related to the database. You might also find more drivers by searching on GitHub for “Metabase driver”.

+ +

If you’re having problems installing or using a community driver, your best bet is to contact the author of the driver.

+ +

Write your own driver

+ +

Check out Guide to writing a Metabase driver.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/contributing.html b/_site/docs/doc-update-detection/developers-guide/contributing.html new file mode 100644 index 000000000..3c533398a --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/contributing.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/developers-guide/dev-branch-docker.html b/_site/docs/doc-update-detection/developers-guide/dev-branch-docker.html new file mode 100644 index 000000000..9d8e28571 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/dev-branch-docker.html @@ -0,0 +1,3100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +How to run a development branch of Metabase using Docker | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

How to run a development branch of Metabase using Docker

+ +

If you want to run a branch of Metabase that’s currently in development, the easiest way to get started is to use a pre-built Docker image. You can also compile Metabase yourself.

+ +

If you’re looking to download and run the latest official open source version of Metabase, check the operations guide.

+ +

Installing Docker

+ +

The only thing you’ll need to get started is Docker itself.

+ + + +

OR

+ +
    +
  • If you like to install things via Homebrew:
  • +
+ +
brew install --cask docker
+
+ +

Once Docker is installed, you’re ready to go.

+ +

Run a development branch to test or verify features

+ +

See here for a list of development branches that you can run via Docker.

+ +
    +
  1. +

    Open your terminal app of choice.

    +
  2. +
  3. +

    Copy and paste this command, switching out <branch-name> for the name of the branch you’d like to test:

    +
  4. +
+ +
docker run --platform linux/amd64 -d -p 3000:3000 --name metabase-dev metabase/metabase-dev:<branch-name>
+
+ +
    +
  1. In your browser, navigate to http://localhost:3000, where you should see Metabase. It may take a minute or two to start up depending on your computer.
  2. +
+ +

Note: This will always start Metabase with a fresh database.

+ +

Pull and run the latest changes

+ +

Run:

+ +
docker pull metabase/metabase-enterprise-head:latest
+
+ +

Then:

+ +
docker run --platform linux/amd64 -d -p 3000:3000 --name metabase metabase/metabase-enterprise-head:latest
+
+ +

The “latest” tag is not automatically upgraded on your local machine, so the above commands ensure that you’re pulling the latest changes.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/devenv.html b/_site/docs/doc-update-detection/developers-guide/devenv.html new file mode 100644 index 000000000..933e50961 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/devenv.html @@ -0,0 +1,3411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Development environment | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Development environment

+ +

The Metabase application has two basic components:

+ +
    +
  1. A backend written in Clojure which contains a REST API as well as all the relevant code for talking to databases and processing queries.
  2. +
  3. A frontend written as a Javascript single-page application which provides the web UI.
  4. +
+ +

Both components are built and assembled together into a single JAR file. In the directory where you run the JAR, you can create a JAR file (if Metabase hasn’t already created it) and add drivers in there (the drivers are also JARs).

+ +

Quick start

+ +

To spin up a development environment, run:

+ +
yarn dev
+
+ +

This runs both the frontend and backend. Alternatively, you can run them separately in two terminal sessions below.

+ +

Frontend

+ +

Metabase depends on third-party libraries to run, so you’ll need to keep those up to date. The Clojure CLI will automatically fetch the dependencies when needed. With JavaScript dependencies, however, you’ll need to kick off the installation process manually.

+ +
# javascript dependencies
+$ yarn
+
+ +

Start the frontend build process with

+ +
yarn build-hot
+
+ +

See Frontend development.

+ +

Backend

+ +

Run your backend development server with

+ +
clojure -M:run
+
+
+ +

See backend development.

+ +

Frontend development

+ +

We use these technologies for our FE build process to allow us to use modules, es6 syntax, and css variables.

+ +
    +
  • webpack
  • +
  • babel
  • +
  • cssnext
  • +
+ +

Frontend tasks are executed using yarn. All available tasks can be found in package.json under scripts.

+ +

To build the frontend client without watching for changes, you can use:

+ +
$ yarn build
+
+ +

If you’re working on the frontend directly, you’ll most likely want to reload changes on save, and in the case of React components, do so while maintaining state. To start a build with hot reloading, use:

+ +
$ yarn build-hot
+
+ +

Note that at this time if you change CSS variables, those changes will only be picked up when a build is restarted.

+ +

There is also an option to reload changes on save without hot reloading if you prefer that.

+ +
$ yarn build-watch
+
+ +

Some systems may have trouble detecting changes to frontend files. You can enable filesystem polling by uncommenting the watchOptions clause in webpack.config.js. If you do this it may be worth making git ignore changes to webpack config, using git update-index --assume-unchanged webpack.config.js

+ +

We exclude ESLint loader in dev mode for seven times quicker initial builds by default. You can enable it by exporting an environment variable:

+ +
$ USE_ESLINT=true yarn build-hot
+
+ +

Frontend testing

+ +

Run all unit and Cypress end-to-end tests with

+ +
yarn test
+
+ +

Cypress tests and some unit tests are located in frontend/test directory. New unit test files are added next to the files they test.

+ +

Frontend debugging

+ +

By default, we use a simple source mapping option that is optimized for speed.

+ +

If you run into issues with breakpoints, especially inside jsx, please set env variable BETTER_SOURCE_MAPS to true before you run the server.

+ +

Example:

+ +
BETTER_SOURCE_MAPS=true yarn dev
+
+ +

Cypress end-to-end tests

+ +

End-to-end tests simulate realistic sequences of user interactions. Read more about how we approach end-to-end testing with Cypress.

+ +

Cypress end-to-end tests use an enforced file naming convention <test-suite-name>.cy.spec.js to separate them from unit tests.

+ +

Jest unit tests

+ +

Unit tests are focused around isolated parts of business logic.

+ +

Unit tests use an enforced file naming convention <test-suite-name>.unit.spec.js to separate them from end-to-end tests.

+ +
yarn test-unit # Run all tests at once
+yarn test-unit-watch # Watch for file changes
+
+ +

Backend development

+ +

Clojure REPL is the main development tool for the backend. There are some directions below on how to setup your REPL for easier development.

+ +

And of course your Jetty development server is available via

+ +
clojure -M:run
+
+ +

You can also start a REPL another way (e.g., through your editor) and then call:

+ +
(do (dev) (start!))
+
+ +

To start the server (at localhost:3000). This will also set up or migrate your application database. To actually +use Metabase, don’t forget to start the frontend as well (e.g. with yarn build-hot).

+ +

The application database

+ +

By default, Metabase uses H2 for its application database, but we recommend using Postgres. This is configured with +several properties that can be set as environment variables or in a deps.edn. One approach is:

+ +
;; ~/.clojure/deps.edn
+
+{:aliases
+ {:user
+  {:jvm-opts
+   ["-Dmb.db.host=localhost"
+    "-Dmb.db.type=postgres"
+    "-Dmb.db.user=<username>"
+    "-Dmb.db.dbname=<dbname>"
+    "-Dmb.db.pass="]}}}
+
+ +

You could also pass a full conection string in as the mb.db.connection.uri:

+ +
"-Dmb.db.connection.uri=postgres://<user>:<password>@localhost:5432/<dbname>"
+
+ +

Besides using environment variables, there is the option to interface with the configuration library environ directly.

+ +

This approach requires creating a .lein-env file within your project directory:

+ +
{:mb-db-type   "postgres"
+ :mb-db-host   "localhost"
+ :mb-db-user   "<username>"
+ :mb-db-dbname "<dbname>"
+ :mb-db-pass   ""}
+
+ +

Despite the name, this file works fine with deps.edn projects. An advantage of this approach versus the global deps.edn approach is that it is scoped to this project only.

+ +

Only use this for development, it is not supported for production use. There is already entry in .gitignore to prevent you accidentally committing this file.

+ +

Building drivers

+ +

Most of the drivers Metabase uses to connect to external data warehouse databases are separate projects under the +modules/ subdirectory. When running Metabase via clojure, you’ll need to build these drivers in order to have access +to them. You can build drivers as follows:

+ +
# Build the 'mongo' driver
+./bin/build-driver.sh mongo
+
+ +

(or)

+ +
# Build all drivers
+./bin/build-drivers.sh
+
+ +

Including driver source paths for development or other tasks

+ +

For development when running various Clojure tasks you can add the drivers and drivers-dev aliases to merge the +drivers’ dependencies and source paths into the Metabase project:

+ +
# Install dependencies, including for drivers
+clojure -P -X:dev:ci:drivers:drivers-dev
+
+ +

Running unit tests

+ +

Run unit tests with

+ +
# OSS tests only
+clojure -X:dev:test
+
+# OSS + EE tests
+clojure -X:dev:ee:ee-dev:test
+
+ +

or a specific test (or test namespace) with

+ +
# run tests in only one namespace (pass in a symbol)
+clojure -X:dev:test :only metabase.session.api-test
+
+# run one specific test (pass in a qualified symbol)
+clojure -X:dev:test :only metabase.session.api-test/my-test
+
+# run tests in one specific folder (test/metabase/util in this example)
+# pass arg in double-quotes so Clojure CLI interprets it as a string;
+# our test runner treats strings as directories
+clojure -X:dev:test :only '"test/metabase/util"'
+
+ +

As in any clojure.test project, you can also run unit tests from the REPL. Some examples of useful ways to run tests are:

+ +
;; run a single test with clojure.test
+some-ns=> (clojure.test/run-test metabase.util-test/add-period-test)
+
+Testing metabase.util-test
+
+Ran 1 tests containing 4 assertions.
+0 failures, 0 errors.
+{:test 1, :pass 4, :fail 0, :error 0, :type :summary}
+
+;; run all tests in the namespace
+some-ns=> (clojure.test/run-tests 'metabase.util-test)
+
+Testing metabase.util-test
+{:result true, :num-tests 100, :seed 1696600311261, :time-elapsed-ms 45, :test-var "pick-first-test"}
+
+Ran 33 tests containing 195 assertions.
+0 failures, 0 errors.
+{:test 33, :pass 195, :fail 0, :error 0, :type :summary}
+
+;; run tests for a set of namespaces related to a feature you are working on (eg pulses)
+some-ns=> (let [namespaces '[metabase.pulse.markdown-test metabase.pulse.parameters-test]]
+            (apply require namespaces) ;; make sure the test namespaces are loaded
+            (apply clojure.test/run-tests namespaces))
+
+Testing metabase.pulse.markdown-test
+
+Testing metabase.pulse.parameters-test
+
+Ran 5 tests containing 147 assertions.
+0 failures, 0 errors.
+{:test 5, :pass 147, :fail 0, :error 0, :type :summary}
+
+;; but we also have a lovely test runner with lots of cool options
+some-ns=> (metabase.test-runner/find-and-run-tests-repl {:namespace-pattern ".*pulse.*"})
+Running tests with options {:mode :repl, :namespace-pattern ".*pulse.*", :exclude-directories ["classes" "dev" "enterprise/backend/src" "local" "resources" "resources-ee" "src" "target" "test_config" "test_resources"], :test-warn-time 3000}
+Excluding directory "dev/src"
+Excluding directory "local/src"
+Looking for test namespaces in directory test
+Finding tests took 1.6 s.
+Excluding directory "test_resources"
+Excluding directory "enterprise/backend/src"
+Looking for test namespaces in directory enterprise/backend/test
+Excluding directory "src"
+Excluding directory "resources"
+Running 159 tests
+...
+
+;; you can even specify a directory if you're working on a subfeature like that
+some-ns=> (metabase.test-runner/find-and-run-tests-repl {:only "test/metabase/pulse/"})
+Running tests with options {:mode :repl, :namespace-pattern #"^metabase.*", :exclude-directories ["classes" "dev" "enterprise/backend/src" "local" "resources" "resources-ee" "src" "target" "test_config" "test_resources"], :test-warn-time 3000, :only "test/metabase/pulse/"}
+Running tests in "test/metabase/pulse/"
+Looking for test namespaces in directory test/metabase/pulse
+Finding tests took 37.0 ms.
+Running 65 tests
+...
+
+
+ +

Testing drivers

+ +

By default, the tests only run against the h2 driver. You can specify which drivers to run tests against with the env var DRIVERS:

+ +
DRIVERS=h2,postgres,mysql,mongo clojure -X:dev:drivers:drivers-dev:test
+
+ +

Some drivers require additional environment variables when testing since they are impossible to run locally (such as +Redshift and Bigquery). The tests will fail on launch and let you know what parameters to supply if needed.

+ +

If running tests from the REPL, you can call something like:

+ +
(mt/set-test-drivers! #{:postgres :mysql :h2})
+
+ +

Most drivers need to be able to load some data (a few use static datasets) and all drivers need to be able to connect to an instance of that database. You can find out what is needed in each’s drivers test data namespace which follows that pattern metabase.test.data.<driver>.

+ +

There should be an implementation of a multimethod tx/dbdef->connection-details which must produce a way to connect to a database. You can see what is required.

+ +

Here’s the one for postgres in metabase.test.data.postgres:

+ +
(defmethod tx/dbdef->connection-details :postgres
+  [_ context {:keys [database-name]}]
+  (merge
+   {:host     (tx/db-test-env-var-or-throw :postgresql :host "localhost")
+    :port     (tx/db-test-env-var-or-throw :postgresql :port 5432)
+    :timezone :America/Los_Angeles}
+   (when-let [user (tx/db-test-env-var :postgresql :user)]
+     {:user user})
+   (when-let [password (tx/db-test-env-var :postgresql :password)]
+     {:password password})
+   (when (= context :db)
+     {:db database-name})))
+
+ +

You can see that this looks in the environment for:

+ +
    +
  • host (defaults to “localhost”)
  • +
  • port (defaults to 5432)
  • +
  • user
  • +
  • password
  • +
+ +

The function names indicate if they throw or not (although in this instance the ones that would throw are also supplied default values).

+ +

The (tx/db-test-env-var :postgresql :password) will look in the env/env map for :mb-postgresql-test-password which will be set by the environmental variable MB_POSTGRESQL_TEST_PASSWORD.

+ +
some-ns=> (take 10 (keys environ.core/env))
+(:mb-redshift-test-password
+ :java-class-path
+ :path
+ :mb-athena-test-s3-staging-dir
+ :iterm-profile
+ :mb-snowflake-test-warehouse
+ :mb-bigquery-cloud-sdk-test-service-account-json
+ :tmpdir
+ :mb-oracle-test-service-name
+ :sun-management-compiler)
+
+ +

Running the linters

+ +

clj-kondo must be installed separately.

+ +
# Run Eastwood
+clojure -X:dev:ee:ee-dev:drivers:drivers-dev:eastwood
+
+# Run the namespace checker
+clojure -X:dev:ee:ee-dev:drivers:drivers-dev:test:namespace-checker
+
+# Run clj-kondo
+./bin/kondo.sh
+
+# Lint the migrations file (if you've written a database migration):
+./bin/lint-migrations-file.sh
+
+ +

Continuous integration

+ +

All frontend and backend linters and tests can be executed with

+ +
$ yarn ci
+
+ +

It is also possible to execute front-end and back-end checks separately

+ +
$ yarn ci-frontend
+$ yarn ci-backend
+
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/docs.html b/_site/docs/doc-update-detection/developers-guide/docs.html new file mode 100644 index 000000000..7071a15a1 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/docs.html @@ -0,0 +1,3075 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Developing Metabase documentation | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Developing Metabase documentation

+ +

Notes on writing docs for Metabase.

+ + + +

You can check for broken links in the docs directory by running:

+ +
yarn run docs-lint-links
+
+ +

This command uses Markdown link check to vet links in all of the markdown files in the docs directory. We recommend writing the command’s output to a file. E.links.,

+ +
touch ~/links-to-fix.txt && yarn run docs-lint-links > ~/links-to-fix.txt
+
+ +

Alternatively, if you just want to check the in-product links to make sure they link to actual documents:

+ +
yarn run lint-docs-links
+
+ +

You can view both commands in the package.json file under scripts.

+ +

Updating API docs

+ +

To update an API endpoint description, you’ll need to edit the comment in the source code for that endpoint.

+ +

To bring your changes into docs/latest/api-documentation, you’ll need to open a separate PR. Check out a new branch from the current release branch, and run:

+ +
clojure -M:ee:run api-documentation
+
+ +

Style guide

+ +

Ancient style guide that needs an update.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/driver-changelog.html b/_site/docs/doc-update-detection/developers-guide/driver-changelog.html new file mode 100644 index 000000000..eeb521d9f --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/driver-changelog.html @@ -0,0 +1,4077 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Driver interface changelog | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Driver Interface Changelog

+ +

Metabase 0.55.0

+ +
    +
  • Added a feature :expression-literals for drivers that support expressions consisting of a single string, number, or boolean literal value.
  • +
+ +

Metabase 0.54.0

+ +
    +
  • +

    Added the multi-method allowed-promotions that allows driver control over which column type promotions are supported for uploads.

    +
  • +
  • +

    Added the multi-method alter-table-columns!, like alter-columns! but accepts additional kw-arg opts. +Existing implementations of alter-columns! will be used by default.

    +
  • +
  • +

    alter-columns! is now marked as deprecated. Drivers +should seek to implement the new alter-table-columns! method.

    +
  • +
  • +

    The multimethod metabase.driver.sql-jdbc.sync.interface/alter-table-columns-sql has been added, like alter-columns-sql but accepts additional kw-arg opts. Existing implementations of alter-columns-sql will be used by default.

    +
  • +
  • +

    metabase.driver.sql-jdbc.sync.interface/alter-columns-sql is now marked as deprecated. Drivers should seek to implement the new alter-table-columns-sql method.

    +
  • +
  • +

    Added a feature :test/arrays and multimethod native-array-query to enable the testing of array types for +databases that support them.

    +
  • +
  • +

    Added a feature :expressions/text for drivers that support casting to text

    +
  • +
  • +

    Added a feature :expressions/date for drivers that support casting text to date

    +
  • +
  • +

    Added a feature :expressions/integer for drivers that support casting text to integer

    +
  • +
  • +

    Added a feature :distinct-where for drivers that support the distinct-where function.

    +
  • +
  • +

    Added a feature :split-part for drivers that support the split-part function.

    +
  • +
+ +

Metabase 0.53.0

+ +
    +
  • +

    Added the multimethod bad-connection-details to allow mocking bad connection parameters for tests.

    +
  • +
  • +

    Added driver/dynamic-database-types-lookup and its :postgres implementation. The method generates map +of database_type to base_type, for dynamic types, ie. those which are not covered +by sql-jdbc.sync/database-type->base-type. Its original purpose was to enable mapping of user defined enums in +postgres to appropriate base type in results metadata.

    +
  • +
+ +

Metabase 0.52.12

+ +
    +
  • Added the multimethod metabase.driver/db-details-to-test-and-migrate. This can be used to cleanup and migrate ambiguous connection details from previous versions.
  • +
+ +

Metabase 0.52.0

+ +
    +
  • +

    The Docker image for Metabase 0.52.0 now uses Java 21 instead of Java 11. Please make sure to test your driver +against Java 21 and make sure it works as expected.

    + +

    We have found several of our own drivers that run into issues with the security changes introduced in newer JVMs; as +such, we’re currently setting the JVM flag

    + +
    --add-opens java.base/java.nio=ALL-UNNAMED
    +
    + +

    when running Metabase to disable some of these new security checks. If your tests run into issues with Java 21 +without the flag set, try running with it set – this might fix the problems.

    +
  • +
+ +

Metabase 0.51.4

+ +
    +
  • +

    Another driver feature has been added: describe-indexes. If a driver opts-in to supporting this feature, The +multimethod metabase.driver/describe-indexes must be implemented, as a replacement for +metabase.driver/describe-table-indexes.

    +
  • +
  • +

    The multimethod metabase.driver.sql-jdbc.sync.describe-table/describe-indexes-sql has been added. The method needs +to be implemented if the driver supports describe-indexes and you want to use the default JDBC implementation of +metabase.driver/describe-indexes.

    +
  • +
+ +

Metabase 0.51.0

+ +
    +
  • +

    New optional method metabase.driver/query-result-metadata has been added for efficiently calculating metadata for +queries without actually running them. :sql-jdbc has been given a default implementation; drivers not based on +this that can determine result metadata without actually running queries should add their implementations as well +for better performance when saving Questions. Refer to the method docstring for more information and where to find +an example implementation.

    +
  • +
  • +

    Prior to 0.51.0, to generate SQL queries with inline parameters, Metabase would generate a parameterized SQL string, +then attempt to parse the SQL replace and replace ? placeholders with inline values from the driver method +metabase.driver.sql.util.unprepare/unprepare-value. In 0.51.0+, Metabase instead generates these queries using +Honey SQL 2’s :inline option, eliminating the need to parse and replace ? placeholders. As such, the +metabase.driver.sql.util.unprepare namespace has been deprecated; you should remove all usages of it in your driver.

    +
  • +
  • +

    The metabase.driver.sql.util.unprepare/unprepare-value method has been replaced by the new method +metabase.driver.sql.query-processor/inline-value. The signatures of these two functions are the same, and you +should be able to simply change the all of your unprepare-value implementations to inline-value instead. See +PR #45008 for examples of this change.

    + +

    For the time being, implementations of unprepare-value are used as implementations of inline-value +automatically, but unprepare-value is slated for removal in 0.54.0.

    +
  • +
  • +

    metabase.driver.sql.query-processor/format-honeysql is now a multimethod, mainly so you can bind +*compile-with-inline-parameters* if you need to always compile without parameterization.

    +
  • +
  • +

    The dynamic variable metabase.driver/*compile-with-inline-parameters* (default false) has been added; drivers +that can generate parameterized queries should look at its value in their implementation of +metabase.driver/mbql->native and adjust their output accordingly. For :sql-jdbc-based drivers that support +parameterization, this is handled in the shared metabase.driver.sql.query-processor code, so you shouldn’t need +to adjust anything here. For :sql drivers that do not support JDBC-style parameterized queries you can implement +format-honeysql and bind *compile-with-inline-parameters* as discussed above. See the :athena driver for an +example of how to do this.

    +
  • +
  • +

    metabase.driver.sql.util.unprepare/unprepare, which took a parameterized SQL string and de-parameterized or +“unprepared” it, has been removed. Instead, if you need a query with parameters spliced directly into the SQL, +bind metabase.driver/*compile-with-inline-parameters* as discussed above.

    +
  • +
  • +

    Similarly, the driver method metabase.driver/splice-parameters-into-native-query has been marked deprecated, and +the default implementation will throw an Exception if called. Rework code that generates parameterized queries and +then calls unprepare or splice-parameters-into-native-query with code that generates queries with inlined +parameters in the first place as discussed above. Tests can use +metabase.query-processor.compile/compile-with-inline-parameters if needed.

    +
  • +
  • +

    metabase.query-processor.compile/compile-and-splice-parameters has been removed; replace usages with +metabase.query-processor.compile/compile-with-inline-parameters.

    +
  • +
  • +

    The three-arity of metabase.driver.sql.query-processor/format-honeysql (which had an additional parameter for +Honey SQL version) has been removed; replace all usages with the two-arity version. Honey SQL 2 has been the only +supported version since Metabase 0.49.0.

    +
  • +
  • +

    The :skip-drop-db? option sometimes passed to methods for loading and destroying test data is no longer passed, +you can remove code that checks for it. Test data code is now better about avoiding unneeded/redundant calls to +metabase.test.data.interface/create-db!, so test data loading code should not need to call DROP DATABASE IF EXISTS before loading test data.

    +
  • +
  • +

    Test data loading for JDBC-based databases has been overhauled somewhat. The multimethod +metabase.test.data.sql-jdbc.load-data/load-data! and helper functions for it have been removed in favor of several +new simpler to compose and understand multimethods.

    +
  • +
  • +

    metabase.test.data.sql-jdbc.load-data/row-xform is a transducer applied to each row when loading test data. The +default implementation is identity, but you can use metabase.test.data.sql-jdbc.load-data/add-ids-xform to add +IDs to each row (this replaces the removed metabase.test.data.sql-jdbc.load-data/load-data-add-ids function) and +metabase.test.data.sql-jdbc.load-data/maybe-add-ids-xform (which replaces +metabase.test.data.sql-jdbc.load-data/load-data-maybe-add-ids! and +metabase.test.data.sql-jdbc.load-data/load-data-maybe-add-ids-chunked!).

    +
  • +
  • +

    metabase.test.data.sql-jdbc.load-data/chunk-size is used to control the number of rows that should be loaded in +each batch. The default is 200, but you can implement this method and return nil to load data all at once +regardless of the number of rows. metabase.test.data.sql-jdbc.load-data/*chunk-size*, +metabase.test.data.sql-jdbc.load-data/load-data-chunked, +metabase.test.data.sql-jdbc.load-data/load-data-all-at-once!, +metabase.test.data.sql-jdbc.load-data/load-data-chunked!, and other similar functions are no longer needed and +have been removed.

    +
  • +
  • +

    metabase.test.data.sql-jdbc.load-data/chunk-xform is a transducer applied to each chunk of rows (dependent on +chunk-size) or the entire group of rows if chunk-size is nil. The default is identity. It can be used to +implement special behavior for each chunk, for example writing the chunk to a CSV file to load separately in the +metabase.test.data.sql-jdbc.load-data/do-insert! method. See the metabase.test.data.vertica for an example of +this.

    +
  • +
  • +

    Connections are now created once and reused for much of test data loading. The second argument to +metabase.test.data.sql-jdbc.load-data/do-insert! is now a java.sql.Connection instead of a clojure.java.jdbc +spec.

    +
  • +
  • +

    Similarly, metabase.test.data.sql-jdbc.execute/execute-sql! and helper functions like +metabase.test.data.sql-jdbc.execute/sequentially-execute-sql! are now called with a java.sql.Connection +instead of both a DatabaseDefinition and either :server or :db context; the appropriate connection type is +created automatically and passed in in the calling code. Update your method implementations and usages +accordingly.

    +
  • +
  • +

    Added method metabase.test.data.interface/dataset-already-loaded? to check if a test dataset has already been +loaded. JDBC-based drivers have a default implementation that checks whether we can connect to the database; you +may need to override this for drivers that don’t actually physically create new databases in tests. You can check +whether your JDBC-based driver works correctly using the default implementation by running the test +metabase.test.data.sql-jdbc-test/dataset-already-loaded?-test.

    +
  • +
  • +

    metabase.test.data.sql.ddl/insert-rows-ddl-statements has been renamed to +metabase.test.data.sql.ddl/insert-rows-dml-statements, since INSERT is DML, not DDL. Please update your method +implementations accordingly.

    +
  • +
  • +

    The :foreign-keys driver feature has been removed. :metadata/keys-constraints should be used for drivers that +support foreign key relationships reporting during sync. Implicit joins now depend on the :left-join feature +instead. The default value is true for :sql based drivers. All join features are now enabled for :sql based +drivers by default. Previously, those depended on the :foreign-keys feature. If your driver supports :left-join, +the test for remapping and implicit joins will be now executed.

    +
  • +
  • +

    The:parameterized-sql driver feature has been added to distinguish drivers that don’t support parametrized SQL in +tests. Currently, this is disabled only for :sparksql.

    +
  • +
  • +

    The test methods metabase.test.data.interface/supports-time-type? and +metabase.test.data.interface/supports-timestamptz-type? have been removed and replaced by the features +:test/time-type and :test/timestamptz-type respectively. If you implemented these methods, replace +implementations with implementations of metabase.driver/database-supports? for your driver and the equivalent +feature keyword instead.

    +
  • +
  • +

    Drivers that use metabase.driver.sql.query-processor/->honeysql can implement +:metabase.driver.sql.query-processor/nfc-path to include the nfc-path in the field identifier. So that record-like +fields can be referenced with <table>.<record>.<record-field>. See bigquery-cloud-sdk for an example. Defaults to nil to indicate that the path should not be part of the identifier.

    +
  • +
  • +

    :test/dynamic-dataset-loading feature has been added. It enables drivers to bail out of tests that require +creation of new, not pre-loaded, dataset during test run time.

    +
  • +
  • +

    The :temporal/requires-default-unit feature has been added. It should be false for most drivers, but it’s necessary +for a few (like the old, pre-JDBC Druid driver) to find all temporal field refs and put a :temporal-unit :default on them. +That default setting was previously done for all drivers, but it introduced some downstream issues, so now only those +drivers which need it can set the feature.

    +
  • +
+ +

Metabase 0.50.17

+ +
    +
  • Added method metabase.driver/incorporate-auth-provider-details for driver specific behavior required to +incorporate response of an auth-provider into the DB details. In most cases this means setting the :password +and/or :username based on the auth-provider and its response.
  • +
+ +

Metabase 0.50.16

+ +
    +
  • +

    :type/fingerprinting-unsupported has been added in the metabase.types namespace. Similar to +:type/field-values-unsupported for field values scanning, it is used to determine whether a specific field +should have its fingerprint computed or not. At the time of writing that logic is performed in +metabase.sync.analyze.fingerprint/fields-to-fingerprint-base-clause.

    +
  • +
  • +

    :type/Large has been also been added in the metabase.types namespace. It can be used by driver authors to +signal that a specific field contains large enough values to skip fingerprinting or field values scanning. It +can be used for other purposes as well in the future. Examples include Oracle CLOB or Postgres JSON columns.

    +
  • +
+ +

Metabase 0.50.0

+ +
    +
  • +

    The Metabase metabase.mbql.* namespaces have been moved to metabase.legacy-mbql.*. You probably didn’t need to +use these namespaces in your driver, but if you did, please update them.

    +
  • +
  • +

    The multimethod metabase.driver/truncate! has been added. This method is used to delete a table’s rows in the most +efficient way possible. This is currently only required for drivers that support the :uploads feature, and has +a default implementation for JDBC-based drivers.

    +
  • +
  • +

    New feature :window-functions/cumulative has been added. Drivers that implement this method are expected to +implement the cumulative sum (:cum-sum) and cumulative count (:cum-count) aggregation clauses in their native +query language. For non-SQL drivers (drivers not based on our :sql or :sql-jdbc drivers), this feature flag is +set to false by default; the old (broken) post-processing implementations of cumulative aggregations will continue +to be used. (See issues #13634 and +#15118 for more information on why the old implementation is +broken.)

    + +

    Non-SQL drivers should be updated to implement cumulative aggregations natively if possible.

    + +

    The SQL implementation uses OVER (...) expressions. It will automatically move GROUP BY expressions like +date_trunc() into a SUBSELECT so fussy databases like BigQuery can reference plain column identifiers. The +actual SQL generated will look something like

    + +
    SELECT
    +  created_at_month,
    +  sum(sum(total) OVER (ORDER BY created_at_month ROWS UNBOUNDED PRECEDING) AS cumulative_sum
    +FROM (
    +  SELECT
    +    date_trunc('month', created_at) AS created_at_month,
    +    total
    +  FROM
    +    my_table
    +  ) source
    +GROUP BY
    +  created_at_month
    +ORDER BY
    +  created_at_month
    +
    + +

    Non-SQL drivers can use +metabase.query-processor.util.transformations.nest-breakouts/nest-breakouts-in-stages-with-window-aggregation +if they want to leverage the same query transformation. See the default :sql implementation of +metabase.driver.sql.query-processor/preprocess for an example of using this transformation when needed.

    + +

    You can run the new tests in metabase.query-processor-test.cumulative-aggregation-test to verify that your driver +implementation is working correctly.

    +
  • +
  • +

    metabase.driver.common/class->base-type no longer supports Joda Time classes. They have been deprecated since 2019.

    +
  • +
  • +

    New feature :window-functions/offset has been added to signify that a driver supports the new MBQL :offset +clause (equivalent of SQL lead and lag functions). This is enabled by default for :sql and :sql-jdbc-based +drivers. Other drivers should add an implementation for this clause and enable the feature flag.

    +
  • +
  • +

    :type/field-values-unsupported was added in metabase.types namespace. It is used in field values computation +logic, to determine whether a specific field should have its field values computed or not. At the time of writing +that is performed in metabase.models.field-values/field-should-have-field-values?. Deriving from it, driver +developers have a way to out of field values computation for fields that are incompatible with the query used for +computation. Example could be Druid’s COMPLEX<JSON> database type fields. See the :druid-jdbc implementation +of sql-jdbc.sync/database-type->base-type in the metabase.driver.druid-jdbc and derivations in the +metabase.types namespace for an example.

    +
  • +
  • +

    New feature :metadata/key-constraints has been added to signify that a driver support defining and enforcing foreign +key constraints at the schema level. This is a different, stronger condition than :foreign-keys. Some databases +(Presto, Athena, etc.) support querying over foreign key relationships (:foreign-keys) but do not track or enforce +those relationships in the schema. Defaults to true in :sql and :sql-jdbc drivers; set to false in the +first-party SparkSQL, Presto and Athena drivers.

    +
  • +
  • +

    New feature :connection/multiple-databases has been added to indicate whether a connection to this driver +corresponds to multiple databases or just one. The default is false, where a connection specifies a single database. +This is the common case for classic relational DBs like Postgres, and some cloud databases. In contrast, a driver like +Athena sets this to true because it connects to an S3 bucket and treats each file within it as a database.

    +
  • +
  • +

    New feature :identifiers-with-spaces has been added to indicate where a driver supports identifiers like table or +column names that contains a space character. Defaults to false.

    +
  • +
  • +

    New feature :uuid-type has been added to indicate that this database is able to distinguish and filter against UUIDs. +Only a few database support native UUID types. The default is false.

    +
  • +
+ +

Metabase 0.49.22

+ +
    +
  • A new optional method metabase.driver.sql/json-field-length has been added. It should be implemented for all +drivers that derive from :sql and support the :nested-field-columns feature. If implemented, Metabase will skip +querying large JSON values during the “sync-fields” step that could otherwise slow down the inference of nested +field columns and cause Metabase to run out of heap space.
  • +
+ +

Metabase 0.49.9

+ +
    +
  • Another driver feature has been added: upload-with-auto-pk. It only affects drivers that support uploads, and +is optional to support. Drivers support this feature by default, and can choose not to support it if there is no way +to create a table with an auto-incrementing integer column. The driver can override the default using +driver/database-supports?.
  • +
+ +

Metabase 0.49.1

+ +
    +
  • +

    Another driver feature has been added: describe-fields. If a driver opts-in to supporting this feature, The +multimethod metabase.driver/describe-fields must be implemented, as a replacement for +metabase.driver/describe-table.

    +
  • +
  • +

    The multimethod metabase.driver.sql-jdbc.sync.describe-table/describe-fields-sql has been added. The method needs +to be implemented if the driver supports describe-fields and you want to use the default JDBC implementation of +metabase.driver/describe-fields.

    +
  • +
+ +

Metabase 0.49.0

+ +
    +
  • +

    The multimethod metabase.driver/describe-table-fks has been deprecated in favor of metabase.driver/describe-fks. +metabase.driver/describe-table-fks will be removed in 0.52.0.

    +
  • +
  • +

    The multimethod metabase.driver/describe-fks has been added. The method needs to be implemented if the database +supports the :foreign-keys and :describe-fks features. It replaces the metabase.driver/describe-table-fks +method, which is now deprecated.

    +
  • +
  • +

    The multimethod metabase.driver.sql-jdbc.sync.describe-table/describe-fks-sql has been added. The method needs +to be implemented if you want to use the default JDBC implementation of metabase.driver/describe-fks.

    +
  • +
  • +

    The multimethod metabase.driver/alter-columns! has been added. This method is used to alter a table’s columns in the +database. This is currently only required for drivers that support the :uploads feature, and has a default +implementation for JDBC-based drivers.

    +
  • +
  • +

    The multimethod metabase.driver.sql-jdbc.sync.interface/alter-columns-sql has been added. The method +allows you to customize the query used by the default JDBC implementation of metabase.driver/alter-columns!.

    +
  • +
  • +

    The multimethod metabase.driver.sql-jdbc.sync.interface/current-user-table-privileges has been added. +JDBC-based drivers can implement this to improve the performance of the default SQL JDBC implementation of +metabase.driver/describe-database. It needs to be implemented if the database supports the :table-privileges +feature and the driver is JDBC-based.

    +
  • +
  • +

    The multimethod metabase.driver/create-table! can take an additional optional map with an optional key primary-key. +metabase.driver/upload-type->database-type must also be changed, so that if +:metabase.upload/auto-incrementing-int-pk is provided as the upload-type argument, the function should return a +type without the primary-key constraint included. See PR #22166 +for more information. These changes only need to be implemented if the database supports the :uploads feature.

    +
  • +
  • +

    The multimethod metabase.driver/create-auto-pk-with-append-csv? has been added. The method only needs to be +implemented if the database supported the :uploads feature in 47 or earlier, and should return true if so.

    +
  • +
  • +

    The multimethod metabase.driver/add-columns! has been added. This method is used to add columns to a table in the +database. It only needs to be implemented if the database supported the :uploads feature in 47 or earlier.

    +
  • +
  • +

    A new driver method has been added metabase.driver/describe-table-indexes along with a new feature :index-info. +This method is used to get a set of column names that are indexed or are the first columns in a composite index.

    +
  • +
  • +

    metabase.util.honeysql-extensions, deprecated in 0.46.0, has been removed. SQL-based drivers using Honey SQL 1 +are no longer supported. See 0.46.0 notes for more information. +metabase.driver.sql.query-processor/honey-sql-version is now deprecated and no longer called. All drivers are +assumed to use Honey SQL 2.

    +
  • +
  • +

    The method metabase.driver.sql.parameters.substitution/align-temporal-unit-with-param-type is now deprecated. +Use metabase.driver.sql.parameters.substitution/align-temporal-unit-with-param-type-and-value instead, +which has access to value and therefore provides more flexibility for choosing the right conversion unit.

    +
  • +
+ +

Metabase 0.48.0

+ +
    +
  • +

    The MBQL schema in metabase.mbql.schema now uses Malli instead of +Schema. If you were using this namespace in combination with Schema, you’ll +want to update your code to use Malli instead.

    +
  • +
  • +

    Another driver feature has been added: :table-privileges. This feature signals whether we can store +the table-level privileges for the database on database sync.

    +
  • +
  • +

    The multimethod metabase.driver/current-user-table-privileges has been added. This method is used to get +the set of privileges the database connection’s current user has. It needs to be implemented if the database +supports the :table-privileges feature.

    +
  • +
  • +

    The following functions in metabase.query-processor.store (qp.store) are now deprecated

    + +
      +
    • qp.store/database
    • +
    • qp.store/table
    • +
    • qp.store/field
    • +
    + +

    Update usages of the to the corresponding functions in metabase.lib.metadata (lib.metadata):

    + +
    (qp.store/database)       => (lib.metadata/database (qp.store/metadata-provider))
    +(qp.store/table table-id) => (lib.metadata/table (qp.store/metadata-provider) table-id)
    +(qp.store/field field-id) => (lib.metadata/field (qp.store/metadata-provider) field-id)
    +
    + +

    Note that the new methods return keys as kebab-case rather than snake_case.

    +
  • +
  • +

    Similarly, drivers should NOT access the application database directly (via toucan functions or otherwise); use +lib.metadata functions instead. This access may be blocked in a future release.

    +
  • +
  • +

    SQL drivers that implement metabase.driver.sql.query-processor/->honeysql for +metabase.models.table/Table/:model/Table should be updated to implement it for :metadata/table instead. As +with the changes above, the main difference is that the new metadata maps use kebab-case keys rather than +snake_case keys.

    +
  • +
  • +

    metabase.driver.sql.query-processor/cast-field-if-needed now expects a kebab-cased field as returned by +lib.metadata/field.

    +
  • +
  • +

    metabase.query-processor.store/fetch-and-store-database!, +metabase.query-processor.store/fetch-and-store-tables!, and +metabase.query-processor.store/fetch-and-store-fields! have been removed. Things are now fetched automatically as +needed and these calls are no longer necessary.

    +
  • +
  • +

    metabase.models.field/json-field? has been removed, use metabase.lib.field/json-field? instead. Note that the +new function takes a Field as returned by lib.metadata/field, i.e. a kebab-case map.

    +
  • +
  • +

    Tests should try to avoid using any of the with-temp helpers or application database objects; instead, use the +metadata functions above and and the helper metadata providers in metabase.lib, metabase.lib.test-util, and +metabase.query-processor.test-util for mocking them, such as mock-metadata-provider, +metabase-provider-with-cards-for-queries, remap-metadata-provider, and merged-mock-metadata-provider.

    +
  • +
  • +

    metabase.query-processor.util.add-alias-info/field-reference is now deprecated. If your driver implemented it, +implement metabase.query-processor.util.add-alias-info/field-reference-mlv2 instead. The only difference between +the two is that the latter is passed Field metadata with kebab-case keys while the former is passed legacy +metadata with snake_case keys.

    +
  • +
  • +

    metabase.driver/current-db-time, deprecated in 0.34, and related methods and helper functions, have been removed. +Implement metabase.driver/db-default-timezone instead.

    +
  • +
  • +

    metabase.driver.sql-jdbc.sync.interface/db-default-timezone, a helper for writing +metabase.driver/db-default-timezone implementations for JDBC-based drivers, has been deprecated, and will be +removed in 0.51.0 or later. You can easily implement metabase.driver/db-default-timezone directly, and use +metabase.driver.sql-jdbc.execute/do-with-connection-with-options to get a java.sql.Connection for a Database.

    +
  • +
  • +

    Added a new multimethod metabase.driver.sql.parameters.substitution/align-temporal-unit-with-param-type, which returns +a suitable temporal unit conversion keyword for field, param-type and the given driver. The resulting keyword +will be used to call the corresponding metabase.driver.sql.query-processor/date implementation to convert the field. +Returns nil if the conversion is not necessary for this field and param-type combination.

    +
  • +
  • +

    The multimethod metabase.driver.sql-jdbc.execute/inject-remark has been added. It allows JDBC-based drivers to +override the default behavior of how SQL query remarks are added to queries (prepending them as a comment).

    +
  • +
  • +

    The arity of multimethod metabase.driver.sql-jdbc.sync.interface/fallback-metadata-query has been updated from 3 to 4, +it now takes an additional db argument. The new function arguments are: [driver db-name-or-nil schema table].

    +
  • +
+ +

Metabase 0.47.0

+ +
    +
  • +

    A new driver feature has been added: :schemas. This feature signals whether the database organizes tables in +schemas (also known as namespaces) or not. Most databases have schemas so this feature is on by default. +An implementation of the multimethod metabase.driver/database-supports? for :schemas is required only if the +database doesn’t store tables in schemas.

    +
  • +
  • +

    Another driver feature has been added: :uploads. The :uploads feature signals whether the database supports +uploading CSV files to tables in the database. To support the uploads feature, implement the following new +multimethods: metabase.driver/create-table! (creates a table), metabase.driver/drop-table! (drops +a table), and metabase.driver/insert-into! (inserts values into a table).

    +
  • +
  • +

    The multimethod metabase.driver/syncable-schemas has been added. This method is used to list schemas to upload +CSVs to, and it should include all schemas that can be synced. Currently it only needs to be implemented +if the database has schema, and the database supports the :uploads feature.

    +
  • +
  • +

    The multimethod metabase.driver/supports? has been deprecated in favor of metabase.driver/database-supports?. +The existing default implementation of database-supports? currently calls supports?, but it will be removed in +0.50.0.

    +
  • +
  • +

    metabase.driver.sql-jdbc.execute/connection-with-timezone has been marked deprecated and is scheduled for removal +in Metabase 0.50.0. The new method metabase.driver.sql-jdbc.execute/do-with-connection-with-options replaces it. +Migration to the new method is straightforward. See PR #22166 for +more information. You should use metabase.driver.sql-jdbc.execute/do-with-connection-with-options instead of +clojure.java.jdbc/with-db-connection or clojure.java.jdbc/get-connection going forward.

    +
  • +
  • +

    The multimethods set-role!, set-role-statement, and default-database-role have been added. These methods are +used to enable connection impersonation, which is a new feature added in 0.47.0. Connection impersonation allows users +to be assigned to specific database roles which are set before any queries are executed, so that access to tables can +be restricted at the database level instead of (or in conjunction with) Metabase’s built-in permissions system.

    +
  • +
  • +

    The multimethod metabase.driver.sql-jdbc.sync.describe-table/get-table-pks is changed to return a vector instea +of a set.

    +
  • +
  • +

    The function metabase.query-processor.timezone/report-timezone-id-if-supported has been updated to take an additional +database argument for the arity which previously had one argument. This function might be used in the implementation +of a driver’s multimethods.

    +
  • +
  • +

    metabase.driver/prettify-native-form was added to enable driver developers use native form formatting +specific to their driver. For details see the PR #34991.

    +
  • +
+ +

Metabase 0.46.0

+ +
    +
  • +

    The process for building a driver has changed slightly in Metabase 0.46.0. Your build command should now look +something like this:

    + +
    # Example for building the driver with bash or similar
    +
    +# switch to the local checkout of the Metabase repo
    +cd /path/to/metabase/repo
    +
    +# get absolute path to the driver project directory
    +DRIVER_PATH=`readlink -f ~/sudoku-driver`
    +
    +# Build driver. See explanation in sample Sudoku driver README
    +clojure \
    +  -Sdeps "{:aliases {:sudoku {:extra-deps {com.metabase/sudoku-driver {:local/root \"$DRIVER_PATH\"}}}}}"  \
    +  -X:build:sudoku \
    +  build-drivers.build-driver/build-driver! \
    +  "{:driver :sudoku, :project-dir \"$DRIVER_PATH\", :target-dir \"$DRIVER_PATH/target\"}"
    +
    + +

    Take a look at our build instructions for the sample Sudoku +driver +for an explanation of the command.

    + +

    Note that while this command itself is quite a lot to type, you no longer need to specify a :build alias in your +driver’s deps.edn file.

    + +

    Please upvote https://ask.clojure.org/index.php/7843/allow-specifying-aliases-coordinates-that-point-projects , +which will allow us to simplify the driver build command in the future.

    +
  • +
  • +

    The multimethod metabase.driver/table-rows-sample has been added. This method is used in situations where Metabase +needs a limited sample from a table, like when fingerprinting. The default implementation defined in the +metabase.db.metadata-queries namespace runs an MBQL query using the regular query processor to produce the sample +rows. This is good enough in most cases, so this multimethod should not be implemented unless really +necessary. Currently, the only case when a special implementation is used is for BigQuery, which does not respect +limit clauses.

    +
  • +
  • +

    The multimethod metabase.driver.sql.query-processor/datetime-diff has been added. This method is used by +implementations of ->honeysql for the :datetime-diff clause. It is recommended to implement this if you want to +use the default SQL implementation of ->honeysql for the :datetime-diff, which includes validation of argument +types across all units.

    +
  • +
  • +

    The multimethod metabase.query-processor.util.add-alias-info/field-reference has been added. This method is used +to produce a reference to a field by the add-alias-info middleware. (Note that this middleware is optional, +currently it is only used by the SQL and MongoDB drivers.) The default implementation returns the name of the field +instance. It should be overridden if just the name is not a valid a valid reference. For example, MongoDB supports +nested documents and references to nested fields should contain the whole path. See the namespace +metabase.driver.mongo.query-processor for an alternative implementation.

    +
  • +
  • +

    The multimethod metabase.driver.sql-jdbc.sync.interface/syncable-schemas (aliased as +metabase.driver.sql-jdbc.sync/syncable-schemas), which was deprecated in 0.43.0, has been removed. Implement +metabase.driver.sql-jdbc.sync.interface/filtered-syncable-schemas instead. See 0.43.0 notes below for more +details.

    +
  • +
  • +

    The multimethod metabase.driver/format-custom-field-name, which was deprecated in 0.42.0, has been removed. +Implement metabase.driver/escape-alias instead. See 0.42.0 notes below for more information.

    +
  • +
  • +

    The multimethod metabase.driver.sql-jdbc.execute/read-column, which was deprecated in 0.35.0, has been removed. +Implement metabase.driver.sql-jdbc.execute/read-column-thunk instead. See 0.35.0 notes below for more information.

    +
  • +
+ +

Honey SQL 2

+ +

The following only applies to SQL drivers; you can ignore it for non-SQL drivers.

+ +

Prior to Metabase 0.46.0, SQL drivers used Honey SQL 1 as an intermediate target when compiling queries. In 0.46.0 we +have began the process of migrating to Honey SQL 2 as our new intermediate target.

+ +

We plan to continue to support use of Honey SQL 1 until Metabase 0.49.0. Please be sure to migrate your drivers before +then.

+ +

In Metabase 0.46.x, 0.47.x, and 0.48.x, you can specify which version of Honey SQL you driver should use by +implementing the metabase.driver.sql.query-processor/honey-sql-version multimethod:

+ +
(require '[metabase.driver.sql.query-processor :as sql.qp])
+
+;;; use Honey SQL 2 for :my-driver
+(defmethod sql.qp/honey-sql-version :my-driver
+  [_driver]
+  2)
+
+ +

This method must return either 1 or 2. Currently, the default implementation returns 1. Effectively this means +you currently have to opt-in to Honey SQL 2 compilation. It’s a good idea to do this sooner rather than later so your +driver is prepared for 0.49.0 well in advance.

+ +

In Metabase 0.47.x or 0.48.x we will likely change the default Honey SQL version to 2 to ensure everyone is aware of +the upcoming breaking changes in 0.49.0 and give them one or two release cycles to update their drivers to target +Honey SQL 2. You will still be able to opt-in to using Honey SQL 1 until 0.49.0 by implementing +sql.qp/honey-sql-version and returning 1.

+ +

What You Need to Change

+ +

Our Honey SQL utility namespace, metabase.util.honeysql-extensions, commonly aliased as hx, has been updated to +generate forms appropriate for either Honey SQL 1 or Honey SQL 2. This is done automatically based on your driver’s +honey-sql-version. metabase.driver.sql.query-processor itself also supports both targets in the same way.

+ +

The actual changes you will need to make to your driver code will probably be fairly small. The most important things +to note when porting your driver:

+ +
    +
  1. +

    Avoid use of things from Honey SQL 1 namespaces like honeysql.core or honeysql.format. If you must, use Honey +SQL honey.sql instead; you may not need either.

    +
  2. +
  3. +

    While you can continue to use metabase.util.honeysql-extensions in the short term, since it can target either +version of Honey SQL, we will probably remove this namespace at some point in the future. Update your code to use +metabase.util.honey-sql-2 instead. The namespaces implement an almost identical set of helper functions, so all +you should need to switch is which one you :require in your ns form.

    +
  4. +
  5. +

    honeysql.core/call no longer exists; instead of a form like (hsql/call :my_function 1 2), you simply return a +plain vector like [:my_function 1 2]. (hsql/raw "x") is now[:raw "x"]. New handlers can be registered with +Honey SQL 2 with honey.sql/register-fn!. There is no equivalent of the Honey SQL 1 honeysql.format./ToSql +protocol, so you should no longer define one-off types to implement custom SQL compilation rules. Use +honey.sql/register-fn! instead.

    +
  6. +
  7. +

    In Honey SQL 1 you were able to register functions to a more limited extent by implementing the multimethod +honeysql.format/fn-handler. Metabase registered the functions :extract, :distinct-count, and +:percentile-cont in this way. For Honey SQL 2, we’ve registered these functions as qualified keywords in the +metabase.util.honey-sql-2 namespace, to prevent confusion as to where they’re defined. Thus you’ll need to update +the keyword if you’re using these functions.

    + +
    ;;; Honey SQL 1
    +(hsql/call :distinct-count expr)
    +
    + +

    becomes

    + +
    ;;; Honey SQL 2
    +(require '[metabase.util.honey-sql-2 :as h2x])
    +
    +[::h2x/distinct-count expr]
    +
    +
  8. +
  9. +

    Because custom expressions are now just plain vectors like [:my_function 1], you may need to wrap expressions in +an additional vector if they appear inside :select, :from, or other places where a vector could be interpreted +as [expression alias]. e.g.

    + +
    ;; Honey SQL 1
    +(honeysql.core/format {:select [[:my_function 1]]})
    +;; => ["SELECT my_function AS 1"]
    +
    +;; Honey SQL 2
    +;;
    +;; WRONG
    +(honey.sql/format {:select [[:my_function 1]]})
    +;; => ["SELECT my_function AS ?" 1]
    +
    +;; CORRECT
    +(honey.sql/format {:select [[[:my_function 1]]]})
    +;; => ["SELECT MY_FUNCTION(?)" 1]
    +
    + +

    The SQL query processor does this automatically for forms it generates, so you only need to worry about this if +you’re overriding the way it generates :select or other top-level clauses.

    +
  10. +
  11. +

    Numbers are parameterized by default, e.g. {:select [1]} becomes SELECT ? rather than SELECT 1. You can use +:inline to force the SQL to be generated inline instead: {:select [[[:inline 1]]]} becomes SELECT 1. Numbers +generated by the SQL query processor code should automatically be inlined, but you may need to make sure any +numbers you generate are wrapped in :inline if they can end up as expressions inside a GROUP BY clause. Some +databases can recognize expressions as being the same thing only when they are not parameterized:

    + +
    -- This is okay
    +SELECT x + 1
    +FROM table
    +GROUP BY x + 1
    +
    +-- Bad: DB doesn't know whether the two x + ? expressions are the same thing
    +SELECT x + ?
    +FROM table
    +GROUP BY x + ?
    +
    +
  12. +
+ +

Exercise caution when :inlineing things – take care not to use it on untrusted strings or other avenues for SQL +injection. Only inlining things that are a number? is a safe bet.

+ +

Please read Differences between Honey SQL 1.x and +2.x for more information on the +differences between the library versions.

+ + + +

Note: these breaking changes will hopefully be fixed before 0.46.0 ships. This will be updated if they are.

+ +

The classes metabase.util.honeysql_extensions.Identifer and metabase.util.honeysql_extensions.TypedHoneySQLForm +have been moved to metabase.util.honey_sql_1.Identifer and metabase.util.honey_sql_1.TypedHoneySQLForm, +respectively. On the off chance that your driver directly referencing these class names, you may need to update things +to use the new class names.

+ +

Similarly, metabase.util.honeysql-extensions/->AtTimeZone has been removed; use +metabase.util.honeysql-extensions/at-time-zone instead.

+ +

Metabase 0.45.0

+ +
    +
  • metabase.driver.sql-jdbc.connection/details->connection-spec-for-testing-connection has been removed in Metabase +0.45.0, because it leaked SSH tunnels. See #24445. If you are +using this function, please update your code to use +metabase.driver.sql-jdbc.connection/with-connection-spec-for-testing-connection instead, which properly cleans up +after itself.
  • +
+ +

New methods

+ +
    +
  • +

    metabase.driver.sql-jdbc.sync.describe-table-fields has been added. Implement this method if you want to override +the default behavior for fetching field metadata (such as types) for a table.

    +
  • +
  • +

    metabase.driver.sql-jdbc.sync.describe-table/get-table-pks has been added. This methods is used to get a set of pks +given a table.

    +
  • +
  • +

    ->honeysql [<driver> :convert-timezone] has been added. Implement this method if you want your driver to support +the convertTimezone expression. This method takes 2 or 3 arguments and returns a timestamp without time zone column.

    +
  • +
+ +

Metabase 0.43.0

+ +
    +
  • +

    The :expressions map in an MBQL query now uses strings as keys rather than keywords (see +#14647). You only need to be concerned with this if you are +accessing or manipulating this map directly. Drivers deriving from :sql implementing ->honeysql for [<driver> :expression] may need to be updated. A utility function, metabase.mbql.util/expression-with-name, has been +available since at least Metabase 0.35.0 and handles both types of keys. It is highly recommended that you use this +function rather than accessing :expressions directly, as doing so can make your driver compatible with both 0.42.0 +and with 0.43.0 and newer.

    +
  • +
  • +

    There is now a describe-nested-field-columns method under sql-jdbc.sync namespace which returns an instance of +NestedFCMetadata. This is in order to allow JSON columns in Postgres and eventually other DB’s which are usually +ordinary RDBMS’s but then sometimes they have a denormalized column with JSON or some other semantics. Given a table +with denormalized columns which have nested field semantics (so, typed sub-fields which are still denormalized but +stable in type between rows), return value should be a NestedFCMetadata, a map of flattened key paths to the +detected sub-field. Field detection in syncing will then be enriched with those nested types. This is materially +different from the way we do it for mongo because every kind of JSON column is different, but it’s going to run +every sync so it can’t be too slow, even on enormous tables and enormous denormalized columns on those enormous tables.

    +
  • +
+ +

Metabase 0.42.0

+ +

Changes in Metabase 0.42.0 affect drivers that derive from :sql (including :sql-jdbc). +Non-SQL drivers likely will require no changes.

+ +

0.42.0 introduces several significant changes to the way the SQL query processor compiles and determines aliases for +MBQL :field clauses. For more background, see pull request +#19384.

+ +

If you were manipulating Field or Table aliases, we consolidated a lot of overlapping vars and methods, which means you may need to delete deprecated method implementations.

+ +

Significant changes

+ +
    +
  • +

    The metabase.driver.sql.query-processor/->honeysql method for Field instances, e.g.

    + +
    (defmethod sql.qp/->honeysql [:my-driver (class Field)]
    +  [driver field]
    +  ...)
    +
    + +

    is no longer invoked. All compilation is now handled by the MBQL :field clause method, e.g.

    + +
    (defmethod sql.qp/->honeysql [:my-driver :field]
    +  [driver field-clause]
    +  ...)
    +
    + +

    If you were doing something special here, you’ll need to move that special login into [<driver> :field] instead. +(You may no longer need this special logic, however – see below.)

    +
  • +
  • +

    :field, :expression, and :aggregation-options clauses now contain information about what aliases you should +use to refer to them on both the left-hand side and right-hand side of SQL AS or elsewhere in a query. See PR +#19610 for a detailed discussion about the new information, +hereafter referred to as the /#19610 information/.

    +
  • +
  • +

    If you have a custom implementation of ->honeysql for :field or (class Field): ->honeysql methods for :field should use or replace the +#19610 information rather than attempting to determine or +override it in some other fashion.

    +
  • +
+ +

New methods

+ +
    +
  • +

    metabase.driver/escape-alias (moved from metabase.driver.sql.query-processor/escape-alias, which was introduced +in 0.41.0) is now used to generate the #19610 information and +used consistently across the SQL QP code. If you need to transform generated Field aliases for any reason (such as +escaping disallowed characters), implement this method.

    +
  • +
  • +

    metabase.driver.sql-jdbc.sync.interface/filtered-syncable-schemas has been added, and will eventually replace +metabase.driver.sql-jdbc.sync.interface/syncable-schemas. It serves a similar purpose, except that it’s also +passed the inclusion and exclusion patterns (ex: auth*,data*) to further filter schemas that will be synced.

    +
  • +
+ +

Deprecated methods and vars

+ +

The following methods and vars are slated for removal in Metabase 0.45.0 unless otherwise noted.

+ +
    +
  • +

    metabase.driver/format-custom-field-name is now unused. Implement metabase.driver/escape-alias instead.

    +
  • +
  • +

    metabase.driver.sql.query-processor/escape-alias has been renamed to metabase.driver/escape-alias. Everything +else is the same.

    +
  • +
  • +

    metabase.driver.sql.query-processor/field-clause->alias no longer uses the optional parameter unique-name-fn. +Aliases are now made unique automatically, after escaping them; implement metabase.driver/escape-alias if you need +to do something special before they are made unique. (Unique aliases are also escaped a second time if you need to +do something /really/ special.)

    +
  • +
  • +

    metabase.driver.sql.query-processor/field->alias, which was deprecated in 0.41.0, is now unused in 0.42.0. +Implementing this method no longer has any effect. Implement metabase.driver/escape-alias instead if you need to +do something special; use the #19610 information if you need to escape the alias +for one reason or another. This method is still slated for removal in Metabase 0.44.0.

    +
  • +
  • +

    metabase.driver.sql.query-processor/*field-options* is now unused and is no longer bound automatically. If you need field options for some reason, see our SQL Server driver for an example on how to create it.

    +
  • +
  • +

    metabase.driver.sql.query-processor/*table-alias* is now unused and is no longer bound automatically. Use or +override :metabase.query-processor.util.add-alias-info/source-table from the #19610 +information instead.

    +
  • +
  • +

    metabase.driver.sql.query-processor/*source-query* is now unused and is no longer bound automatically. Use +metabase.driver.sql.query-processor/*inner-query* instead, which is always bound, even if we aren’t inside of a +source query.

    +
  • +
  • +

    metabase.driver.sql.query-processor/field->identifier is now unused. Implementing this method should no longer be +necessary under any circumstances. Override ->honeysql for [<driver> :field] and manipulate the #19610 +information if you need to do something special here.

    +
  • +
  • metabase.driver.sql.query-processor/prefix-field-alias is no longer used. Previously, it was made available to +give drivers a chance to escape automatically generated aliases for joined Fields. This is no longer necessary, +because metabase.driver/escape-alias is called on automatically generates aliases. Implement +metabase.driver/escape-alias if you need to do something special.
  • +
  • metabase.driver.sql-jdbc.sync.interface/syncable-schemas has been deprecated in favor of +metabase.driver.sql-jdbc.sync.interface/filtered-syncable-schemas (see above). The existing default implementation +of syncable-schemas currently calls filtered-syncable-schemas (with nil filters, i.e. the filtering operation +is actually a no-op), but it will eventually be removed.
  • +
+ +

Removed Methods and Vars

+ +
    +
  • metabase.mbql.schema/DatetimeFieldUnit, deprecated in 0.39.0, is now removed.
  • +
+ +

Older versions

+ +

Before 0.42.0, this information was tracked in our Wiki. You can find changes for versions before 0.42.0 in the +table below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VersionWiki page
0.41.0changes
0.40.0No changes.
0.39.0No changes.
0.38.0changes
0.37.0changes
0.36.0changes
0.35.0changes
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/drivers/basics.html b/_site/docs/doc-update-detection/developers-guide/drivers/basics.html new file mode 100644 index 000000000..0a823af9a --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/drivers/basics.html @@ -0,0 +1,3113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Database driver basics | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Database driver basics

+ +

A Metabase driver:

+ +
    +
  • Provides Metabase with basic information for the database such as the database’s capabilities, connection properties, and so on.
  • +
  • Provides Metabase with information about the schema of the database – the tables (or equivalent), the fields in those tables, the foreign key relationships (for databases that support foreign keys). +
      +
    • This functionality is used by the Metabase sync process and stored in the application database.
    • +
    • The stored information is used in the visual Query Builder and other places to show users what tables/columns/etc. are available
    • +
    +
  • +
  • Compiles our in-house query language, MBQL, into native queries. +
      +
    • MBQL queries are generated by the visual query builder.
    • +
    • The Metabase query processor* converts MBQL queries to native queries
    • +
    +
  • +
  • Executes native queries and returns results.
  • +
+ +

Write your driver as a module and package it as a plugin

+ +

Metabase drivers are organized into modules and packaged as plugins. Modules are the source code; plugins are the JARs built from that source code.

+ +

A Metabase plugin is a JAR file that contains the compiled class files and a Metabase plugin manifest that lists details about the driver. In most cases, plugins are lazily loaded, which means that Metabase won’t initialize the drivers until it connects to a database that would use the driver.

+ +

For Metabase to use your driver, all you need to do is put the driver JAR you built into the /plugin directory, which you’ll find in the same directory where you run your metabase.jar. Something like this:

+ +
/Users/cam/metabase/metabase.jar
+/Users/cam/metabase/plugins/my-plugin.jar
+
+ +

You can change the plugin directory by setting the environment variable MB_PLUGINS_DIR.

+ +

Example module directory

+ +

Let’s take a high-level look at the SQLite driver:

+ +
|-- deps.edn
+|-- resources
+|   `-- metabase-plugin.yaml
+|-- src
+|   `-- metabase
+|       `-- driver
+|           `-- sqlite.clj
+`-- test
+    `-- metabase
+        |-- driver
+        |   `-- sqlite_test.clj
+        `-- test
+            `-- data
+                `-- sqlite.clj
+
+ +

There are three files to call out here:

+ +

deps.edn

+ +

The deps.edn file specifies the driver’s dependencies.

+ +

resources/metabase-plugin.yaml

+ +

Your driver’s manifest includes details about your driver.

+ +

src/metabase/driver/sqlite.clj

+ +

This is the core file for your driver. We’ll talk more about it in Implementing multimethods.

+ +

Next Up

+ +

We’ll learn more about plugin manifests.

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/drivers/driver-tests.html b/_site/docs/doc-update-detection/developers-guide/drivers/driver-tests.html new file mode 100644 index 000000000..6fb52dd89 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/drivers/driver-tests.html @@ -0,0 +1,3270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Submitting a PR for a new driver | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Submitting a PR for a new driver

+ +

If you want to submit a PR to add a driver plugin to the Metabase repo (as opposed to keeping it in a separate repo), you’ll need to:

+ +
    +
  • Be able to run your database locally with Docker.
  • +
  • Make sure your driver passes Metabase’s core test suite.
  • +
+ +

Testing your driver

+ +

To test your driver, you’ll need to:

+ +
    +
  • Move your plugin into the modules/drivers directory in the Metabase repository.
  • +
  • Add test extensions to your driver.
  • +
  • Edit .github/workflows/drivers.yml to tell GitHub Actions how to set up a Docker image for your database and run tests against it.
  • +
+ +

Add test extensions to your driver

+ +

Test extensions do things like create new databases and load data for given database definitions. Metabase defines a huge suite of tests that automatically run against all drivers, including your new driver.

+ +

To run the test suite with your driver, you’ll need to write a series of method implementations for special test extension multimethods. Test extensions do things like create new databases and load data for database definitions.

+ +

These test extensions will tell Metabase how to create new databases and load them with test data, and provide information about what Metabae can expect from the created database. Test extensions are simply additional multimethods used only by tests. Like the core driver multimethods, they dispatch on the driver name as a keyword, e.g. :mysql.

+ +

File organization

+ +

Test extensions for a driver usually live in a namespace called metabase.test.data.<driver>. If your driver is for SQLite, your files should look something like:

+ +
metabase/modules/drivers/sqlite/deps.edn                           ; <- deps go in here
+metabase/modules/drivers/sqlite/resources/metabase-plugin.yaml     ; <- plugin manifest
+metabase/modules/drivers/sqilte/src/metabase/driver/sqlite.clj     ; <- main driver namespace
+
+ +

So you’ll create a new directory and file to house your text extension method implementations.

+ +
metabase/modules/drivers/sqlite/test/metabase/test/data/sqlite.clj   ; <- test extensions
+
+ +

Where are test extension methods defined?

+ +

Metabase test extensions live in the metabase.test.data.interface namespace. Like the core driver methods, :sql and :jdbc-sql implement some of the test extensions themselves, but define additional methods you must implement to use them; see the metabase.test.data.sql +and metabase.test.data.sql-jdbc namespaces.

+ +

You’ll need to require the following namespaces, aliased like so:

+ +
(require '[metabase.test.data.interface :as tx]) ; tx = test extensions
+(require '[metabase.test.data.sql :as sql.tx])   ; sql test extensions
+(require '[metabase.test.data.sql-jdbc :as sql-jdbc.tx])
+
+ +

Registering test extensions

+ +

Like the driver itself, you need to register the fact that your driver has test extensions, so Metabase knows it doesn’t need to try to load them a second time. (If they’re not loaded yet, Metabase will load them when needed by looking for a namespace named metabase.test.data.<driver>, which is why you need to follow that naming pattern.) The :sql and :sql-jdbc drivers have their own sets of test extensions, so depending on which parent you’re using for your driver, register test extensions with:

+ +
# Non-SQL drivers
+(tx/add-test-extensions! :mongo)
+
+# non-JDBC SQL
+(sql/add-test-extensions! :bigquery)
+
+# JDBC SQL
+(sql-jdbc.tx/add-test-extensions! :mysql)
+
+ +

You only need one call – there’s no need to do all three for a :sql-jdbc driver. This call should go at the beginning of your test extension namespace, like this:

+ +
(ns metabase.test.data.mysql
+  (:require [metabase.test.data.sql-jdbc :as sql-jdbc.tx]))
+
+(sql-jdbc.tx/register-test-extensions! :mysql)
+
+ +

Anatomy of a Metabase test

+ +

Let’s look at an real-life Metabase test so we can understand how it works and what exactly we need to do to power it:

+ +
;; expect-with-non-timeseries-dbs = run against all drivers listed in `DRIVERS` env var except timeseries ones like Druid
+(expect-with-non-timeseries-dbs
+  ;; expected results
+  [[ 5 "Brite Spot Family Restaurant" 20 34.0778 -118.261 2]
+   [ 7 "Don Day Korean Restaurant"    44 34.0689 -118.305 2]
+   [17 "Ruen Pair Thai Restaurant"    71 34.1021 -118.306 2]
+   [45 "Tu Lan Restaurant"             4 37.7821 -122.41  1]
+   [55 "Dal Rae Restaurant"           67 33.983  -118.096 4]]
+  ;; actual results
+  (-> (data/run-mbql-query venues
+        {:filter   [:ends-with $name "Restaurant"]
+         :order-by [[:asc $id]]})
+      rows formatted-venues-rows))
+
+ +

Let’s say we launch tests with

+ +
DRIVERS=mysql clojure -X:dev:drivers:drivers-dev:test`.
+
+ +
    +
  1. Metabase will check and see if test extensions for :mysql are loaded. If not, it will (require 'metabase.test.data.mysql).
  2. +
  3. Metabase will check to see if the default test-data database has been created for MySQL, loaded with data, and synced. If not, it will call the test extension method tx/load-data! to create the test-data database and load data into it. After loading the data, Metabase syncs the test database. (This is discussed in more detail below.)
  4. +
  5. Metabase runs an MBQL query against the venues table of the MySQL test-data database. The run-mbql-query macro is a helper for writing tests that looks up Field IDs based on names for symbols that have $ in from of them. Don’t worry too much about that right now; just know the actual query that is ran will look something like: +
    {:database 100 ; ID of MySQL test-data database
    + :type :query
    + :query {:source-table 20 ; Table 20 = MySQL test-data.venues
    +         :filter [:ends-with [:field-id 555] "Restaurant"] ; Field 555 = MySQL test-data.venues.name
    +         :order-by [[:asc [:field-id 556]]]}} ; Field 556 = MySQL test-data.venues.id
    +
    +
  6. +
  7. The results are ran through helper functions rows and formatted-venues-rows which return only the parts of the query results we care about
  8. +
  9. Those results are compared against the expected results.
  10. +
+ +

That’s about as much as you’d need to know about the internals of how Metabase tests work; now that we’ve covered that, let’s take a look at how we can empower Metabase to do what it needs to do.

+ +

Loading Data

+ +

In order to ensure consistent behavior across different drivers, the Metabase test suite creates new databases and load datas into them from a set of shared Database Definitions. That means whether we’re running a test against MySQL, Postgres, SQL Server, or MongoDB, a single test can check that we get the exact same results for every driver!

+ +

Most of these database definitions live in EDN files; the majority of tests run against a test database named “test data”, whose definition can be found here. Take a look at that file – it’s just a simple set of tables names, column names and types, and then a few thousand rows of data to load into those tables.

+ +

Like test extension method definitions, schemas for DatabaseDefinition live in metabase.test.data.interface – you can take a look and see exactly what a database definition is supposed to look like.

+ +

Your biggest job as a writer of test definitions is to write the methods needed to take a database definition, create a new database with the appropriate tables and columns, and load data into it. For non-SQL drivers, you’ll need to implement tx/load-data!; :sql and :sql-jdbc have a shared implementation used by child drivers, but define their own set of test extension methods. For example, :sql (and :sql-jdbc) will handle the DDL statements for creating tables, but need to know what type it should use for the primary key, so you’ll need to implement sql.tx/pk-sql-type:

+ +
(defmethod sql.tx/pk-sql-type :mysql [_] "INTEGER NOT NULL AUTO_INCREMENT")
+
+ +

I’d like to document every single test extension method in detail here, but until I find the time to do that, the methods are all documented in the codebase itself; take a look at the appropriate test extension namespaces and see which methods you’ll need to implement. You can also refer to the test extensions written for other similar drivers to get a picture of what exactly it is you need to be doing.

+ +

Connection Details

+ +

Of course, Metabase also needs to know how it can connect to your newly created database. Specifically, it needs to know what it should save as part of the connection :details map when it saves the newly created database as a Database object. All drivers with test extensions need to implement tx/dbdef->connection-details to return an appropriate set of :details for a given database definition. For example:

+ +
(defmethod tx/dbdef->connection-details :mysql [_ context {:keys [database-name]}]
+  (merge
+   {:host     (tx/db-test-env-var :mysql :host "localhost")
+    :port     (tx/db-test-env-var :mysql :port 3306)
+    :user     (tx/db-test-env-var :mysql :user "root")
+    ;; :timezone :America/Los_Angeles
+    :serverTimezone "UTC"}
+   (when-let [password (tx/db-test-env-var :mysql :password)]
+     {:password password})
+   (when (= context :db)
+     {:db database-name})))
+
+ +

Let’s take a look at what’s going on here.

+ +

Connection context

+ +

tx/dbdef->connection-details is called in two different contexts:

+ +
    +
  • When creating a database,
  • +
  • And when loading data into one and syncing.
  • +
+ +

Most databases won’t let you connect to a database that hasn’t been created yet, meaning something like a CREATE DATABASE "test-data"; statement would have to be ran without specifying test-data as part of the connection. Thus, the context parameter. context is either :server, meaning “give me details for connecting to the DBMS server, but not to a specific database”, or :db, meaning “give me details for connecting to a specific database”. In MySQL’s case, it adds the :db connection property whenever context is :db.

+ +

Getting connection properties from env vars

+ +

You’ll almost certainly be running your database in a local Docker container. Rather than hardcode the connection details (the username, host, port…) for the Docker container, we’d like to be flexible, and let people specify those in environment variables, in case they’re running against a different container or are just running the database outside of a container, or on another computer entirely. You can use tx/db-test-env-var to get details from environment variables. For example,

+ +
(tx/db-test-env-var :mysql :user "root")
+
+ +

Tells Metabase to look for the environment variable MB_MYSQL_TEST_USER; if not found, default to "root". The name of the environment variable follows the pattern MB_<driver>_TEST_<property>, as passed into the function as first and second args, respectively. You don’t need to specify a default value for tx/db-test-env-var; perhaps user is an optional parameter; and if MB_MYSQL_TEST_USER isn’t specified, you don’t need to specify it in the connection details.

+ +

But what about properties you want to require, but do not have sane defaults? In those cases, you can use tx/db-test-env-var-or-throw. It the corresponding enviornment variable isn’t set, these will throw an Exception, ultimately causing tests to fail.

+ +
;; If MB_SQLSERVER_TEST_USER is unset, the test suite will quit with a message saying something like
+;; "MB_SQLSERVER_TEST_USER is required to run tests against :sqlserver"
+(tx/db-test-env-var-or-throw :sqlserver :user)
+
+ +

Note that tx/dbdef->connection-details won’t get called in the first place for drivers you aren’t running tests against (i.e., drivers not listed in the DRIVERS env var), so you wouldn’t see that SQL Server error message when running tests against Mongo, for example.

+ +

Besides tx/db-test-env-var, metabase.test.data.interface has several other helpful utility functions. Take a good look at that namespace as well as metabase.test.data.sql if your database uses SQL and metabase.test.data.sql-jdbc if your database uses a JDBC driver.

+ +

Other Test Extensions

+ +

There’s a few other things Metabase needs to know when comparing test results. For example, different databases name tables and columns in different ways; methods exist to let Metabase know it should expect something like the venues table in the test-data Database Definition to come back as VENUES for a database that uppercases everything. (We consider such minor variations in naming to still mean the same thing.) Take a look at tx/format-name and other methods like that and see which ones you need to implement.

+ +

What about DBMSes that don’t let you create new databases programatically?

+ +

This is actually a common problem, and luckily we have figured out how to work around it. The solution is usually something like using different schemas in place of different databases, or prefixing table names with the database name, and creating everything in the same database. For SQL-based databases, you can implement sql.tx/qualified-name-components to have tests use a different identifier instead of what they would normally use, for example "shared_db"."test-data_venues".id instead of "test-data".venues.id. The SQL Server and Oracle test extensions are good examples of such black magic in action.

+ +

Setting up CI

+ +

Once you have all the tests passing, you’ll need to set up GitHub Actions to run those tests against your driver. You’ll need to add a new job to .github/workflows/drivers.yml to run tests against your database.

+ +

Here is an example configuration for PostgreSQL.

+ +
be-tests-postgres-latest-ee:
+  needs: files-changed
+  if: github.event.pull_request.draft == false && needs.files-changed.outputs.backend_all == 'true'
+  runs-on: ubuntu-22.04
+  timeout-minutes: 60
+  env:
+    CI: "true"
+    DRIVERS: postgres
+    MB_DB_TYPE: postgres
+    MB_DB_PORT: 5432
+    MB_DB_HOST: localhost
+    MB_DB_DBNAME: circle_test
+    MB_DB_USER: circle_test
+    MB_POSTGRESQL_TEST_USER: circle_test
+    MB_POSTGRES_SSL_TEST_SSL: true
+    MB_POSTGRES_SSL_TEST_SSL_MODE: verify-full
+    MB_POSTGRES_SSL_TEST_SSL_ROOT_CERT_PATH: "test-resources/certificates/us-east-2-bundle.pem"
+  services:
+    postgres:
+      image: circleci/postgres:latest
+      ports:
+        - "5432:5432"
+      env:
+        POSTGRES_USER: circle_test
+        POSTGRES_DB: circle_test
+        POSTGRES_HOST_AUTH_METHOD: trust
+  steps:
+    - uses: actions/checkout@v4
+    - name: Test Postgres driver (latest)
+      uses: ./.github/actions/test-driver
+      with:
+        junit-name: "be-tests-postgres-latest-ee"
+
+ +

For more on what it is you’re doing here and how all this works, see Workflow syntax for GitHub Actions.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/drivers/multimethods.html b/_site/docs/doc-update-detection/developers-guide/drivers/multimethods.html new file mode 100644 index 000000000..2ab9be668 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/drivers/multimethods.html @@ -0,0 +1,3175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Implementing multimethods for your driver | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Implementing multimethods for your driver

+ +

Implementing multimethods lets you take advantage of Metabase’s existing driver code by extending those methods to work for your particular database.

+ +

Let’s first focus on the main driver file for our Fox Pro ‘98 src/metabase/driver/foxpro98.clj. Take a look at this sample code:

+ +
;; Define a namespace for the driver
+(ns com.mycompany.metabase.driver.foxpro98
+  (:require [metabase.driver :as driver]))
+
+;; Can you include a different method here as an example?
+(defmethod driver/display-name :foxpro98 [_]
+  "Visual FoxPro '98")
+
+ +

Let’s walk through each code block.

+ +

Driver namespaces

+ +
;; Define a namespace for the driver
+(ns com.mycompany.metabase.driver.foxpro98
+  (:require [metabase.driver :as driver]))
+
+ +

Each Metabase driver lives in its own namespace

+ +

In this case, the namespace iscom.mycompany.metabase.driver.foxpro98. +All core Metabase drivers live in metabase.driver.<name-goes-here> namespaces. It’s probably best to use names that follow the Java package naming conventions.

+ +

Many drivers are further broken out into additional namespaces

+ +

Especially larger drivers. Commonly, a driver will have a query-processor namespace (e.g., com.mycompany.metabase.driver.foxpro98.query-processor) that contains the logic for converting MBQL queries (queries built using Metabase’s graphical query builder) into native queries (like SQL). The query processor is often the most complicated part of a driver, so keeping that logic separate can help make things easier to work with. Some drivers also have a separate sync namespace that has implementations for methods used by Metabase’s database synchronization.

+ +

Driver initialization

+ +

All drivers can include additional code to be executed once (and only once) using metabase.driver/initialize! when Metabase initializes the driver, that is, before the driver establishes a connection to a database for the first time. (In fact, Metabase uses metabase.driver/initialize! to lazy-load the driver.) There are only a few cases where you should use metabase.driver/initialize, such as allocating resources or setting certain system properties.

+ +

metabase.driver multimethods

+ +

The metabase.driver namespace defines a series of multimethods, and drivers provide implementations for them, as in our example:

+ +
(defmethod driver/display-name :foxpro98 [_]
+  "Visual FoxPro '98")
+
+ +

The four main features of a Metabase driver described above are all implemented by multimethods. These methods dispatch on the driver’s keyword, :foxpro98 in our case. In fact, that’s all a Metabase driver is – a keyword! There are no classes or objects to be seen – just a single keyword.

+ +

You can browse the metabase.driver namespace for a complete list of multimethods that you could implement. Read the docstring for each method and decide whether you need to implement it. Most methods are optional.

+ +

Listing the available driver multimethods

+ +

To quickly look up a list of all driver multimethods, you can run the command

+ +
clojure -M:run driver-methods
+
+ +

which will print a list of all driver namespaces and multimethods. This includes many things like sql and sql-jdbc multimethods, as well as test extension multimethods.

+ +

If you want to see the docstrings for the methods as well, run:

+ +
clojure -M:run driver-methods docs
+
+ +

Parent drivers

+ +

Many drivers share implementation details, and writing complete implementations for sync methods and the like would involve a lot of duplicate code. Thus many high-level features are partially or fully implemented in shared “parent” drivers, such as the most common parent, :sql-jdbc. A “parent” driver is analogous to a superclass in object-oriented programming.

+ +

You can define a driver parent by listing the parent in the plugin manifest.

+ +

Parents like :sql-jdbc are intended as a common abstract “base class” for drivers that can share much of their implementation; in the case of :sql-jdbc, it’s intended for SQL-based drivers that use a JDBC driver under the hood.:sql-jdbc and other parents provide implementations for many of the methods needed to power the four main features of a Metabase driver. In fact, :sql-jdbc provides implementations of things like driver/execute-prepared-statement!, so a driver using it as a parent does not need to provide one itself. However, various parent drivers define their own multimethods to implement.

+ +

Notable parent drivers

+ +

These parents are kind of a big deal.

+ +
    +
  • :sql-jdbc can be used as the parent for SQL-based databases with a JDBC driver. +
      +
    • :sql-jdbc implements most of the four main features, but instead you must implement sql-jdbc multimethods found in metabase.driver.sql-jdbc.* namespaces, as well as some methods in metabase.driver.sql.* namespaces.
    • +
    +
  • +
  • :sql is itself the parent of :sql-jdbc; it can be used for SQL-based databases that do not have a JDBC driver, such as BigQuery. +
      +
    • :sql implements a significant chunk of driver functionality, but you must implement some methods found in metabase.driver.sql.* namespaces to use it.
    • +
    +
  • +
  • Some drivers use other “concrete” drivers as their parent – for example, :redshift uses :postgres as a parent, only supplying method implementations to override postgres ones where needed.
  • +
+ +

Calling parent driver implementations

+ +

You can get a parent driver’s implementation for a method by using get-method:

+ +
(defmethod driver/mbql->native :bigquery [driver query]
+  ((get-method driver/mbql-native :sql) driver query))
+
+ +

This is the equivalent of calling super.someMethod() in object-oriented programming.

+ +

You must pass the driver argument to the parent implementation as-is so any methods called by that method used the correct implementation. Here’s two ways of calling parents that you should avoid:

+ +
(defmethod driver/mbql->native :bigquery [_ query]
+  ;; BAD! If :sql's implementation of mbql->native calls any other methods, it won't use the :bigquery implementation
+  ((get-method driver/mbql->native :sql) :sql query))
+
+ +

also avoid:

+ +
(defmethod driver/mbql->native :bigquery [_ query]
+  ;; BAD! If someone else creates a driver using :bigquery as a parent, any methods called by :sql's implementation
+  ;; of mbql->native will use :bigquery method implementations instead of custom ones for that driver
+  ((get-method driver/mbql->native :sql) :bigquery query))
+
+ +

Multiple parents

+ +

Astute readers may have noticed that BigQuery is mentioned as having both :sql and :google as a parent. This multiple inheritance is allowed and helpful! You can define a driver with multiple parents as follows:

+ +
(driver/register! :bigquery, :parent #{:sql :google})
+
+ +

In some cases, both parents may provide an implementation for a method; to fix this ambiguity, simply provide an implementation for your driver and pass them to the preferred parent driver’s implementation as described above.

+ +

For drivers shipped as a plugin, you’ll register methods in the plugin manifest.

+ +

Working with the driver from the REPL and in CIDER

+ +

Having to install metabase-core locally and build driver uberjars would be obnoxious, especially if you had to repeat it to test every change. Luckily, you can run commands as if everything was part of one giant project:

+ +

To start a REPL.

+ +
clojure -A:dev:drivers:drivers-dev
+
+ +

You’ll need to rebuild the driver and install it in your ./plugins directory, and restart Metabase when you make changes.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/drivers/plugins.html b/_site/docs/doc-update-detection/developers-guide/drivers/plugins.html new file mode 100644 index 000000000..c6b7d9555 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/drivers/plugins.html @@ -0,0 +1,3257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Plugin manifests | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Plugin manifests

+ +

Metabase plugin JARs contain a plugin manifest – a top-level file named metabase-plugin.yaml. When Metabase launches, it iterates over every JAR in the plugins directory, and looks for the manifest in each. This manifest tells Metabase what the plugin provides and how to initialize it.

+ +

Example manifest

+ +
info:
+  name: Metabase SQLite Driver
+  version: 1.0.0-SNAPSHOT-3.25.2
+  description: Allows Metabase to connect to SQLite databases.
+contact-info:
+  name: Toucan McBird
+  address: toucan.mcbird@example.com
+driver:
+  name: sqlite
+  display-name: SQLite
+  lazy-load: true
+  parent: sql-jdbc
+  connection-properties:
+    - name: db
+      display-name: Filename
+      placeholder: /home/camsaul/toucan_sightings.sqlite
+      required: true
+init:
+  - step: load-namespace
+    namespace: metabase.driver.sqlite
+  - step: register-jdbc-driver
+    class: org.sqlite.JDBC
+
+ +

The driver section tells Metabase that the plugin defines a driver named :sqlite that has :sql-jdbc as a parent. Metabase’s plugin system uses these details to call driver/register!. The plugin also lists the display name and connection properties for the driver, which Metabase’s plugin system uses to creates implementations for driver/display-name and driver/connection-properties.

+ +

Lazy loading

+ +

The driver in the example above is listed as lazy-load: true, which means that, while the method implementation mentioned above are created when Metabase launches, Metabase won’t initialize the driver until the first time someone attempts to connect to a database that uses that driver.

+ +

You can (but shouldn’t) set a driver to lazy-load: false, as this will make Metabase take longer to launch and eat up more memory.

+ +

Plugin initialization

+ +

Metabase will initialize plugins automatically as needed. Initialization goes something like this: Metabase adds the driver to the classpath, then it performs each init section of the plugin manifest, in order. In the example manifest above, there are two steps, a load-namespace step, and a register-jdbc-driver step:

+ +
init:
+  - step: load-namespace
+    namespace: metabase.driver.sqlite
+  - step: register-jdbc-driver
+    class: org.sqlite.JDBC
+
+ +

Loading namespaces

+ +

You’ll need to add one or more load-namespace steps to your driver manifest to tell Metabase which namespaces contain your driver method implementations. In the example above, the namespace is metabase.driver.sqlite. load-namespace calls require the normal Clojure way, meaning it will load other namespaces listed in the :require section of its namespace declaration as needed. If your driver’s method implementations are split across multiple namespaces, make sure they’ll get loaded as well – you can either have the main namespace handle this (e.g., by including them in the :require form in the namespace declaration) or by adding additional load-namespace steps.

+ +

For some background on namespaces, see Clojure namespaces.

+ +

Registering JDBC Drivers

+ +

Drivers that use a JDBC driver under the hood will need to add a register-jdbc-driver step as well.

+ +

The if-you’re-interested reason is that Java’s JDBC DriverManager won’t use JDBC drivers loaded with something other than the system ClassLoader, which effectively only means Drivermanager will only use JDBC driver classes that are packaged as part of the core Metabase uberjar. Since the system classloader doesn’t allow you to load the classpath at runtime, Metabase uses a custom ClassLoader to initialize plugins. To work around this limitation, Metabase ships with a JDBC proxy driver class that can wrap other JDBC drivers. When Metabase calls register-jdbc-driver, Metabase actually registers a new instance of the proxy class that forwards method calls to the actual JDBC driver. DriverManager is perfectly fine with this.

+ +

Building the driver

+ +

To build a driver as a plugin JAR, check out the Build-driver scripts README.

+ +

Place the JAR you built in your Metabase’s /plugins directory, and you’re off to the races.

+ +

The Metabase plugin manifest reference

+ +

Here’s an example plugin manifest with comments to get you started on writing your own.

+ +
# Basic user-facing information about the driver goes under the info: key
+info:
+
+  # Make sure to give your plugin a name. In the future, we can show
+  # this to the user in a 'plugin management' admin page.
+  name: Metabase SQLite Driver
+
+  # For the sake of consistency with the core Metabase project you
+  # should use semantic versioning. It's not a bad idea to include the
+  # version of its major dependency (e.g., a JDBC driver) when
+  # applicable as part of the 'patch' part of the version, so we can
+  # update dependencies and have that reflected in the version number
+  #
+  # For now core Metabase modules should have a version
+  # 1.0.0-SNAPSHOT-x until version 1.0 ships and the API for plugins
+  # is locked in
+  version: 1.0.0-SNAPSHOT-3.25.2
+
+  # Describe what your plugin does. Not used currently, but in the
+  # future we may use this description in a plugins admin page.
+  description: Allows Metabase to connect to SQLite databases.
+
+# You can list any dependencies needed by the plugin by specifying a
+# list of dependencies. If all dependencies are not met, the plugin
+# will not be initialized.
+#
+# A dependency may be either a 'class' or (in the future) a 'plugin' dependency
+dependencies:
+
+  # A 'class' dependency checks whether a given class is available on
+  # the classpath. It doesn't initialize the class; Metabase defers initialization
+  # until it needs to use the driver
+  # Don't use this for classes that ship as part of the plugin itself;
+  # only use it for external dependencies.
+  - class: oracle.jdbc.OracleDriver
+
+    # You may optionally add a message that will be displayed for
+    # information purposes in the logs, and possibly in a plugin
+    # management page as well in the future
+    message: >
+      Metabase requires the Oracle JDBC driver to connect to JDBC databases. See
+      https://metabase.com/docs/latest/administration-guide/databases/oracle.html
+      for more details
+
+  # A 'plugin' dependency checks whether a given plugin is available.
+  # The value for 'plugin' is whatever that plugin has as its 'name:' -- make
+  # sure you match it exactly!
+  #
+  # If the dependency is not available when this module is first loaded, the module
+  # will be tried again later after more modules are loaded. This means things will
+  # still work the way we expect even if, say, we initially attempt to load the
+  # BigQuery driver *before* loading its dependency, the shared Google driver. Once
+  # the shared Google driver is loaded, Metabase will detect that BigQuery's
+  # dependencies are now satisfied and initialize the plugin.
+  #
+  # In the future, we'll like add version restrictions as well, but for now we only match
+  # by name.
+  - plugin: Metabase SQLHeavy Driver
+
+# If a plugin adds a driver it should define a driver: section.
+#
+# To define multiple drivers, you can pass a list of maps instead. Note
+# that multiple drivers currently still must share the same dependencies
+# set and initialization steps. Thus registering multiple drivers is most
+# useful for slight variations on the same driver or including an abstract
+# parent driver. Note that init steps will get ran once for each driver
+# that gets loaded. This can result in duplicate driver instances registered
+# with the DriverManager, which is certainly not ideal but does not actually
+# hurt anything.
+#
+# In the near future I might move init steps into driver itself (or
+# at least allow them there)
+driver:
+
+  # Name of the driver; corresponds to the keyword (e.g. :sqlite) used
+  # in the codebase
+  name: sqlite
+
+  # Nice display name shown to admins when connecting a database
+  display-name: SQLite
+
+  # Whether loading this driver can be deferred until the first
+  # attempt to connect to a database of this type. Default: true. Only
+  # set this to false if absolutely neccesary.
+  lazy-load: true
+
+  # Parent driver, if any.
+  parent: sql-jdbc
+
+  # You may alternatively specify a list of parents for drivers with
+  # more than one:
+  parent:
+    - google
+    - sql
+
+  # Whether this driver is abstract. Default: false
+  abstract: false
+
+  # List of connection properties to ask users to set to connect to
+  # this driver.
+  connection-properties:
+    # Connection properties can be one of the defaults found in
+    # metabase.driver.common, listed by name:
+    - dbname
+    - host
+
+    # Or a full map for a custom option. Complete schema for custom
+    # options can be found in metabase.driver. NOTE: these are not
+    # currently translated for i18n; I'm working on a way to translate
+    # these. Prefer using one of the defaults from
+    # metabase.driver.common if possible.
+    - name: db
+      display-name: Filename
+      placeholder: /home/camsaul/toucan_sightings.sqlite
+      required: true
+
+    # Finally, you can use merge: to merge multiple maps. This is
+    # useful to override specific properties in one of the defaults.
+    - merge:
+      - port
+      - placeholder: 1433
+
+# Steps to take to initialize the plugin. For lazy-load drivers, this
+# is delayed until the driver is initialized the first time we connect
+# to a database with it
+init:
+
+  # load-namespace tells Metabase to require a namespace from the JAR,
+  # you can do whatever Clojurey things you need to do inside that
+  # namespace
+  - step: load-namespace
+    namespace: metabase.driver.sqlite
+
+  # register-jdbc-driver tells Metabase to register a JDBC driver that
+  # will be used by this driver. (It actually registers a proxy
+  # driver, because DriverManager won't allow drivers that are loaded
+  # by different classloaders than it was loaded by (i.e., the system
+  # classloader); don't worry to much about this, but know for
+  # JDBC-based drivers you need to include your dependency here)
+  - step: register-jdbc-driver
+    class: org.sqlite.JDBC
+
+ +

Next up

+ +

Implementing multimethods for your driver.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/drivers/start.html b/_site/docs/doc-update-detection/developers-guide/drivers/start.html new file mode 100644 index 000000000..e004a374a --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/drivers/start.html @@ -0,0 +1,3081 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Guide to writing a Metabase driver | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Guide to writing a Metabase driver

+ +

So here’s the scenario: you love Metabase. It’s changed your life. But you have some data in a Visual Fox Pro ‘98 database and you need to make charts with it, and it might be a while before the core Metabase team writes a driver for Visual Fox Pro ‘98. No problem! Writing a driver can be fun.

+ +

Does a driver for your data source already exist?

+ +

Before you start building a driver from scratch, see if one already exists that you could contribute to:

+ + + +

Setting up

+ +

Before you start working on a driver, you’ll need to set up your development environment.

+ +

Having an in-depth understanding of Clojure is less important when writing JDBC-based drivers because their implementation is simpler – much of the work is already done for you – but it would still be helpful to understand what things like multimethods are. See Working with Clojure.

+ +

Writing a driver

+ +

Try to avoid skipping right to whichever page you think will give you the code you’ll need to copy-pasta. While Metabase drivers are often fairly small (some as little as fifty lines of code), you should put some careful thought into deciding what goes into those fifty lines. You’ll have an easier time writing the driver, and end up with a better one.

+ +
    +
  1. Driver basics
  2. +
  3. Plugin manifests
  4. +
  5. Implementing multimethods for your driver
  6. +
  7. Submitting a PR for your driver
  8. +
+ +

Example drivers

+ + + +

Driver development announcements

+ +

Occasionally, we may make changes to Metabase that impact database drivers. We’ll try to give everyone as much of a heads up as possible. For notifications regarding potential driver changes, subscribe to the Metabase Community Authors mailing list.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/e2e-tests.html b/_site/docs/doc-update-detection/developers-guide/e2e-tests.html new file mode 100644 index 000000000..5f803a6e3 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/e2e-tests.html @@ -0,0 +1,3358 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +End-to-end tests with Cypress | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

End-to-end tests with Cypress

+ +

Metabase uses Cypress for “end-to-end testing”, that is, tests that are executed against the application as a whole, including the frontend, backend, and application database. These tests are essentially scripts written in JavaScript that run in the web browser: visit different URLs, click various UI elements, type text, and assert that things happen as expected (for example, an element appearing on screen, or a network request occuring).

+ +

Getting Started

+ +

Metabase’s Cypress tests are located in the e2e/test/scenarios source tree, in a structure that roughly mirrors Metabase’s URL structure. For example, tests for the admin “datamodel” pages are located in e2e/test/scenarios/admin/datamodel.

+ +

Our custom Cypress runner builds its own backend and creates a temporary H2 app db. Both are destroyed when this process is killed. The reserved default port is 4000 on the local host. There is nothing stopping you from running your local Metabase instance on localhost:3000 at the same time. This might even be helpful for debugging purposes.

+ +

Standard Development Flow

+ +
    +
  1. +

    Continuously build the frontend

    + +

    a. If you need only the frontend, run yarn build-hot

    + +

    b. If you want to run a local Metabase instance alongside Cypress, the easiest way to achieve this is by using yarn dev or yarn dev-ee (both rely on frontend hot reloading under the hood)

    +
  2. +
  3. +

    In a separate terminal session (without killing the previous one) run yarn test-cypress. This will open a Cypress GUI that will let you choose which tests to run. Alternatively, take a look at run_cypress_local.js and e2e/test/scenarios/docker-compose.yml for all possible options.

    +
  4. +
+ +

Running Options

+ +

To run all Cypress tests headlessly in the terminal:

+ +
OPEN_UI=false yarn run test-cypress
+
+ +

You can quickly test a single file only by using the official --spec flag. +This flag can be used to run all specs within a folder, or to run multiple assorted specs. Consult the official documentation for instructions.

+ +
OPEN_UI=false yarn test-cypress --spec e2e/test/scenarios/question/new.cy.spec.js
+
+ +

You can specify a browser to execute Cypress tests in using the --browser flag. For more details, please consult the official documentation.

+ +

Specifying a browser makes most sense when running Cypress in a run mode. On the other hand, Cypress open mode (GUI) allows one to easily switch between all available browsers on the system. However, some people prefer to specify a browser even in this scenario. If you do this, keep in mind that you are merely preselecting an initial browser for Cypress but you still have the option to choose a different one.

+ +

Anatomy of the Test

+ +

Cypress test files are structured like Mocha tests, where describe blocks are used to group related tests, and it blocks are the tests themselves.

+ +
describe("homepage", () => {
+  it("should load the homepage and...", () => {
+    cy.visit("/metabase/url");
+    // ...
+  });
+});
+
+ +

We strongly prefer using selectors like cy.findByText() and cy.findByLabelText() from @testing-library/cypress since they encourage writing tests that don’t depend on implementation details like CSS class names.

+ +

Try to avoid repeatedly testing pieces of the application incidentally. For example, if you want to test something about the query builder, jump straight there using a helper like openOrdersTable() rather than starting from the home page, clicking “New”, then “Question”, etc.

+ +

Cypress Documentation

+ +
    +
  • Introduction: https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html
  • +
  • Commands: https://docs.cypress.io/api/api/table-of-contents.html
  • +
  • Assertions: https://docs.cypress.io/guides/references/assertions.html
  • +
+ +

Tips/Gotchas

+ +

contains vs find vs get

+ +

Cypress has a set of similar commands for selecting elements. Here are some tips for using them:

+ +
    +
  • contains is (by default) case-sensitive to the text in the DOM. If it’s not matching text you’d expect, check that CSS hasn’t updated the case. You can explicitly tell it to ignore the case with the following option { matchCase: false }. +
      +
    • contains matches substrings. Given two strings “filter by” and “Add a filter”, cy.contains(“filter”); will match both. To avoid these issues, you can either pass a regexp that pins the start/end of the string or scope a string to a specific selector: cy.contains(selector, content);.
    • +
    +
  • +
  • find will let you search within your previous selection.
  • +
  • get will search the entire page even if chained, unless you explicitly tweak the withinSubject option.
  • +
+ +

How to access Sample Database tables and field IDs?

+ +

The Sample Database that we use in E2E tests can change at any time, and with it the references to its tables and fields. Never ever use hard coded numeric references to those IDs. We provide a helpful mechanism to achieve this that is guaranteed to produce correct results. Every time you spin Cypress up, it fetches the information about the Sample Database, extracts table and field IDs and writes that to the e2e/support/cypress_sample_database JSON that we then re-export and make available to all tests.

+ +
// Don't
+const query = {
+  "source-table": 1,
+  aggregation: [["count"]],
+  breakout: [["field", 7, null]],
+};
+
+// Do this instead
+import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
+const { PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE;
+
+const query = {
+  "source-table": PRODUCTS_ID,
+  aggregation: [["count"]],
+  breakout: [["field", PRODUCTS.CATEGORY, null]],
+};
+
+ +

Increase viewport size to avoid scrolling

+ +

Sometimes Metabase views are a bit large for Cypress’ default 1280x800 viewport. This can require you to scroll for tests to work. For example, virtualized tables will not even render the contents outside of the viewport. To avoid these problems, increase the viewport size for a specific test. Unless you’re specifically testing how the application behaves on a window resize, please avoid using the cy.viewport(width, height); in the middle of the test. Set the viewport width/height using the optional Cypress test config instead. This config works with both describe and it blocks.

+ +
describe("foo", { viewportWidth: 1400 }, () => {});
+
+it("bar", { viewportWidth: 1600, viewportHeight: 1200 }, () => {});
+
+ +

Code reloading vs test reloading

+ +

When you edit a Cypress test file, the tests will refresh and run again. However, when you edit a code file, Cypress won’t detect that change. If you’re running yarn build-hot, the code will rebuild and update within Cypress. You’ll have to manually click rerun after the new code has loaded.

+ +

Inspecting while the “contains helper” is open

+ +

One great feature of Cypress is that you can use the Chrome inspector after each step of a test. They also helpfully provide a helper that can test out contains and get calls. This helper creates new UI that prevents inspecting from targeting the correct elements. If you want to inspect the DOM in Chrome, you should close this helper.

+ +

Putting the wrong HTML template in the Uberjar

+ +

yarn build and yarn build-hot each overwrite an HTML template to reference the correct JavaScript files. If you run yarn build before building an Uberjar for Cypress tests, you won’t see changes to your JavaScript reflected even if you then start yarn build-hot.

+ +

Running Cypress on M1 machines

+ +

You might run into problems when running Cypress on M1 machine. +This is caused by the @bahmutov/cypress-esbuild-preprocessor that is using esbuild as a dependency. The error might look like this. The solution is to install NodeJS using one of the Node version managers like nvm or n.

+ +

Another issue you will almost surely face is the inability to connect to our Mongo QA Database. You can solve it by providing the following env:

+ +
export EXPERIMENTAL_DOCKER_DESKTOP_FORCE_QEMU=1
+
+ +

Running tests that depend on Docker images

+ +

A subset of our tests depend on the external services that are available through the Docker images. At the time of this writing, those are the three supported external QA databases, Webmail, Snowplow and LDAP servers. The default cypress command will spin up all necessary docker containers for these tests to function properly, but you can toggle them off if you want

+ +
START_CONTAINERS=false yarn test-cypress
+
+ +

Running tests with Snowplow involved

+ +

Tests that depend on Snowplow expect a running server. This is enabled by default. You can manually enable them as well by spinning up the snowplow micro docker container and setting the appropriate environment variables:

+ +
docker-compose -f ./snowplow/docker-compose.yml up -d
+export MB_SNOWPLOW_AVAILABLE=true
+export MB_SNOWPLOW_URL=http://localhost:9090
+
+ +

Testing with Snowplow

+ +

We have a few helpers for dealing with tests involving snowplow

+ +
    +
  1. You can use describeWithSnowplow (or describeWithSnowplowEE for EE edition) method to define tests that only run when a Snowplow instance is running
  2. +
  3. Use resetSnowplow() test helper before each test to clear the queue of processed events.
  4. +
  5. Use expectGoodSnowPlowEvent({ ...payload}) to assert on the content of a snowplow event. Use expectGoodSnowplowEvents(count) to assert that events have been sent and processed correctly. Prefer the more precise assertion on the actual payload to a mere count of events.
  6. +
  7. Use expectNoBadSnowplowEvents() after each test to assert that no invalid events have been sent.
  8. +
+ +

Running tests that require SMTP server

+ +

Some of our tests depend on the email being set up, and require a local SMTP server. We use maildev Docker image for that purpose. At the time of this writing the image we use is maildev/maildev:2.1.0. The default cypress configuration for local development will handle this for you. If you want to set it up manually, you can use this command:

+ +
docker run -d -p 1080:1080 -p 1025:1025 maildev/maildev:latest
+
+ +

Cypress comes with Lodash for free

+ +

We don’t need to have Lodash in our direct dependencies to be able to use it with Cypress. It is aliased with an underscore and its methods can be accessed with Cypress._.method(). We can use _.times method to stress-test a certain test (or a set of tests) locally.

+ +
// Run the test N times
+Cypress._.times(N, () => {
+  it("should foo", () => {
+    // ...
+  });
+});
+
+ +

Embedding SDK tests

+ +

Tests located in e2e/test-component/scenarios/embedding-sdk/ are used to run automated checks for the Embedding SDK.

+ +

In order to run the tests locally, see sdk docs about e2e

+ +

Sample Apps compatibility with Embedding SDK tests

+ +

In order to check compatibility between Sample Apps and Embedding SDK, we have a special test suite for each sample app that pulls this Sample App, starts it and runs its Cypress tests against the local metabase.jar and local @metabase/embedding-sdk-react package.

+ +

To run these tests locally, run:

+
ENTERPRISE_TOKEN=<token> TEST_SUITE=<sample_app_repo_name>-e2e OPEN_UI=false EMBEDDING_SDK_VERSION=local START_METABASE=false GENERATE_SNAPSHOTS=false START_CONTAINERS=false yarn test-cypress
+
+ +

For example for the metabase-nodejs-react-sdk-embedding-sample, run:

+
ENTERPRISE_TOKEN=<token> TEST_SUITE=metabase-nodejs-react-sdk-embedding-sample-e2e OPEN_UI=false EMBEDDING_SDK_VERSION=local START_METABASE=false GENERATE_SNAPSHOTS=false START_CONTAINERS=false yarn test-cypress
+
+ +

On our CI, test failures do not block the merging of a pull request (PR). However, if a test fails, it’s most likely due to one of the following reasons:

+ +
    +
  • +

    Build Failure:

    + +

    The failure occurs during the build of a local @metabase/embedding-sdk-react dist. This indicates there is likely a syntax or type error in the front-end code.

    +
  • +
  • +

    Test Run Failure:

    + +

    The failure occurs during the actual test execution. In this case, the PR may have introduced a change that either:

    +
      +
    • Breaks the entire Metabase or Embedding SDK, or
    • +
    • Breaks the compatibility between the Embedding SDK and the Sample Apps.
    • +
    +
  • +
+ +

If a PR breaks compatibility between the Embedding SDK and the Sample Apps, the PR can still be merged. However, for each Sample App affected, a separate PR should be created to restore compatibility with the new @metabase/embedding-sdk-react version when it is released. These compatibility PRs should be merged only once the Embedding SDK version containing breaking changes is officially released.

+ +

DB Snapshots

+ +

At the beginning of each test suite we wipe the backend’s db and settings cache. This ensures that the test suite starts in a predictable state.

+ +

Typically, we use the default snapshot by adding before(restore) inside the first describe block to restore before running the whole test suite. If you want to use a snapshot besides the default one, specify the name as an argument to restore like this: before(() => restore("blank")). You can also call restore() inside beforeEach() to reset before every test, or inside specific tests.

+ +

Snapshots are created with a separate set of Cypress tests. These tests start with a blank database and execute specific actions to put the database in predictable state. For example: signup as bob@metabase.com, add a question, turn on setting ABC.

+ +

These snapshot-generating tests have the extension .cy.snap.js. When these tests run they create db dumps in frontend/tests/snapshots/*.sql. They are run before the tests begin and don’t get committed to git.

+ +

Running in CI

+ +

Cypress records videos of each test run, which can be helpful in debugging. Additionally, failed tests have higher quality images saved.

+ +

These files can be found under the “Artifacts” section for each run’s summary in GitHub Actions. +The example of the artifacts for a failed test in “Onboarding” directory: +GitHub Actions artifacts section

+ +

Running Cypress tests against Metabase® Enterprise Edition™

+ +

Prior to running Cypress against Metabase® Enterprise Edition™, set MB_EDITION=ee environment variable.

+ +

Enterprise instance will start without a premium token!

+ +

If you want to test premium features (feature flags), valid tokens need to be available to all Cypress tests. We achieve this by prefixing environment variables with CYPRESS_. +You should provide two tokens that correspond to the EE/PRO self-hosted (all features enabled) and STARTER Cloud (no features enabled) Metabase plans. For more information, please see Metabase pricing page. (note: only a few tests require the no features token)

+ +
    +
  • CYPRESS_ALL_FEATURES_TOKEN
  • +
  • CYPRESS_NO_FEATURES_TOKEN
  • +
+ +
MB_EDITION=ee ENTERPRISE_TOKEN=xxxxxx yarn test-cypress
+
+ +

If you navigate to the /admin/settings/license page, the license input field should display the active token. Be careful when sharing screenshots!

+ +
    +
  • If tests start running but the enterprise features are missing: make sure that the token you use has corresponding feature flags enabled.
  • +
  • If everything with the token seems to be okay, go nuclear and destroy all Java processes: run killall java and restart Cypress.
  • +
+ +

Tags

+ +

Cypress allows us to tag tests, to easily find certain categories of tags. For example, we can tag all tests that require an external database with @external and then run only those tests with yarn test-cypress --env grepTags="@external". Tags should start with @ just to make it easier to distinguish them from other strings in searches.

+ +

These are the tags currently in use:

+ +
    +
  • @external - tests that require an external docker container to run
  • +
  • @actions - tests that use metabase actions and mutate data in a data source
  • +
+ +

How to stress-test a flake fix?

+ +

Fixing a flaky test locally doesn’t mean the fix works in GitHub’s CI environment. The only way to be sure the fix works is to stress-test it in CI. That’s what .github/workflows/e2e-stress-test-flake-fix.yml is made for. It allows you to quickly test the fix in your branch without waiting for the full build to complete.

+ +

Please follow these steps:

+ +

Prepare

+ +
    +
  • Create a new branch with your proposed fix and push it to the remote
  • +
  • Either skip opening a PR altogether or open a draft pull request
  • +
+ +

Trigger the stress-test workflow manually

+ +
    +
  • Go to https://github.com/metabase/metabase/actions/workflows/e2e-stress-test-flake-fix.yml
  • +
  • Click on Run workflow trigger next to “This workflow has a workflow_dispatch event trigger.”
  • +
+ +
    +
  1. Choose your own branch in the first field “Use workflow from” (this part is crucial!)
  2. +
  3. Copy and paste the relative path of the spec you want to test (e.g. e2e/test/scenarios/onboarding/urls.cy.spec.js) - you don’t have to wrap it in quotes
  4. +
  5. Set the desired number of times to run the test
  6. +
  7. Optionally provide a grep filter, according to the documentation
  8. +
  9. Click the green “Run workflow” button and wait for the results
  10. +
+ +

Things to keep in mind when using this workflow

+ +
    +
  • It will automatically try to find and download the previously built Metabase uberjar stored as an artifact from one of the past commits / CI runs.
  • +
  • It was intended to be used for pure E2E fixes that don’t require new Metabase uberjar.
  • +
  • If the fix required a source-code change (either backend of frontend), please open a regular PR instead and let the CI run all tests first. After this, +you can trigger the stress-test workflow manually, as explained above, and it will automatically download newly built artifact from this CI run. Please, +keep in mind that CI needs to fully finish running first. The workflow uses GitHub REST API which doesn’t see artifacts otherwise.
  • +
+ +

Reports

+ +

Individual Mocha reports are automatically generated per spec. They are stored in cypress/reports/mochareports. Please keep in mind that the root level cypress/ folder is git ignored!

+ +

When tests run in CI we do some extra steps by merging these individual reports (using mochawesome-merge), formatting them, and then generating customized GitHub Actions job summaries.

+ +

On an off chance that you need a unified test report while running tests locally, you can achieve that by invoking yarn generate-cypress-html-report.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/emacs.html b/_site/docs/doc-update-detection/developers-guide/emacs.html new file mode 100644 index 000000000..69d6bfe0d --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/emacs.html @@ -0,0 +1,3052 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Developing Metabase with Emacs | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Developing Metabase with Emacs

+ +

.dir-locals.el contains some Emacs Lisp that tells clojure-mode how to indent Metabase macros and which arguments are docstrings. Whenever this file is updated, +Emacs will ask you if the code is safe to load. You can answer ! to save it as safe.

+ +

By default, Emacs will insert this code as a customization at the bottom of your init.el. +You’ll probably want to tell Emacs to store customizations in a different file. Add the following to your init.el:

+ +
(setq custom-file (concat user-emacs-directory ".custom.el")) ; tell Customize to save customizations to ~/.emacs.d/.custom.el
+(ignore-errors                                                ; load customizations from ~/.emacs.d/.custom.el
+  (load-file custom-file))
+
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/frontend.html b/_site/docs/doc-update-detection/developers-guide/frontend.html new file mode 100644 index 000000000..f6c0c720c --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/frontend.html @@ -0,0 +1,3550 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Frontend | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Frontend

+ +

Entity Loaders

+ +

If you’re developing a new feature or just generally need to get at some of the application data on the frontend, Entity Loaders are going to be your friend. They abstract away calling the API, handling loading and error state, cache previously loaded objects, invalidating the cache (in some cases) and let you easily perform updates, or create new items.

+ +

Good uses for Entity Loaders

+ +
    +
  • I need to get a specific X (user, database, etc) and display it.
  • +
  • I need to get a list of X (databases, questions, etc) and display it.
  • +
+ +

Currently available entities:

+ +
    +
  • Questions, Dashboards, Pulses
  • +
  • Collections
  • +
  • Databases, Tables, Fields, Segments, Metrics
  • +
  • Users, Groups
  • +
  • Full current list of entities here: https://github.com/metabase/metabase/tree/master/frontend/src/metabase/entities
  • +
+ +

There are two ways to use loaders, either as React “render prop” components or as React component class decorators (“higher order components”).

+ +

Object loading

+ +

In this example we’re going to load information about a specific database for a new page.

+ +
import React from "react";
+import Databases from "metabase/entities/databases";
+
+@Databases.load({ id: 4 })
+class MyNewPage extends React.Component {
+  render() {
+    const { database } = this.props;
+    return (
+      <div>
+        <h1>{database.name}</h1>
+      </div>
+    );
+  }
+}
+
+ +

This example uses a class decorator to ask for and then display a database with ID 4. If you instead wanted to use a render prop component your code would look like this.

+ +
import React from "react";
+import Databases from "metabase/entities/databases";
+
+class MyNewPage extends React.Component {
+  render() {
+    const { database } = this.props;
+    return (
+      <div>
+        <Databases.Loader id={4}>
+          {({ database }) => <h1>{database.name}</h1>}
+        </Databases.Loader>
+      </div>
+    );
+  }
+}
+
+ +

Now you most likely don’t just want to display just one static item so for cases where some of the values you might need will be dynamic you can use a function to get at the props and return the value you need. If you’re using the component approach you can just pass props as you would normally for dynamic values.

+ +
@Databases.load({
+  id: (state, props) => props.params.databaseId
+}))
+
+ +

List loading

+ +

Loading a list of items is as easy as applying the loadList decorator:

+ +
import React from "react";
+import Users from "metabase/entities/users";
+
+@Users.loadList()
+class MyList extends React.Component {
+  render() {
+    const { users } = this.props;
+    return <div>{users.map(u => u.first_name)}</div>;
+  }
+}
+
+ +

Similar to the object loader’s id argument you can also pass a query object (if the API supports it):

+ +
@Users.loadList({
+  query: (state, props) => ({ archived: props.showArchivedOnly })
+})
+
+ +

Control over loading and error states

+ +

By default both EntityObject and EntityList loaders will handle loading state for you by using LoadingAndErrorWrapper under the hood. If for some reason you want to handle loading on your own you can disable this behavior by setting loadingAndErrorWrapper: false.

+ +

Wrapped objects

+ +

If you pass wrapped: true to a loader then the object or objects will be wrapped with helper classes that let you do things like user.getName(), user.delete(), or user.update({ name: "new name" ). Actions are automatically already bound to dispatch.

+ +

This may incur a performance penalty if there are many objects.

+ +

Any additional selectors and actions defined in the entities’ objectSelectors or objectActions will appear as the wrapped object’s methods.

+ +

Advanced usage

+ +

You can also use the Redux actions and selectors directly, for example, dispatch(Users.actions.loadList()) and Users.selectors.getList(state).

+ +

Style Guide

+ +

Set up Prettier

+ +

We use Prettier to format our JavaScript code, and it is enforced by CI. We recommend setting your editor to “format on save”. You can also format code using yarn prettier, and verify it has been formatted correctly using yarn lint-prettier.

+ +

We use ESLint to enforce additional rules. It is integrated into the Webpack build, or you can manually run yarn lint-eslint to check.

+ +

React and JSX Style Guide

+ +

For the most part we follow the Airbnb React/JSX Style Guide. ESLint and Prettier should take care of a majority of the rules in the Airbnb style guide. Exceptions will be noted in this document.

+ +
    +
  • Prefer React function components over class components
  • +
  • Avoid creating new components within the containers folder, as this approach has been deprecated. Instead, store both connected and view components in the components folder for a more unified and efficient organization. If a connected component grows substantially in size and you need to extract a view component, opt for using the View suffix.
  • +
  • For control components, typically we use value and onChange. Controls that have options (e.x. Radio, Select) usually take an options array of objects with name and value properties.
  • +
  • Components named like FooModal and FooPopover typically refer to the modal/popover content which should be used inside a Modal/ModalWithTrigger or Popover/PopoverWithTrigger
  • +
  • +

    Components named like FooWidget typically include a FooPopover inside a PopoverWithTrigger with some sort of trigger element, often FooName

    +
  • +
  • Use arrow function instance properties if you need to bind a method in a class (instead of this.method = this.method.bind(this); in the constructor), but only if the function needs to be bound (e.x. if you’re passing it as a prop to a React component)
  • +
+ +
class MyComponent extends React.Component {
+  constructor(props) {
+    super(props);
+    // NO:
+    this.handleChange = this.handleChange.bind(this);
+  }
+  // YES:
+  handleChange = e => {
+    // ...
+  };
+  // no need to bind:
+  componentDidMount() {}
+  render() {
+    return <input onChange={this.handleChange} />;
+  }
+}
+
+ +
    +
  • For styling components we currently use a mix of styled-components and “atomic” / “utility-first” CSS classes.
  • +
  • Prefer using grid-styled’s Box and Flex components over raw div.
  • +
  • Components should typically pass along their className prop to the root element of the component. It can be merged with additional classes using the cx function from the classnames package.
  • +
  • In order to make components more reusable, a component should only apply classes or styles to the root element of the component which affects the layout/styling of it’s own content, but not the layout of itself within it’s parent container. For example, it can include padding or the flex class, but it shouldn’t include margin or flex-full, full, absolute, spread, etc. Those should be passed via className or style props by the consumer of the component, which knows how the component should be positioned within itself.
  • +
  • Avoid breaking JSX up into separate method calls within a single component. Prefer inlining JSX so that you can better see what the relation is of the JSX a render method returns to what is in the state or props of a component. By inlining JSX you’ll also get a better sense of what parts should and should not be separate components.
  • +
+ +

+// don't do this
+render () {
+  return (
+    <div>
+      {this.renderThing1()}
+      {this.renderThing2()}
+      {this.state.thing3Needed && this.renderThing3()}
+    </div>
+  );
+}
+
+// do this
+render () {
+  return (
+    <div>
+      <button onClick={this.toggleThing3Needed}>toggle</button>
+      <Thing2 randomProp={this.props.foo} />
+      {this.state.thing3Needed && <Thing3 randomProp2={this.state.bar} />}
+    </div>
+  );
+}
+
+ +

JavaScript Conventions

+ +
    +
  • imports should be ordered by type, typically: +
      +
    1. external libraries (react is often first, along with things like ttags, underscore, classnames, etc)
    2. +
    3. Metabase’s top-level React components and containers (metabase/components/*, metabase/containers/*, etc)
    4. +
    5. Metabase’s React components and containers specific to this part of the application (metabase/*/components/* etc)
    6. +
    7. Metabase’s libs, entities, services, Redux files, etc
    8. +
    +
  • +
  • Prefer const to let (and never use var). Only use let if you have a specific reason to reassign the identifier (note: this now enforced by ESLint)
  • +
  • Prefer arrow functions for inline functions, especially if you need to reference this from the parent scope (there should almost never be a need to do const self = this; etc), but usually even if you don’t (e.x. array.map(x => x * 2)).
  • +
  • Prefer function declarations for top-level functions, including React function components. The exception is for one-liner functions that return a value
  • +
+ +
// YES:
+function MyComponent(props) {
+  return <div>...</div>;
+}
+// NO:
+const MyComponent = props => {
+  return <div>...</div>;
+};
+// YES:
+const double = n => n * 2;
+// ALSO OK:
+function double(n) {
+  return n * 2;
+}
+
+ +
    +
  • Prefer native Array methods over underscore’s. We polyfill all ES6 features. Use Underscore for things that aren’t implemented natively.
  • +
  • Prefer async/await over using promise.then(...) etc directly.
  • +
  • You may use assignment destructuring or argument destructuring, but avoid deeply nested destructuring, since they can be hard to read and prettier sometimes formats them with extra whitespace. +
      +
    • avoid destructuring properties from “entity”-like objects, e.x. don’t do const { display_name } = column;
    • +
    • don’t destructure this directly, e.x. const { foo } = this.props; const { bar } = this.state; instead of const { props: { foo }, state: { bar } } = this;
    • +
    +
  • +
  • Avoid nested ternaries as they often result in code that is difficult to read. If you have logical branches in your code that are dependent on the value of a string, prefer using an object as a map to multiple values (when evaluation is trivial) or a switch statement (when evaluation is more complex, like when branching on which React component to return):
  • +
+ +
// don't do this
+const foo = str == 'a' ? 123 : str === 'b' ? 456 : str === 'c' : 789 : 0;
+
+// do this
+const foo = {
+  a: 123,
+  b: 456,
+  c: 789,
+}[str] || 0;
+
+// or do this
+switch (str) {
+  case 'a':
+    return <ComponentA />;
+  case 'b':
+    return <ComponentB />;
+  case 'c':
+    return <ComponentC />;
+  case 'd':
+  default:
+    return <ComponentD />;
+}
+
+ +

If your nested ternaries are in the form of predicates evaluating to booleans, prefer an if/if-else/else statement that is siloed to a separate, pure function:

+ +
const foo = getFoo(a, b);
+
+function getFoo(a, b, c) {
+  if (a.includes("foo")) {
+    return 123;
+  } else if (a === b) {
+    return 456;
+  } else {
+    return 0;
+  }
+}
+
+ +
    +
  • Be conservative with what comments you add to the codebase. Comments shouldn’t be used as reminders or as todos–record those by creating a new issue in Github. Ideally, code should be written in such a way that it explains itself clearly. When it does not, you should first try rewriting the code. If for whatever reason you are unable to write something clearly, add a comment to explain the “why”.
  • +
+ +

+// don't do this--the comment is redundant
+
+// get the native permissions for this db
+const nativePermissions = getNativePermissions(perms, groupId, {
+  databaseId: database.id,
+});
+
+// don't add TODOs -- they quickly become forgotten cruft
+
+isSearchable(): boolean {
+  // TODO: this should return the thing instead
+  return this.isString();
+}
+
+// this is acceptable -- the implementer explains a not-obvious edge case of a third party library
+
+// foo-lib seems to return undefined/NaN occasionally, which breaks things
+if (isNaN(x) || isNaN(y)) {
+  return;
+}
+
+
+ +
    +
  • Avoid complex logical expressions inside of if statements
  • +
+ +
// don't do this
+if (typeof children === "string" && children.split(/\n/g).length > 1) {
+  // ...
+}
+
+// do this
+const isMultilineText =
+  typeof children === "string" && children.split(/\n/g).length > 1;
+if (isMultilineText) {
+  // ...
+}
+
+ +
    +
  • Use ALL_CAPS for constants
  • +
+ +
// do this
+const MIN_HEIGHT = 200;
+
+// also acceptable
+const OBJECT_CONFIG_CONSTANT = {
+  camelCaseProps: "are OK",
+  abc: 123,
+};
+
+ +
    +
  • Prefer named exports over default exports
  • +
+ +
// this makes it harder to search for Widget
+import Foo from "./Widget";
+// do this to enforce using the proper name
+import { Widget } from "./Widget";
+
+ +
    +
  • Avoid magic strings and numbers
  • +
+ +
// don't do this
+const options = _.times(10, () => ...);
+
+// do this in a constants file
+export const MAX_NUM_OPTIONS = 10;
+const options = _.times(MAX_NUM_OPTIONS,  () => ...);
+
+ +

Write Declarative Code

+ +

You should write code with other engineers in mind as other engineers will spend more time reading than you spend writing (and re-writing). Code is more readable when it tells the computer “what to do” versus “how to do.” Avoid imperative patterns like for loops:

+ +
// don't do this
+let foo = [];
+for (let i = 0; i < list.length; i++) {
+  if (list[i].bar === false) {
+    continue;
+  }
+
+  foo.push(list[i]);
+}
+
+// do this
+const foo = list.filter(entry => entry.bar !== false);
+
+ +

When dealing with business logic you don’t want to be concerned with the specifics of the language. Instead of writing const query = new Question(card).query(); which entails instantiating a new Question instance and calling a query method on said instance, you should introduce a function like getQueryFromCard(card) so that implementers can avoid thinking about what goes into getting a query value from a card.

+ +

Component Styling Tree Rings

+ +

CSS modules

+ +
.primary {
+  color: -var(--mb-color-brand);
+}
+
+ +
import S from "./Foo.css";
+
+const Foo = () => <div className={S.primary} />;
+
+ +

Emotion (discouraged)

+ +
import styled from "@emotion/styled";
+
+const Foo = styled.div`
+  color: ${props => props.color};
+`;
+
+const Bar = ({ color }) => <Foo color={color} />;
+
+ +

Popover

+ +

Popovers are popups or modals.

+ +

In Metabase core, they are visually responsive: they appear above or below the element that triggers their appearance. Their height is automatically calculated to make them fit on the screen.

+ +

Where to Find Popovers in the User Journey

+ +

When creating custom questions

+ +
    +
  1. From home, click on New and then Question
  2. +
  3. 👀 The option picker that automatically opened next to Pick your starting data is a <Popover />.
  4. +
  5. Choose Sample Database if not already selected
  6. +
  7. Choose any of the tables, for example People
  8. +
+ +

Here, clicking on the following will open <Popover /> components:

+ +
    +
  • Pick columns (arrow on the right-hand side of a FieldsPicker control in the section labeled Data)
  • +
  • Gray icon of a grid with + below section labeled Data
  • +
  • Add filters to narrow your answers
  • +
  • Pick the metric you want to see
  • +
  • Pick a column to group by
  • +
  • Sort icon with arrows pointing up and down above Visualize button
  • +
+ +

Unit testing

+ +

Setup pattern

+ +

We use the following pattern to unit test components:

+ +
import React from "react";
+import userEvent from "@testing-library/user-event";
+import { Collection } from "metabase-types/api";
+import { createMockCollection } from "metabase-types/api/mocks";
+import { renderWithProviders, screen } from "__support__/ui";
+import CollectionHeader from "./CollectionHeader";
+
+interface SetupOpts {
+  collection: Collection;
+}
+
+const setup = ({ collection }: SetupOpts) => {
+  const onUpdateCollection = jest.fn();
+
+  renderWithProviders(
+    <CollectionHeader
+      collection={collection}
+      onUpdateCollection={onUpdateCollection}
+    />,
+  );
+
+  return { onUpdateCollection };
+};
+
+describe("CollectionHeader", () => {
+  it("should be able to update the name of the collection", () => {
+    const collection = createMockCollection({
+      name: "Old name",
+    });
+
+    const { onUpdateCollection } = setup({
+      collection,
+    });
+
+    await userEvent.clear(screen.getByDisplayValue("Old name"));
+    await userEvent.type(screen.getByPlaceholderText("Add title"), "New title");
+    await userEvent.tab();
+
+    expect(onUpdateCollection).toHaveBeenCalledWith({
+      ...collection,
+      name: "New name",
+    });
+  });
+});
+
+ +

Key points:

+ +
    +
  • setup function
  • +
  • renderWithProviders adds providers used by the app, including redux
  • +
+ +

Request mocking

+ +

We use fetch-mock to mock requests:

+ +
import fetchMock from "fetch-mock";
+import { setupCollectionsEndpoints } from "__support__/server-mocks";
+
+interface SetupOpts {
+  collections: Collection[];
+}
+
+const setup = ({ collections }: SetupOpts) => {
+  setupCollectionsEndpoints({ collections });
+
+  // renderWithProviders and other setup
+};
+
+describe("Component", () => {
+  it("renders correctly", async () => {
+    setup();
+    expect(await screen.findByText("Collection")).toBeInTheDocument();
+  });
+});
+
+ +

Key points:

+ +
    +
  • setup function
  • +
  • Call helpers from __support__/server-mocks to setup endpoints for your data
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/internationalization.html b/_site/docs/doc-update-detection/developers-guide/internationalization.html new file mode 100644 index 000000000..2fc46348d --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/internationalization.html @@ -0,0 +1,3114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Internationalization | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Internationalization

+ +

We are an application with lots of users all over the world. To help them use Metabase in their own language, we mark all of our strings as i18n.

+ +

Quick Guide

+ +

If you need to add new strings (try to be judicious about adding copy) do the following:

+ +
    +
  1. Tag strings in the frontend using t and jt ES6 template literals (see more details in https://ttag.js.org/):
  2. +
+ +
const someString = t`Hello ${name}!`;
+const someJSX = <div>{jt`Hello ${name}`}</div>;
+
+ +

and in the backend using trs (to use the site language) or tru (to use the current User’s language):

+ +
(trs "Hello {0}!" name)
+
+ +

Translation errors or missing strings

+ +

If you see incorrect or missing strings for your language, please visit our Crowdin project and submit your fixes there.

+ +

Backend Translation Guide

+ +

Metabase allows for translations into many languages. An authoritative list can be found in resources/locales.clj.

+ +

The Metabase Side

+ +

Metabase is concerned about localization into two distinct locales: translating into the server’s locale and translating into the user’s locale. The distinction is largely: will this be logged on the server or sent over the wire back to the user.

+ +

To translate a string for the server, use metabase.util.i18n/trs and for the user’s locale, use the similar metabase.util.i18n/tru. Think tr-server and tr-user.

+ +

How it works

+ +

At a high level, the string to be translated is treated as a lookup key into a map of source-string -> localized-string. This translated string is used like so:

+ +

+;; from source of `translate` in `metabase.util.i18n`
+
+(.format (MessageFormat. looked-up-string) (to-array args))
+
+
+ +

Everything else is largely bookkeeping. This uses the java.text.MessageFormat class for splicing in format args.

+ +

The functions trs and tru create instances of two records, SiteLocalizedString and UserLocalizedString respectively with overrides to the toString method. This method will do the lookup to the current locale (user or site as appropriate), lookup the string to be translated to the associated translated string, and then call the .format method on the MessageFormat.

+ +

The maps from source to translated string

+ +

One step in our build process creates an edn file of source to translated string for each locale we support. These are located in resources/i18n. If you do not have these files, you can run bin/build-translation-resources to generate them.

+ +

We have lots of contributors who help us keep a corpus of translated strings into many different languages. We use Crowdin to keep an authoritative list. We export .po files from this, which is essentially a dictionary from source to translated string. As part of our build process we format these files as edn files, maps from the source to translated string, for each locale.

+ +

Format Args

+ +

Besides string literals, we also want to translate strings that have arguments spliced into the middle. We use the syntax from the java.text.MessageFormat class mentioned before. These are zero-indexed args of the form {0}, {1}.

+ +

eg,

+ +
(trs "{0} accepted their {1} invite" (:common_name new-user) (app-name-trs))
+(tru "{0}th percentile of {1}" p (aggregation-arg-display-name inner-query arg))
+(tru "{0} driver does not support foreign keys." driver/*driver*)
+
+ +

Escaping

+ +

Every string language needs an escape character. Since {0} is an argument to be spliced in, how would you put a literal “{0}” in the string. The apostrophe serves this role and is described in the MessageFormat javadocs.

+ +

These is an unfortunate side effect of this though. Since the apostrophe is such a commeon part of speech (especially in french), we often can end up with escape characters used as a regular part of a string rather than the escape character. Format strings need to use double apostrophes like (deferred-tru "SAML attribute for the user''s email address") to escape the apostrophe.

+ +

There are lots of translated strings in French that use a single apostrophe incorrectly. (eg “l’URL” instead of “l’‘URL”). We have a manual fix to this in bin/i18n/src/i18n/create_artifacts/backend.clj where we try to identify these apostrophes which are not escape characters and replace them with a double quote.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/mage.html b/_site/docs/doc-update-detection/developers-guide/mage.html new file mode 100644 index 000000000..64a2cbfd9 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/mage.html @@ -0,0 +1,3069 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Mage | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

MAGE - Development Automation

+ +

Run ./bin/mage to list your tasks. All of them support -h to learn more and show examples.

+ +

All tasks support a -h option and will print their usage info.

+ +
$ ./bin/mage
+   ███╗   ███╗ █████╗  ██████╗ ███████╗
+   ████╗ ████║██╔══██╗██╔════╝ ██╔════╝
+   ██╔████╔██║███████║██║  ███╗█████╗
+   ██║╚██╔╝██║██╔══██║██║   ██║██╔══╝
+   ██║ ╚═╝ ██║██║  ██║╚██████╔╝███████╗
+   ╚═╝     ╚═╝╚═╝  ╚═╝ ╚═════╝ ╚══════╝
+    The Metabase Automation Genius Engine
+
+The following tasks are available:
+
+cljfmt-staged   Runs cljfmt on staged files
+kondo           Runs Kondo against a file, directory, or everything we usually lint
+...
+start-db        Start a db on a default port in docker
+jar-download    Given a version, downloads a metabase jar
+$ ./bin/mage kondo -h
+<prints help for easily running kondo>
+
+ +

mage Autocomplete

+ +

Run ./bin/mage setup-autocomplete and follow the instructions to setup autocomplete in your terminal.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/mbql-library-changelog.html b/_site/docs/doc-update-detection/developers-guide/mbql-library-changelog.html new file mode 100644 index 000000000..bf62dee55 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/mbql-library-changelog.html @@ -0,0 +1,3073 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +MBQL Library changelog | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

MBQL Library Changelog

+ +

Changes made to the library API for manipulating MBQL queries, found in metabase.lib.js. The latest API documentation +can be found here.

+ +

This library is mainly used by Metabase’s own frontend, but it is treated as a proper API surface which is versioned +and documented in this changelog.

+ +

Metabase 0.50.0

+ +
    +
  • Created this file and began versioning this API.
  • +
  • +

    New function as-returned has been added. It handles a tricky case when adding filters or expressions to a query +with aggregations.

    + +

    Suppose we have a query with aggregations in its last stage. When adding a filter or expression to that stage, it’s +applied before the aggregations. That may be the desired behavior, but if we want a filter or custom expression +based on the aggregations and breakouts in the last stage, there was no good support in this API.

    + +

    as-returned looks at the query and stage, and shifts to a later stage if necessary. If a later stage is needed but +we were already on the last stage, a new empty stage is appended.

    +
  • +
  • New functions column-extractions, extract, and extraction-expression have been added. +
      +
    • column-extractions returns a list of extractions, which are possible custom expressions we can derive from a +given column. For example, getting the host or base domain name from a URL or email address, or the day of the week +from a date or datetime.
    • +
    • extract applies an extraction to the query.
    • +
    • extraction-expression returns the expression for the extraction, allowing further editing.
    • +
    +
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/partner-and-community-drivers.html b/_site/docs/doc-update-detection/developers-guide/partner-and-community-drivers.html new file mode 100644 index 000000000..588a91bca --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/partner-and-community-drivers.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/developers-guide/start.html b/_site/docs/doc-update-detection/developers-guide/start.html new file mode 100644 index 000000000..6754e40e3 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/start.html @@ -0,0 +1,3102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Developer Guide | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Developer Guide

+ +

This guide contains detailed information on how to work on Metabase codebase.

+ +

Contributing

+ + + +

Setup and build

+ + + +

Working with the code

+ + + +

Testing

+ + + +

API documentation

+ + + +

Database drivers

+ + + +

Metabase documentation

+ + + +

Releases

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/versioning.html b/_site/docs/doc-update-detection/developers-guide/versioning.html new file mode 100644 index 000000000..b8bb5fea6 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/versioning.html @@ -0,0 +1,3107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Metabase release versioning | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Metabase release versioning

+ +

We follow our own flavor of the semantic versioning guidelines in order to distinguish the open-source version of Metabase from the paid, source-available version of Metabase (available in the Pro and Enterprise plans).

+ +

Semantic versioning typically follows the format: Major.Minor.Point.Patch. For example, version 3.15.2 or 3.15.2.1.

+ +

With Metabase releases, we prefix the version with a 0 or 1, depending on the license.

+ +

The Metabase version schema

+ +
License.Major.Point.Hotfix
+
+ +

E.g.,

+ +
v0.46.3.1
+
+ +

v0.46.3.1 would be for a hotfix (1) for the third (3) point release of Metabase 46, the open-source edition (0).

+ +

License

+ +
    +
  • 0 for the free, open-source version (sometimes called OSS, for open-source software).
  • +
  • 1 for the paid, source-available version that has all the bells and whistles (sometimes called EE for “Enterprise Edition”).
  • +
+ +

Major

+ +

We release major version when we introduce new features or breaking changes.

+ +

Point

+ +

Sometimes called a minor release, we issue point releases when we add bug fixes and refinements to existing features.

+ +

Hotfix

+ +

Sometimes called a patch release, we issue these hotfix releases to fix security issues in a timely manner, or to undo a horrific regression.

+ +

Other release terms

+ +

The Gold Release

+ +

The gold release is the first release of a new major version of Metabase. So for Metabase version 46, the gold releases would be:

+ +
    +
  • v0.46.0 (the OSS version)
  • +
  • v1.46.0 (the EE version)
  • +
+ +

Release Candidates

+ +

We usually publish release candidates to kick the tires on new features before releasing a new major version (a gold release). To distinguish these release candidates, we append an -RC# at the end.

+ +

E.g.,

+ +
    +
  • v1.46.0-RC1 (the first release candidate for the EE version)
  • +
  • v0.46.0-RC3 (the third release candidate for the OSS version)
  • +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/visual-studio-code.html b/_site/docs/doc-update-detection/developers-guide/visual-studio-code.html new file mode 100644 index 000000000..5343428f2 --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/visual-studio-code.html @@ -0,0 +1,3112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Developing with Visual Studio Code | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Developing with Visual Studio Code

+ +

Debugging

+ +

First, install the following extension:

+ + + +

Note: Debugger for Chrome has been deprecated. You can safely delete it as Visual Studio Code now has a bundled JavaScript Debugger that covers the same functionality.

+ +

Before starting the debugging session, make sure that Metabase is built and running. Choose menu View, Command Palette, search for and choose Tasks: Run Build Task. Alternatively, use the corresponding shortcut Ctrl+Shift+B. The built-in terminal will appear to show the progress, wait a few moment until webpack indicates a complete (100%) bundling.

+ +

To begin debugging Metabase, switch to the Debug view (shortcut: Ctrl+Shift+D) and then select one of the two launch configurations from the drop-down at the top:

+ +
    +
  • Debug with Firefox, or
  • +
  • Debug with Chrome
  • +
+ +

After that, begin the debugging session by choosing menu Run, Start Debugging (shortcut: F5).

+ +

For more details, please refer to the complete VS Code documentation on Debugging.

+ +

Docker-based Workflow

+ +

These instructions allow you to work on Metabase codebase on Windows, Linux, or macOS using Visual Studio Code, without manually installing the necessary dependencies. This is possible by leveraging Docker container and the Remote Containers extension from VS Code.

+ +

For more details, please follow the complete VS Code guide on Developing inside a Container.

+ +

Requirements:

+ + + +

Important: Ensure that Docker is running properly and it can be used to download an image and launch a container, e.g. by running:

+ +
$ docker run hello-world
+
+ +

If everything goes well, you should see the following message:

+ +
Hello from Docker!
+This message shows that your installation appears to be working correctly.
+
+ +

Steps:

+ +
    +
  1. +

    Clone Metabase repository

    +
  2. +
  3. +

    Launch VS Code and open your cloned Metabase repository

    +
  4. +
  5. +

    From the View menu, choose Command Palette… and then find Remote-Container: Reopen in Container. (VS Code may also prompt you to do this with an “Open in container” popup). +Note: VS Code will create the container for the first time and it may take some time. Subsequent loads should be much faster.

    +
  6. +
  7. +

    Use the menu View, Command Palette, search for and choose Tasks: Run Build Task (alternatively, use the shortcut Ctrl+Shift+B).

    +
  8. +
  9. +

    After a while (after all JavaScript and Clojure dependencies are completely downloaded), open localhost:3000 with your web browser.

    +
  10. +
+ +

See here for more on running development branches of Metabase using Docker.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/developers-guide/visual-tests.html b/_site/docs/doc-update-detection/developers-guide/visual-tests.html new file mode 100644 index 000000000..fab7b881e --- /dev/null +++ b/_site/docs/doc-update-detection/developers-guide/visual-tests.html @@ -0,0 +1,3068 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Visual Tests | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Visual Tests

+ +

We use Loki with Storybook for visual tests. Loki captures snapshots from selected stories and creates PNG references in ./loki/references folder.

+ +

Local machine

+ +

Before running Loki tests locally, ensure that both Storybook and Docker are running.

+ +

Commands

+ +
    +
  • Run Visual Tests: yarn test-visual:loki
  • +
  • Update failing snapshots: yarn test-visual:loki-approve-diff
  • +
  • Generate an HTML Report: yarn test-visual:loki-report
  • +
  • Generate and Open Report: yarn test-visual:loki-report-open
  • +
+ +

CI

+ +

Visual tests are automatically triggered on pull requests. The Loki CI job builds the Storybook, captures new snapshots, and compares them with the references. If there are differences, the “Loki Visual Regression Testing” check will fail.

+ +

To view the visual diff report, open the failed job page, go to the Summary section, and download the loki-report artifact.

+ +

If the differences are intentional or caused by a flake, update the reference snapshots by adding the loki-update label to the pull request.

+ +

Adding new tests

+ +

Adding new test is as simple as adding new stories. As of today, we use visual tests only for charts, however, you can use it for any other stories. Make sure the storiesFilter value in loki.config.js includes the stories you want to have as visual tests.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/12-public-links.html b/_site/docs/doc-update-detection/embedding/12-public-links.html new file mode 100644 index 000000000..99f219b77 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/12-public-links.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/embedding/customize-embeds.html b/_site/docs/doc-update-detection/embedding/customize-embeds.html new file mode 100644 index 000000000..f05bdac44 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/customize-embeds.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/embedding/fonts.html b/_site/docs/doc-update-detection/embedding/fonts.html new file mode 100644 index 000000000..8fb13bef7 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/fonts.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/embedding/full-app-embedding.html b/_site/docs/doc-update-detection/embedding/full-app-embedding.html new file mode 100644 index 000000000..b845c0ecd --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/full-app-embedding.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/embedding/images/04-preview.png b/_site/docs/doc-update-detection/embedding/images/04-preview.png new file mode 100644 index 000000000..92c62242d Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/04-preview.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/05-code.png b/_site/docs/doc-update-detection/embedding/images/05-code.png new file mode 100644 index 000000000..9557e92db Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/05-code.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/action-buttons.png b/_site/docs/doc-update-detection/embedding/images/action-buttons.png new file mode 100644 index 000000000..4833ac0c6 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/action-buttons.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/additional-info.png b/_site/docs/doc-update-detection/embedding/images/additional-info.png new file mode 100644 index 000000000..ed2e1a56a Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/additional-info.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/all-users.png b/_site/docs/doc-update-detection/embedding/images/all-users.png new file mode 100644 index 000000000..b89582dde Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/all-users.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/create-a-public-link.png b/_site/docs/doc-update-detection/embedding/images/create-a-public-link.png new file mode 100644 index 000000000..fdcd683cd Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/create-a-public-link.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/dashboard-sharing.png b/_site/docs/doc-update-detection/embedding/images/dashboard-sharing.png new file mode 100644 index 000000000..8b2f0d12a Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/dashboard-sharing.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/embedded-example-dashboard.png b/_site/docs/doc-update-detection/embedding/images/embedded-example-dashboard.png new file mode 100644 index 000000000..65c0fd398 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/embedded-example-dashboard.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/enable-public-sharing.png b/_site/docs/doc-update-detection/embedding/images/enable-public-sharing.png new file mode 100644 index 000000000..13a96abea Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/enable-public-sharing.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/interactive-question-sample-app.png b/_site/docs/doc-update-detection/embedding/images/interactive-question-sample-app.png new file mode 100644 index 000000000..f492bbcb8 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/interactive-question-sample-app.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/interactive-question.png b/_site/docs/doc-update-detection/embedding/images/interactive-question.png new file mode 100644 index 000000000..a46e7cae6 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/interactive-question.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/jwt-setup.png b/_site/docs/doc-update-detection/embedding/images/jwt-setup.png new file mode 100644 index 000000000..539d36e1d Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/jwt-setup.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/map-user-attribute.png b/_site/docs/doc-update-detection/embedding/images/map-user-attribute.png new file mode 100644 index 000000000..366ac30e9 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/map-user-attribute.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/no-top-no-side.png b/_site/docs/doc-update-detection/embedding/images/no-top-no-side.png new file mode 100644 index 000000000..0a07d147b Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/no-top-no-side.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/powered-by-metabase.png b/_site/docs/doc-update-detection/embedding/images/powered-by-metabase.png new file mode 100644 index 000000000..7108cd02c Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/powered-by-metabase.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/public-embed.png b/_site/docs/doc-update-detection/embedding/images/public-embed.png new file mode 100644 index 000000000..8e87c240c Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/public-embed.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/public-export.png b/_site/docs/doc-update-detection/embedding/images/public-export.png new file mode 100644 index 000000000..e22760ad0 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/public-export.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/public-link-custom-destination.png b/_site/docs/doc-update-detection/embedding/images/public-link-custom-destination.png new file mode 100644 index 000000000..ee4b0bd8c Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/public-link-custom-destination.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/pug-and-play.png b/_site/docs/doc-update-detection/embedding/images/pug-and-play.png new file mode 100644 index 000000000..096915f98 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/pug-and-play.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/query-builder.png b/_site/docs/doc-update-detection/embedding/images/query-builder.png new file mode 100644 index 000000000..7bc097aa3 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/query-builder.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/sandboxed-invoices-table.png b/_site/docs/doc-update-detection/embedding/images/sandboxed-invoices-table.png new file mode 100644 index 000000000..0eaa36d82 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/sandboxed-invoices-table.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/see-shared-content.png b/_site/docs/doc-update-detection/embedding/images/see-shared-content.png new file mode 100644 index 000000000..c577f72c1 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/see-shared-content.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/sharing-embed.png b/_site/docs/doc-update-detection/embedding/images/sharing-embed.png new file mode 100644 index 000000000..0a898e674 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/sharing-embed.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/side-nav.png b/_site/docs/doc-update-detection/embedding/images/side-nav.png new file mode 100644 index 000000000..daff7aa27 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/side-nav.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/static-question.png b/_site/docs/doc-update-detection/embedding/images/static-question.png new file mode 100644 index 000000000..0ce9d08c7 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/static-question.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/sync-groups.png b/_site/docs/doc-update-detection/embedding/images/sync-groups.png new file mode 100644 index 000000000..8d5e5aa44 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/sync-groups.png differ diff --git a/_site/docs/doc-update-detection/embedding/images/top-nav.png b/_site/docs/doc-update-detection/embedding/images/top-nav.png new file mode 100644 index 000000000..64f76f746 Binary files /dev/null and b/_site/docs/doc-update-detection/embedding/images/top-nav.png differ diff --git a/_site/docs/doc-update-detection/embedding/interactive-embedding-quick-start-guide.html b/_site/docs/doc-update-detection/embedding/interactive-embedding-quick-start-guide.html new file mode 100644 index 000000000..2f53f1b19 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/interactive-embedding-quick-start-guide.html @@ -0,0 +1,3368 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Interactive embedding quickstart | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Interactive embedding quickstart

+ +

You’ll embed the full Metabase application in your app. Once logged in, people can view a Metabase dashboard in your web app, and be able to use the full Metabase application to explore their data, and only their data.

+ + + +

Prerequisites

+ +
    +
  • You have an app that you can embed Metabase in.
  • +
  • You have a Pro or Enterprise subscription of Metabase. If you’re unsure where to start, sign up for a free trial for Pro On-Prem. If you have Docker Desktop installed, you can just search for “metabase-enterprise” to find the Docker image and run it. Alternatively, you can follow these instructions.
  • +
+ +

The code featured in this guide can be found in our sample repo.

+ +

Set up SSO and interactive embedding in Metabase

+ +

Have a dashboard ready to embed

+ +

You’ll first need a dashboard to embed. If you don’t have one yet, you can use the Example Dashboard Metabase includes on new instances or you can generate one using x-rays.

+ +

Visit that dashboard and make a note of its URL, e.g. /dashboard/1-e-commerce-insights. You’ll need to put this relative URL in your app, as you’ll use the dashboard as the first page that logged-in people will see when they visit the analytics section in your app. It’s enough to include the ID only and omit the rest of the URL, e.g. /dashboard/1.

+ +

You could also use the dashboard’s Entity ID. On the dashboard, click on the info button. On the Overview tab, look for the dashboard’s Entity ID. Copy that Entity ID. You’ll use that Entity ID in the iframe’s src URL: (e.g., src=/dashboard/entity/[Entity ID]).

+ +

Enable interactive embedding

+ +

In Metabase, click on the gear icon in the upper right and go to Admin settings > Settings > Embedding. Look for Interactive Embedding and click on the Enabled toggle.

+ +

Click on the Configure button under Interactive Embedding. Under Authorized origins, add the URL of the website or web app where you want to embed Metabase. If you’re running your app locally, you can add localhost and specify the port number, e.g. http://localhost:8080.

+ +

SameSite configuration

+ +

If you’re embedding Metabase in a different domain, you may need to set the session cookie’s SameSite value to none

+ +

Set up SSO with JWT in your Metabase

+ +

Enable authentication with JWT

+ +

While still in the Admin panel’s Settings section, click on Authentication.

+ +

On the card that says JWT, click the Setup button (you may have to scroll down to view the JWT card).

+ +

Admin settings: Authentication > JTW setup.

+ +

Set JWT Identity provider URI

+ +

In your app, you’ll create a route for SSO at /sso/metabase. In the JWT IDENTITY PROVIDER URI field, enter the URL of your SSO route. For example, our sample app runs on port 8080, so in that case this JWT IDENTITY PROVIDER URI could be http://localhost:8080/sso/metabase.

+ +

Generate a JWT signing key

+ +

Click on the Generate key button to generate a signing key. Keep this key a secret. You’ll use it on your server. If you generate another key, you’ll overwrite the existing key, so you’ll need to update the key in your app as well.

+ +

Copy this key, as you’ll need it in the next section.

+ +

Save and enable JWT authentication

+ +

We’ll set up group synchronization later, but for now, be sure to click the Save and enable button to activate JWT authentication.

+ +

Set up SSO with JWT in your app’s server

+ +

Add the signing key and Metabase site URL to your app

+ +

Here you’ll need to input some values for your SSO to work.

+ +

You’ll want to declare up two constants in your app:

+ +
    +
  • METABASE_JWT_SHARED_SECRET, paste the JWT signing key that you got from your Metabase here.
  • +
  • METABASE_SITE_URL, which points to your Metabase’s root path.
  • +
+ +
const METABASE_JWT_SHARED_SECRET = "YOURSIGNINGKEY";
+const METABASE_SITE_URL = "https://your-domain.metabaseapp.com";
+
+ +

The signing key should preferably be setup as an environment variable, to avoid accidentally committing your key to your app’s repo.

+ +

Add a JWT library to your app’s server

+ +

Add a JWT library to your app. For example, if you’re using a Node backend with JavaScript, we recommend using jsonwebtoken.

+ +

In your terminal:

+ +
npm install jsonwebtoken --save
+
+ +

And in your app, require the library:

+ +
import jwt from "jsonwebtoken";
+
+ +

Restricting access to certain routes

+ +

Presumably, your app already has some way of making sure some routes are only accessible after having signed in. Our examples use a simple helper function named restrict that protects these routes:

+ +
function restrict(req, res, next) {
+  if (req.session.user) {
+    next();
+  } else {
+    req.session.returnTo = req.originalUrl;
+    req.session.error = "Access denied!";
+    res.redirect("/login");
+  }
+}
+
+ +

Add a function to sign users

+ +

We need to write a function to sign user JWTs, using the JWT library.

+ +
const signUserToken = user =>
+  jwt.sign(
+    {
+      email: user.email,
+      first_name: user.firstName,
+      last_name: user.lastName,
+      exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration
+    },
+    METABASE_JWT_SHARED_SECRET,
+  );
+
+ +

Add a sso/metabase route

+ +

You’ll need to add a route to sign people in to your Metabase via SSO using JWT. If the person isn’t signed in to your app yet, your app should redirect them through your sign-in flow. In the code below, this check and redirection is handled by the restrict function we introduced earlier.

+ +
app.get("/sso/metabase", restrict, (req, res) => {
+  const ssoUrl = new URL("/auth/sso", METABASE_INSTANCE_URL);
+  ssoUrl.searchParams.set("jwt", signUserToken(req.session.user));
+  ssoUrl.searchParams.set("return_to", req.query.return_to?.toString() ?? "/");
+
+  res.redirect(ssoUrl.href);
+});
+
+ +

If the person has never signed in to Metabase before, Metabase will create an account for them.

+ +

CHECKPOINT: sign in to your Metabase using SSO

+ +

Make sure you are signed out of your Metabase. From the Metabase sign-in page, click on “Sign in with SSO”. You should be redirected to your app.

+ +

Log in to your app. Your app should redirect you to your Metabase welcome page. If the person doesn’t yet have a Metabase account, Metabase should create an account for them.

+ +

Embed Metabase in your app

+ +

Now to embed your Metabase in your app. You’ll want to set up a route to serve your embedded analytics. Let’s call it /analytics. Note that we’re using the restrict helper function (defined above) because this page should only be viewable after people sign in to your app.

+ +

In this route, we need to render an iframe that will load your Metabase. The src attribute of the iframe should point to the relative path of the SSO endpoint of your app. Once the person signs in to your app (and therefore in to your Metabase), we add the query string parameter return_to so that the iframe displays the requested dashboard.

+ +

METABASE_DASHBOARD_PATH should be pointing to the relative path of the dashboard you created at the beginning of this guide (/dashboard/[ID], or if you used the dashboard’s Entity ID: /dashboard/entity/[Entity ID]).

+ +
app.get("/analytics", restrict, (req, res) => {
+  const METABASE_DASHBOARD_PATH = "/dashboard/entity/[Entity ID]"; // e.g., `/dashboard/1` or `/dashboard/entity/nXg0q7VOZJp5a3_hceMRk`
+  const iframeUrl = `/sso/metabase?return_to=${METABASE_DASHBOARD_PATH}`;
+
+  res.send(
+    `<iframe src="${iframeUrl}" frameborder="0" width="1280" height="600" allowtransparency></iframe>`,
+  );
+});
+
+ +

The METABASE_DASHBOARD_PATH is just the first thing people will see when they log in, but you could set that path to any Metabase URL. And since you’re embedding the full Metabase, people will be able to drill through the data and view other questions, dashboards, and collections.

+ +

CHECKPOINT: view a Metabase dashboard in your app

+ +

People using your app should now be able to access /analytics and view your embedded Metabase dashboard.

+ +

How to test: Sign in to your app and visit the /analytics route. You should see the Metabase dashboard.

+ +
+

If you’re using the Safari browser, and you’re serving Metabase and your app from different domains, you may need to go to Safari’s settings and turn off Prevent cross-site tracking.

+
+ +

Set up a group in Metabase

+ +

Now that you have SSO and interactive embedding set up, it’s time to set up groups so that you can apply permissions to your embedded Metabase entities (questions, dashboards, collections, and so on).

+ +

Add a groups key to your token

+ +

Recall the signUserToken function used to create the JWTs. Add a groups key to the signed token that maps to an array. Metabase will look at the values in that array to see if any of the values map to a group in Metabase (We’ll walk through mapping groups in a bit).

+ +
const signUserToken = user =>
+  jwt.sign(
+    {
+      email: user.email,
+      first_name: user.firstName,
+      last_name: user.lastName,
+      groups: ["Customer-Acme"],
+      exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration
+    },
+    METABASE_JWT_SHARED_SECRET,
+  );
+
+ +

Create a group in Metabase

+ +

In Metabase, click the gear icon and go to Admin settings > People > Groups. Click the Create a group button. Add a group that corresponds with a group in your app. If you’re using the sample app, add a group called Customer Acme.

+ +

Synchronize groups between Metabase and your app

+ +

You’ll map this string in the groups key to a Metabase group, so that when the person signs in via SSO, Metabase automatically assigns them to the appropriate Metabase group.

+ +

In Metabase’s admin section, go to Settings > Authentication. Scroll to the JWT card and click Edit.

+ +

In the Group schema section, toggle on Synchronize group memberships. For each group you want to sync, add a group mapping. When you click New mapping, enter “Customer-Acme”, the string that you included in the groups array in your JWT payload. You can then associate that group name with the Metabase group “Customer Acme” that we created earlier.

+ +

Mapping user attributes to groups.

+ +

Be sure to Save changes.

+ +

CHECKPOINT: verify that Metabase assigns people to groups when they log in

+ +

First, sign out of Metabase and sign in using SSO.

+ +

Then sign out and sign in to your Metabase as an admin and go to Admin settings > People section and verify that Metabase added the person to the appropriate group.

+ +

Note: only Metabase admins and group managers are aware of groups. Basic users have no concept of groups, and no way of knowing which groups they’re a part of.

+ +

Set permissions

+ +

Now to apply permissions to that group so that people only see data specific to their accounts.

+ +

Reset permissions for the All Users group

+ +

Metabase ships with two initial groups: “Admins” and “All Users”. By default, Metabase gives the “All Users” group access to connected data sources. And since Metabase grants people the privileges of their most permissive group, you’ll want to restrict what the “All Users” groups can see before you add them to groups with limited or no access to data sources and collections.

+ +

To reset permissions for the All users group, click on the gear icon and go to Admin settings > Permissions. Under the Data tab, go to Groups and select All Users. For the Sample Database in the View data column, select “Blocked”. Click Save changes and a modal will pop up summarizing what you’re changing. Click Yes.

+ +

Resetting permissions of the All Users group to

+ +

Allow view access to the automatically generated dashboards collection

+ +

Still in the Permissions tab, click on the Collections sub-tab, then on the Automatically generated dashboards collection, and set the Collection access permissions for the All Users group to View.

+ +

Click Save changes, then Yes.

+ +

Add a user attribute to the token

+ +

You can include user attributes in the JSON web token. Metabase will pick up any keys from the JWT payload and store them as user attributes. Among other use cases, you can use these user attributes to set row-level permissions on tables, so people can only see results tied to their accounts.

+ +

If you’re using our sample app, edit the signUserToken function used to create the JWT by adding a key account_id with value 28.

+ +
const signUserToken = user =>
+  jwt.sign(
+    {
+      email: user.email,
+      first_name: user.firstName,
+      last_name: user.lastName,
+      // hard-coded account ID added to this object
+      // just to test sandboxing with Metabase's Sample Database: Invoices table
+      account_id: 28,
+      groups: ["Customer-Acme"],
+      exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration
+    },
+    METABASE_JWT_SHARED_SECRET,
+  );
+
+ +

That user ID will correspond to the Account ID column in the Sample Database’s Invoices table. We’ll use this account_id user attribute to sandbox the Invoices table, so people will only see rows in that table that contain their account ID.

+ +

Note that to persist the user attribute in Metabase, you’ll need to log in. Log in to your app as a non-admin, and visit the page with your embedded Metabase.

+ +

Set row-level permissions with data sandboxing

+ +

In Metabase, go to Admin settings > Permissions. Under the Data tab on the left, click on a group. For “Sample Database”, change its Data access column to Granular.

+ +

Metabase will display a list of the tables in the database. Next, change Data access for the “Invoices” table to Sandboxed.

+ +

Sandboxing a table.

+ +

Next, Metabase will prompt you with a modal to associate a column in that table with a user attribute.

+ +

Leave the Filter by a column in a table option checked, and associate the “Account ID” column in the Invoices table with the user attribute account_id. (Note that Metabase will only display the user attributes if the user has signed in through SSO before.)

+ +

Mapping a column in the sandboxed table to a user attribute.

+ +

Click Save to confirm your select. Then click the Save changes button in the upper right.

+ +

Metabase will ask if you’re sure you want to do this. You are sure.

+ +

CHECKPOINT: view sandboxed dashboard

+ +

Make sure you’ve logged out of your previous session.

+ +

Log in to your app, navigate to /analytics. The dashboard will now present different information, since only a subset of the data is visible to this person. Click on Browse Data at the bottom of the left nav. View your sandboxed Invoices table, and you should only see rows in that table that are associated with the person’s account.

+ +

Hiding Metabase elements

+ +

You can decide to show or hide various Metabase elements, like whether to show the nav bar, search or the +New button, and so on.

+ +

For example, to hide the logo and the top navigation bar of your embedded Metabase, you’d append the query string parameters ?logo=false&top_nav=false to the return_to URL that you include in the SSO redirect.

+ +

In the handler of your /sso/metabase path, add the query parameters:

+ +
ssoUrl.searchParams.set(
+  "return_to",
+  `${req.query.return_to ?? "/"}?logo=false&top_nav=false`,
+);
+
+ +

CHECKPOINT: verify hidden UI elements

+ +

Sign out and sign in to your app again and navigate to /analytics. Your embedded Metabase should not include the logo or the top navigation.

+ +

Next steps

+ +

You can customize how Metabase looks in your app: fonts, colors, and logos.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/interactive-embedding.html b/_site/docs/doc-update-detection/embedding/interactive-embedding.html new file mode 100644 index 000000000..2dc8b242c --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/interactive-embedding.html @@ -0,0 +1,3452 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Interactive embedding | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Interactive embedding

+ +
+
+ + + + + + + +

Interactive embedding is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ + + +

Interactive embedding is what you want if you want to offer multi-tenant, self-service analytics.

+ +

Interactive embedding is the only type of embedding that integrates with your permissions and SSO to give people the right level of access to query and drill-down into your data.

+ +

Interactive embedding demo

+ +

To get a feel for what you can do with interactive embedding, check out our interactive embedding demo.

+ +

To see the query builder in action, click on Reports > + New > Question.

+ +

Quick start

+ +

Check out the Interactive embedding quick start.

+ +

Prerequisites for interactive embedding

+ +
    +
  1. Make sure you have a license token for a Pro or Enterprise plan.
  2. +
  3. Organize people into Metabase groups.
  4. +
  5. Set up permissions for each group.
  6. +
  7. Set up SSO to automatically apply permissions and show people the right data upon sign-in. In general, we recommend using SSO with JWT.
  8. +
+ +

If you’re dealing with a multi-tenant situation, check out our recommendations for Configuring permissions for different customer schemas.

+ +

If you have your app running locally, and you’re using the Pro Cloud version, or hosting Metabase and your app in different domains, you’ll need to set your Metabase environment’s session cookie samesite option to “none”.

+ +

Enabling interactive embedding in Metabase

+ +
    +
  1. Go to Settings > Admin settings > Embedding.
  2. +
  3. Click Enable.
  4. +
  5. Click Interactive embedding.
  6. +
  7. Under Authorized origins, add the URL of the website or web app where you want to embed Metabase (such as https://*.example.com).
  8. +
+ +

Setting up embedding on your website

+ +
    +
  1. Create an iframe with a src attribute set to: + +
  2. +
  3. Optional: Depending on the way your web app is set up, set environment variables to: + +
  4. +
  5. Optional: Enable communication to and from the embedded Metabase using supported postMessage messages: + +
  6. +
  7. Optional: Set parameters to show or hide Metabase UI components.
  8. +
+ +

Once you’re ready to roll out your interactive embed, make sure that people allow browser cookies from Metabase, otherwise they won’t be able to log in.

+ +

Pointing an iframe to a Metabase URL

+ +

Go to your Metabase and find the page that you want to embed.

+ +

For example, to embed your Metabase home page, set the src attribute to your site URL, such as:

+ +
src="http://metabase.yourcompany.com/"
+
+ +

To embed a specific Metabase dashboard, you’ll want to use the dashboard’s Entity ID URL /dashboard/entity/[Entity ID].

+ +
src="http://metabase.yourcompany.com/dashboard/entity/[Entity ID]"
+
+ +

To get a dashboard’s Entity ID, visit the dashboard and click on the info button. In the Overview tab, copy the Entity ID. Then in your iframe’s src attribute to:

+ +
src=http://metabase.yourcompany.com/dashboard/entity/Dc_7X8N7zf4iDK9Ps1M3b
+
+ +

If your dashboard has more than one tab, select the tab you want people to land on and copy the Tab’s ID. Add the tab’s ID to the URL:

+ +
src=http://metabase.yourcompany.com/dashboard/entity/Dc_7X8N7zf4iDK9Ps1M3b?tab=YLNdEYtzuSMA0lqO7u3FD
+
+ +

You can use a dashboard’s sequential ID, but you should prefer the Entity ID, as Entity IDs are stable across different Metabase environments (e.g., if you’re testing on a staging environment, the Entity IDs will remain the same when exporting the data and importing it into a production environment).

+ +

If you want to point to a question, collection, or model, visit the item, click on its info, grab the item’s Entity ID and follow the url structure: /[Item type]/entity/[Entity-Id]. Examples:

+ +
    +
  • /collection/entity/[Entity ID]
  • +
  • /model/entity/[Entity ID]
  • +
  • /question/entity/[Entity ID]
  • +
+ +

Pointing an iframe to an authentication endpoint

+ +

Use this option if you want to send people directly to your SSO login screen (i.e., skip over the Metabase login screen with an SSO button), and redirect to Metabase automatically upon authentication.

+ +

You’ll need to set the src attribute to your auth endpoint, with a return_to parameter pointing to the encoded Metabase URL. For example, to send people to your SSO login page and automatically redirect them to http://metabase.yourcompany.com/dashboard/1:

+ +
https://metabase.example.com/auth/sso?return_to=http%3A%2F%2Fmetabase.yourcompany.com%2Fdashboard%2F1
+
+ +

If you’re using JWT, you can use the relative path for the redirect (i.e., your Metabase URL without the site URL). For example, to send people to a Metabase page at /dashboard/1:

+ +
https://metabase.example.com/auth/sso?jwt=<token>&return_to=%2Fdashboard%2F1
+
+ +

You must URL encode (or double encode, depending on your web setup) all of the parameters in your redirect link, including parameters for filters (e.g., filter=value) and UI settings (e.g., top_nav=true). For example, if you added two filter parameters to the JWT example shown above, your src link would become:

+ +
https://metabase.example.com/auth/sso?jwt=<token>&redirect=%2Fdashboard%2F1%3Ffilter1%3Dvalue%26filter2%3Dvalue
+
+ +

Cross-browser compatibility

+ +

To make sure that your embedded Metabase works in all browsers, put Metabase and the embedding app in the same top-level domain (TLD). The TLD is indicated by the last part of a web address, like .com or .org.

+ +

Note that your interactive embed must be compatible with Safari to run on any browser in iOS (such as Chrome on iOS).

+ +

Embedding Metabase in a different domain

+ +
+

Skip this section if your Metabase and embedding app are already in the same top-level domain (TLD).

+
+ +

If you want to embed Metabase in another domain (say, if Metabase is hosted at metabase.yourcompany.com, but you want to embed Metabase at yourcompany.github.io), you can tell Metabase to set the session cookie’s SameSite value to “none”.

+ +

You can set session cookie’s SameSite value in Admin settings > Embedding > Interactive embedding > SameSite cookie setting.

+ +

SameSite values include:

+ +
    +
  • Lax (default): Allows cookies to be sent when someone navigates to the origin site from an external site (like when following a link).
  • +
  • None: Allows all cross-site requests. Incompatible with most Safari and iOS browsers, such as Chrome on iOS. If you set this environment variable to “None”, you must use HTTPS in Metabase to prevent browsers from rejecting the request.
  • +
  • Strict (not recommended): Never allows cookies to be sent on a cross-site request. Warning: this will prevent users from following external links to Metabase.
  • +
+ +

You can also set the MB_SESSION_COOKIE_SAMESITE environment variable.

+ +

If you’re using Safari, you’ll need to allow cross-site tracking. Depending on the browser, you may also run into issues when viewing emdedded items in private/incognito tabs.

+ +

Learn more about SameSite cookies.

+ +

Securing interactive embeds

+ +

Metabase uses HTTP cookies to authenticate people and keep them signed into your embedded Metabase, even when someone closes their browser session. If you enjoy diagrammed auth flows, check out Interactive embedding with SSO.

+ +

To limit the amount of time that a person stays logged in, set MAX_SESSION_AGE to a number in minutes. The default value is 20,160 (two weeks).

+ +

For example, to keep people signed in for 24 hours at most:

+ +
MAX_SESSION_AGE=1440
+
+ +

To automatically clear a person’s login cookies when they end a browser session:

+ +
MB_SESSION_COOKIES=true
+
+ +

To manually log someone out of Metabase, load the following URL (for example, in a hidden iframe on the logout page of your application):

+ +
https://metabase.yourcompany.com/auth/logout
+
+ +

If you’re using JWT for SSO, we recommend setting the exp (expiration time) property to a short duration (e.g., 1 minute).

+ +

Supported postMessage messages from embedded Metabase

+ +

To keep up with changes to an embedded Metabase URL (for example, when a filter is applied), set up your app to listen for “location” messages from the embedded Metabase. If you want to use this message for deep-linking, note that “location” mirrors “window.location”.

+ +
{
+  "metabase": {
+    "type": "location",
+    "location": LOCATION_OBJECT_OR_URL
+  }
+}
+
+ +

To make an embedded Metabase page (like a question) fill up the entire iframe in your app, set up your app to listen for a “frame” message with “normal” mode from Metabase:

+ +
{
+  "metabase": {
+    "type": "frame",
+    "frame": {
+      "mode": "normal"
+    }
+  }
+}
+
+ +

To specify the size of an iframe in your app so that it matches an embedded Metabase page (such as a dashboard), set up your app to listen for a “frame” message with “fit” mode from Metabase:

+ +
{
+  "metabase": {
+    "type": "frame",
+    "frame": {
+      "mode": "fit",
+      "height": HEIGHT_IN_PIXELS
+    }
+  }
+}
+
+ +

Supported postMessage messages to embedded Metabase

+ +

To change an embedding URL, send a “location” message from your app to Metabase:

+ +
{
+  "metabase": {
+    "type": "location",
+    "location": LOCATION_OBJECT_OR_URL
+  }
+}
+
+ +

Group strategies with sandboxing

+ +

If you want multiple people from a single customer account to collaborate on questions and dashboards, you’ll need to set up one group per customer account.

+ +

You can handle data sandboxing with a single, separate group that just sandboxes your data. For example, each person could be part of a customer group that sets up data permissions with sandboxing via a certain attribute that applies to everyone across all your customer accounts.

+ +

Additionally, each person within a single customer account could also be a member of a group specific to that customer account. That way they can collaborate on collections with other people in their organization, without seeing stuff created by people from other customers’ accounts.

+ +

Showing or hiding Metabase UI components

+ +

To change the interface of your interactive embed, you can add parameters to the end of your embedding URL. If you want to change the colors or fonts in your embed, see Customizing appearance.

+ +

For example, you can disable Metabase’s top nav bar and side nav menu like this:

+ +
your_embedding_url?top_nav=false&side_nav=false
+
+ +

Top nav and side nav disabled

+ +

Options include:

+ + + +
+

To make sure that query parameters are preserved when using click behavior, configure the Site URL Admin setting to be your Metabase server URL.

+
+ +

action_buttons

+ +

Visible by default on question pages when the header is enabled.

+ +

To hide the action buttons such as Filter, Summarize, the query builder button, and so on:

+ +
header=false&action_buttons=false
+
+ +

Action buttons

+ +

additional_info

+ +

Visible by default on question and dashboard pages, when the header is enabled.

+ +

To hide the gray text “Edited X days ago by FirstName LastName”, as well as the breadcrumbs with collection, database, and table names:

+ +

header=false&additional_info=false

+ +

Additional info

+ + + +

Shown by default in the top nav bar. Collection breadcrumbs show the path to the item (i.e., the collection(s) the item is in). To hide the breadcrumbs:

+ +
breadcrumbs=false
+
+ + + +

Visible by default on question and dashboard pages.

+ +

To hide a question or dashboard’s title, additional info, and action buttons:

+ +

header=false

+ +

locale

+ +

You can change the language of the user interface via a parameter. For example, to set the locale to Spanish:

+ +
locale=es
+
+ +

Read more about localization.

+ + + +

Whether to show the logo that opens and closes the sidebar nav. Default is true. How Metabase displays the logo depends on the side_nav setting. Here’s a rough breakdown of how these two parameters interact:

+ +

If logo=true and:

+ +
    +
  • side_nav=true: Looks like regular Metabase (with whatever logo you have set).
  • +
  • side_nav=false: There is no sidebar, so nothing happens when you hover over the logo.
  • +
+ +

If logo=false and:

+ +
    +
  • side_nav=true: Metabase shows the generic sidebar icon, with a gray color in normal state, and a brand color on hover.
  • +
  • side_nav=false: There is no side nav nor logo, so the breadcrumbs move all the way to the left of the screen.
  • +
+ +

new_button

+ +

Hidden by default. To show the + New button used to create queries or dashboards:

+ +
top_nav=true&new_button=true
+
+ + + +

Hidden by default. To show the search box in the top nav:

+ +
top_nav=true&search=true
+
+ +

side_nav

+ +

The navigation sidebar is shown on /collection and home page routes, and hidden everywhere else by default.

+ +

To allow people to minimize the sidebar:

+ +
top_nav=true&side_nav=true
+
+ +

Side nav

+ +

top_nav

+ +

Shown by default. To hide the top navigation bar:

+ +
top_nav=false
+
+ +

Top nav bar

+ +

search, new_button, and breadcrumbs all depend on top_nav being set to true. If these three children (search, new_button, and breadcrumbs) are all false, Metabase will hide the top nav bar.

+ +

Reference apps

+ +

To build a sample interactive embed using SSO with JWT, see our reference apps:

+ + + +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/introduction.html b/_site/docs/doc-update-detection/embedding/introduction.html new file mode 100644 index 000000000..9c8d0ac58 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/introduction.html @@ -0,0 +1,3199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedding introduction | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedding introduction

+ +

You can embed Metabase tables, charts, and dashboards—even Metabase’s query builder—in your website or application.

+ +

Here are the different ways you can embed Metabase.

+ + + +

Embedded analytics SDK with React

+ +

With the Embedded analytics SDK, you can embed individual Metabase components with React (like standalone charts, dashboards, the query builder, and more). You can manage access and interactivity per component, and you have advanced customization for seamless styling.

+ +

When to use the Embedded analytics SDK: you want the most control over how you embed Metabase in your React app.

+ +

Interactive embedding

+ +

Interactive embedding is the only kind of embedding that integrates with SSO and data permissions to enable true self-service access to the underlying data.

+ +

When to use interactive embedding: you want to offer multi-tenant, self-service analytics. With interactive embedding, people can create their own questions, dashboards, models, and more, all in their own data sandbox.

+ +

Static embedding

+ +

Also known as signed embedding, static embedding is a secure way to embed charts and dashboards.

+ +

When to use static embedding: you don’t want to offer ad-hoc querying or chart drill-through. To filter data relevant to the viewer, you can use static embeds with locked parameters.

+ + + +

If you’d like to share your data with the good people of the internet, admins can create a public link or embed a question or dashboard directly in your website.

+ +

When to use public links and embeds: public links and embeds are good for one-off charts and dashboards. Admins can use them when you just need to show someone a chart or dashboard without giving people access to your Metabase. And you don’t care who sees the data; you want to make those stats available to everyone.

+ +

Comparison of embedding types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ActionEmbedded analytics SDKInteractiveStaticPublic
Display charts and dashboards
Display interactive filter widgets
Export results*
Restrict data with locked filters
Restrict data with sandboxes
Use the drill-through menu
Self-serve via query builder
View usage of embeds with usage analytics
Actions on dashboards
Embed individual Metabase components
Manage access and interactivity per component
+ +

* Each embedding type allows data downloads by default, but only Pro and Enterprise plans can disable data downloads.

+ +

Switching from static to interactive embedding

+ +

Interactive embedding requires authentication via single sign-on (SSO), so you’ll need to set that up both in your Metabase and in your application’s server. Check out our Interactive embedding quick start.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/public-links.html b/_site/docs/doc-update-detection/embedding/public-links.html new file mode 100644 index 000000000..96e1c41c2 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/public-links.html @@ -0,0 +1,3234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Public sharing | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Public sharing

+ +
+

Only admins can create public links and iframes.

+
+ +

Admins can create and share public links (URLs) for questions and dashboards. People can view them as standalone destinations (URLs) or as embedded iframes in another page or app. In both cases, the public item will display static (view-only) results of your question or dashboard, so visitors won’t be able to drill-down into the underlying data on their own.

+ + + +

Create a public link for a question

+ +

To create a public link for a question, admins can click on the Sharing icon at the top right of a question and select Create a public link. Copy the link and test it out by viewing the link in a private/incognito browser session.

+ + + +

This export option is only available for questions, not dashboards.

+ +

To create a public link that people can use to download the results of a question:

+ +
    +
  1. Click on the Sharing icon for the question.
  2. +
  3. Select Create a public link.
  4. +
  5. Click on the file format you want (below the Public link URL): CSV, XLSX, or JSON.
  6. +
+ +

Public export

+ +

Open the public link in a new tab to test the download.

+ + + +

To share a dashboard via a public link, admins can click on the Sharing button in the top right menu.

+ +

Sharing a dashboard

+ +

To embed a dashboard, see static embedding.

+ +

Exporting raw, unformatted question results

+ +

To export the raw, unformatted rows, you’ll need to append ?format_rows=false to the URL Metabase generates. For example, if you create a public link for a CSV download, the URL would look like:

+ +
https://www.example.com/public/question/cf347ce0-90bb-4669-b73b-56c73edd10cb.csv?format_rows=false
+
+ +

By default, Metabase will export the results of a question that include any formatting you added (for example, if you formatted a column with floats to display as a percentage (0.42 -> 42%)).

+ +

See docs for the export format endpoint.

+ + + +

Metabase’s automatic drill-through won’t work on public dashboards because public links don’t give people access to your raw data.

+ +

You can simulate drill-through on a public dashboard by setting up a custom click behavior that sends people from one public link to another public link.

+ +
    +
  1. Create a second dashboard to act as the destination dashboard.
  2. +
  3. Create a public link for the destination dashboard.
  4. +
  5. Copy the destination dashboard’s public link.
  6. +
  7. On your primary dashboard, create a custom destination with type “URL”.
  8. +
  9. Set the custom destination to the destination dashboard’s public link.
  10. +
  11. Optional: pass a filter value from the primary dashboard to the destination dashboard by adding a query parameter to the end of the destination URL:
  12. +
+ +

+/public/dashboard/?child_filter_name={{parent_column_name}}
+
+
+ +

For example, if you have a primary public dashboard that displays Invoices data, you can pass the Plan name (on click) to a destination public dashboard that displays Accounts data:

+ +

Public link with custom destination

+ +

Public embeds

+ +

Public embed

+ +

If you want to embed your question or dashboard as an iframe in a simple web page or app:

+ +
    +
  1. Click on the Sharing icon for your question or dashboard.
  2. +
  3. Click Embed.
  4. +
  5. In the bottom of the embedding popup, click on Get embedding code.
  6. +
  7. Copy the iframe snippet Metabase generates for you.
  8. +
  9. Paste the iframe snippet in your destination of choice.
  10. +
+ +

To customize the appearance of your question or dashboard, you can update the link in the src attribute with public embed parameters.

+ +

Public embed parameters

+ +

To apply appearance or filter settings to your public embed, you can add parameters to the end of the link in your iframe’s src attribute.

+ +

Note that it’s possible to find the public link URL behind a public embed. If someone gets access to the public link URL, they can remove the parameters from the URL to view the original question or dashboard (that is, without any appearance or filter settings).

+ +

If you’d like to create a secure embed that prevents people from changing filter names or values, check out static embedding.

+ +

Appearance parameters

+ +

To toggle appearance settings, add hash parameters to the end of the public link in your iframe’s src attribute.

+ +

See appearance parameters.

+ +

Filter parameters

+ +

You can display a filtered view of your question or dashboard in a public embed. Make sure you’ve set up a question filter or dashboard filter first.

+ +

To apply a filter to your embedded question or dashboard, add a query parameter to the end of the link in your iframe’s src attribute, like this:

+ +
/dashboard/42?filter_name=value
+
+ +

For example, say that we have a dashboard with an “ID” filter. We can give this filter a value of 7:

+ +
/dashboard/42?id=7
+
+ +

To set the “ID” filter to a value of 7 and hide the “ID” filter widget from the public embed:

+ +
/dashboard/42?id=7#hide_parameters=id
+
+ +

To specify multiple values for filters, separate the values with ampersands (&), like this:

+ +
/dashboard/42?id=7&name=janet
+
+ +

You can hide multiple filter widgets by separating the filter names with commas, like this:

+ +
/dashboard/42#hide_parameters=id,customer_name
+
+ +

Note that the name of the filter in the URL should be specified in lower case, and with underscores instead of spaces. If your filter is called “Filter for User ZIP Code”, you’d write:

+ +
/dashboard/42?filter_for_user_zip_code=02116
+
+ +

Disable public sharing

+ +

Public sharing is enabled by default.

+ +

Enable public sharing

+ +

To disable public sharing:

+ +
    +
  1. Click on the Gear icon in the upper right.
  2. +
  3. Select Admin settings.
  4. +
  5. In the Settings tab, select Public sharing.
  6. +
  7. Toggle off Public sharing.
  8. +
+ +

Once toggled on, the Public sharing section will display Metabase questions, dashboards, and actions with active public links.

+ +

If you disable public sharing, then re-enable public sharing, all your previously generated public links will still work (as long as you didn’t deactivate them).

+ + + + + +
    +
  1. Visit the question or dashboard.
  2. +
  3. Click on Sharing icon.
  4. +
  5. Select Public link or Embed.
  6. +
  7. Click Remove public link.
  8. +
+ + + +

Admins can view and deactivate all public links for a Metabase.

+ +
    +
  1. Click on the gear icon in the upper right.
  2. +
  3. Select Admin settings.
  4. +
  5. Go to the Settings tab.
  6. +
  7. Go to the Public sharing tab in the left sidebar.
  8. +
  9. For each item you want to deactivate, click on the X to revoke its public link.
  10. +
+ +

See all publicly shared content

+ +

Admins can see all publicly shared questions, dashboards, and actions in Admin Settings > Public Sharing.

+ +

See shared content

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/appearance.html b/_site/docs/doc-update-detection/embedding/sdk/appearance.html new file mode 100644 index 000000000..c4cb04ddc --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/appearance.html @@ -0,0 +1,3281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - appearance | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - appearance

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +

You can style your embedded Metabase components with a theme.

+ +

Here’s an example that includes the various styling options available:

+ +
import { defineMetabaseTheme } from "@metabase/embedding-sdk-react";
+
+const theme = defineMetabaseTheme({
+  // Specify a font to use from the set of fonts supported by Metabase.
+  // You can set the font to "Custom" to use the custom font
+  // configured in your Metabase instance.
+  fontFamily: "Lato",
+
+  // Override the base font size for every component.
+  // This does not usually need to be set, as the components
+  // inherit the font size from the parent container, such as the body.
+  fontSize: "16px",
+
+  // Override the base line height for every component.
+  lineHeight: 1.5,
+
+  // Match your application's color scheme
+  colors: {
+    // The primary color of your application
+    brand: "#9B5966",
+
+    // Lighter variation of the brand color. Used for hover and accented elements.
+    "brand-hover": "#DDECFA",
+
+    // Lightest variation of the brand color. Used for hover and accented elements.
+    "brand-hover-light": "#EEF6FC",
+
+    // The color of text that is most prominent
+    "text-primary": "#4C5773",
+
+    // The color of text that is less prominent
+    "text-secondary": "#696E7B",
+
+    // The color of text that is least prominent
+    "text-tertiary": "#949AAB",
+
+    // Default background color
+    background: "#FFFFFF",
+
+    // Slightly muted background color.
+    "background-secondary": "#EDF2F5",
+
+    // Slightly darker background color used for hover and accented elements
+    "background-hover": "#F9FBFC",
+
+    // Muted background color used for disabled elements, such as disabled buttons and inputs.
+    "background-disabled": "#F3F5F7",
+
+    // Color used for borders
+    border: "#EEECEC",
+
+    // Color used for filters context
+    filter: "#7172AD",
+
+    // Color used for aggregations and breakouts context
+    summarize: "#88BF4D",
+
+    // Color used to indicate successful actions and positive values/trends
+    positive: "#BADC58",
+
+    // Color used to indicate dangerous actions and negative values/trends
+    negative: "#FF7979",
+
+    /** Color used for popover shadows */
+    shadow: "rgba(0,0,0,0.08)",
+
+    // Overrides the chart colors. Supports up to 8 colors
+    // Limitation: this does not affect charts with custom series color
+    charts: [
+      // can either be a hex code
+      "#9B59B6",
+
+      // or a color object. tint and shade represents lighter and darker variations
+      // only base color is required, while tint and shade are optional
+      { base: "#E74C3C", tint: "#EE6B56", shade: "#CB4436" },
+    ],
+  },
+
+  components: {
+    // Dashboard
+    dashboard: {
+      // Background color for all dashboards
+      backgroundColor: "#2F3640",
+
+      // Border color of the dashboard grid, shown only when editing dashboards.
+      // Defaults to `colors.border`
+      gridBorderColor: "#EEECEC",
+
+      card: {
+        // Background color for all dashboard cards
+        backgroundColor: "#2D2D30",
+
+        // Apply a border color instead of shadow for dashboard cards.
+        // Unset by default.
+        border: "1px solid #EEECEC",
+      },
+    },
+
+    // Question
+    question: {
+      // Background color for all questions
+      backgroundColor: "#2E353B",
+
+      // Toolbar of the default interactive question layout
+      toolbar: {
+        backgroundColor: "#F3F5F7",
+      },
+    },
+
+    // Tooltips
+    tooltip: {
+      // Tooltip text color.
+      textColor: "#FFFFFF",
+
+      // Secondary text color shown in the tooltip, e.g. for tooltip headers and percentage changes.
+      secondaryTextColor: "#949AAB",
+
+      // Tooltip background color.
+      backgroundColor: "#2E353B",
+
+      // Tooltip background color for focused rows.
+      focusedBackgroundColor: "#0A0E10",
+    },
+
+    // Data table
+    table: {
+      cell: {
+        // Text color of cells, defaults to `text-primary`
+        textColor: "#4C5773",
+
+        // Default background color of cells, defaults to `background`
+        backgroundColor: "#FFFFFF",
+
+        // Font size of cell values, defaults to ~12.5px
+        fontSize: "12.5px",
+      },
+
+      idColumn: {
+        // Text color of ID column, defaults to `brand`
+        textColor: "#9B5966",
+
+        // Background color of ID column, defaults to a lighter shade of `brand`
+        backgroundColor: "#F5E9EB",
+      },
+    },
+
+    // Number chart
+    number: {
+      // Value displayed on number charts.
+      // This also applies to the primary value in trend charts.
+      value: {
+        fontSize: "24px",
+        lineHeight: "21px",
+      },
+    },
+
+    // Cartesian chart
+    cartesian: {
+      // Padding around the cartesian charts.
+      // Uses CSS's `padding` property format.
+      padding: "4px 8px",
+    },
+
+    // Pivot table
+    pivotTable: {
+      cell: {
+        // Font size of cell values, defaults to ~12px
+        fontSize: "12px",
+      },
+
+      // Pivot row toggle to expand or collapse row
+      rowToggle: {
+        textColor: "#FFFFFF",
+        backgroundColor: "#95A5A6",
+      },
+    },
+
+    collectionBrowser: {
+      breadcrumbs: {
+        expandButton: {
+          textColor: "#8118F4",
+          backgroundColor: "#767D7C",
+          hoverTextColor: "#CE8C8C",
+          hoverBackgroundColor: "#69264B",
+        },
+      },
+    },
+
+    // Popover are used in components such as click actions in interactive questions.
+    popover: {
+      // z-index of the popover. Useful for embedding components in a modal. defaults to 4.
+      zIndex: 4,
+    },
+  },
+});
+
+ +

Customizing loader and error components

+ +

You can provide your own components for loading and error states by specifying loaderComponent and errorComponent as props to MetabaseProvider.

+ +
import {
+  MetabaseProvider,
+  StaticDashboard,
+} from "@metabase/embedding-sdk-react";
+
+<MetabaseProvider
+  loaderComponent={() => <div>Analytics is loading...</div>}
+  errorComponent={({ message }) => <div>There was an error: {message}</div>}
+>
+  <StaticDashboard dashboardId={1} />
+</MetabaseProvider>
+
+ +

Limitations

+ +

Colors configured in a question’s visualization settings will override theme colors.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/authentication.html b/_site/docs/doc-update-detection/embedding/sdk/authentication.html new file mode 100644 index 000000000..a3b0b9732 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/authentication.html @@ -0,0 +1,3289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - authentication | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - authentication

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +

For using the SDK in production, you’ll need to set up authentication with JWT SSO.

+ +

If you’re developing locally, you can also set up authentication with API keys.

+ +

Setting up JWT SSO

+ +

Prerequisites:

+ + + +

To set up JWT SSO with Metabase and your app, you’ll need to:

+ +
    +
  1. Enable JWT SSO in your Metabase
  2. +
  3. Add a new endpoint to your backend to handle authentication
  4. +
  5. Wire the SDK in your frontend to your new endpoint
  6. +
+ +

1. Enable JWT SSO in your Metabase

+ +
    +
  1. Configure JWT by going to Admin Settings > Settings > Authentication and clicking on Setup
  2. +
  3. Generate a key and copy it to your clipboard.
  4. +
+ +

2. Add a new endpoint to your backend to handle authentication

+ +

You’ll need add a library to your backend to sign your JSON Web Tokens.

+ +

For Node.js, we recommend jsonwebtoken:

+ +
npm install jsonwebtoken --save
+
+ +

Next, set up your endpoint: this example code for Node.js sets up an endpoint in an app, /sso/metabase, that creates a token using the shared secret to authenticate calls to Metabase.

+ +
import express from "express";
+import cors from "cors";
+import session from "express-session";
+import jwt from "jsonwebtoken";
+import fetch from "node-fetch";
+
+// Replace this with your Metabase URL
+const METABASE_INSTANCE_URL = "YOUR_METABASE_URL_HERE";
+// Replace this with the JWT signing secret you generated when enabling
+// JWT SSO in your Metabase.
+const METABASE_JWT_SHARED_SECRET = "YOUR_SECRET_HERE";
+
+const app = express();
+
+app.get("/sso/metabase", async (req, res) => {
+  // Usually, you would grab the user from the current session
+  // Here it's hardcoded for demonstration purposes
+  // Example:
+  // const { user } = req.session;
+  const user = {
+    email: "rene@example.com",
+    firstName: "Rene",
+    lastName: "Descartes",
+    group: "Customer",
+  };
+
+  if (!user) {
+    console.log("no user");
+    res.status(401).json({
+      status: "error",
+      message: "not authenticated",
+    });
+
+    return;
+  }
+
+  const token = jwt.sign(
+    {
+      email: user.email,
+      first_name: user.firstName,
+      last_name: user.lastName,
+      groups: [user.group],
+      exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration
+    },
+    METABASE_JWT_SHARED_SECRET,
+  );
+  const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`;
+  console.log("Hitting MB SSO endpoint", ssoUrl);
+
+  try {
+    const response = await fetch(ssoUrl, { method: "GET" });
+    const session = await response.text();
+
+    console.log("Received session", session);
+    res.status(200).set("Content-Type", "application/json").end(session);
+  } catch (error) {
+    if (error instanceof Error) {
+      res.status(401).json({
+        status: "error",
+        message: "authentication failed",
+        error: error.message,
+      });
+    }
+  }
+});
+
+ +

3. Wire the SDK in your frontend to your new endpoint

+ +

Update the SDK config in your frontend code to point your backend’s authentication endpoint.

+ +
const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://your-metabase.example.com", // Required: Your Metabase instance URL
+  authProviderUri: "https://your-app.example.com/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session
+});
+
+ +

(Optional) If you use headers instead of cookies to authenticate calls from your frontend to your backend, you’ll need to use a custom fetch function.

+ +

If your frontend and backend don’t share a domain, you need to enable CORS

+ +

You can add some middleware in your backend to handle cross-domain requests.

+ +
// Middleware
+
+// If your FE application is on a different domain from your BE, you need to enable CORS
+// by setting Access-Control-Allow-Credentials to true and Access-Control-Allow-Origin
+// to your FE application URL.
+//
+// Limitation: We currently only support setting one origin in Authorized Origins in Metabase for CORS.
+app.use(
+  cors({
+    credentials: true,
+  }),
+);
+
+app.use(
+  session({
+    secret: SESSION_SECRET,
+    resave: false,
+    saveUninitialized: true,
+    cookie: { secure: false },
+  }),
+);
+
+app.use(express.json());
+
+// routes
+app.get("/sso/metabase", metabaseAuthHandler);
+app.listen(PORT, () => {
+  console.log(`API running at http://localhost:${PORT}`);
+});
+
+ +

Getting Metabase authentication status

+ +

You can query the Metabase authentication status using the useMetabaseAuthStatus hook. This is useful if you want to completely hide Metabase components when the user is not authenticated.

+ +

This hook can only be used within components wrapped by MetabaseProvider.

+ +
const auth = useMetabaseAuthStatus();
+
+if (auth.status === "error") {
+  return <div>Failed to authenticate: {auth.error.message}</div>;
+}
+
+if (auth.status === "success") {
+  return <InteractiveQuestion questionId={110} />;
+}
+
+ +

Customizing JWT authentication

+ +

You can customize how the SDK fetches the refresh token by specifying the fetchRefreshToken function with the defineMetabaseAuthConfig function:

+ +
// Pass this configuration to MetabaseProvider.
+// Wrap the fetchRequestToken function in useCallback if it has dependencies to prevent re-renders.
+const authConfig = defineMetabaseAuthConfig({
+  fetchRequestToken: async url => {
+    const response = await fetch(url, {
+      method: "GET",
+      headers: { Authorization: `Bearer ${yourToken}` },
+    });
+
+    return await response.json();
+  },
+  metabaseInstanceUrl: "http://localhost:3000",
+  authProviderUri: "http://localhost:9090/sso/metabase",
+});
+
+ +

Security warning: each end-user must have their own Metabase account

+ +

Each end-user must have their own Metabase account.

+ +

The problem with having end-users share a Metabase account is that, even if you filter data on the client side via the SDK, all end-users will still have access to the session token, which they could use to access Metabase directly via the API to get data they’re not supposed to see.

+ +

If each end-user has their own Metabase account, however, you can configure permissions in Metabase and everyone will only have access to the data they should.

+ +

In addition to this, we consider shared accounts to be unfair usage. Fair usage of the SDK involves giving each end-user of the embedded analytics their own Metabase account.

+ +

Authenticating locally with API keys

+ +
+

The Embedded analytics SDK only supports JWT authentication in production. Authentication with API keys is only supported for local development and evaluation purposes.

+
+ +

For developing locally to try out the SDK, you can authenticate using an API key.

+ +

First, create an API key.

+ +

Then you can then use the API key to authenticate with Metabase in your application. All you need to do is include your API key in the config object using the key: apiKey.

+ +
import {
+  MetabaseProvider,
+  defineMetabaseAuthConfig,
+} from "@metabase/embedding-sdk-react";
+
+const authConfigApiKey = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://metabase.example.com",
+  apiKey: "YOUR_API_KEY",
+});
+
+export default function App() {
+  return (
+    <MetabaseProvider authConfig={authConfigApiKey} className="optional-class">
+      Hello World!
+    </MetabaseProvider>
+  );
+}
+
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/collections.html b/_site/docs/doc-update-detection/embedding/sdk/collections.html new file mode 100644 index 000000000..bd395167b --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/collections.html @@ -0,0 +1,3129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - collections | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - collections

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +

You can embed Metabase’s collection browser so that people can explore items in your Metabase from your application.

+ +

CollectionBrowser props

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
collectionIdnumber \| 'root' \| 'personal'The numerical ID of the collection, “personal” for the user’s personal collection, or “root” for the root collection. You can find this ID in the URL when accessing a collection in your Metabase instance. For example, the collection ID in http://localhost:3000/collection/1-my-collection would be 1. Defaults to “personal”
onClick(item: CollectionItem) => voidAn optional click handler that emits the clicked entity.
pageSizenumberThe number of items to display per page. The default is 25.
visibleEntityTypes["question", "model", "dashboard", "collection"]The types of entities that should be visible. If not provided, all entities will be shown.
+ +

Example embedding code with CollectionBrowser

+ +
import React from "react";
+import { CollectionBrowser } from "@metabase/embedding-sdk-react";
+
+export default function App() {
+  const collectionId = 123; // This is the collection ID you want to browse
+  const handleItemClick = item => {
+    console.log("Clicked item:", item);
+  };
+
+  return (
+    <CollectionBrowser
+      collectionId={collectionId}
+      onClick={handleItemClick}
+      pageSize={10}
+      // Define the collection item types you want to be visible
+      visibleEntityTypes={["dashboard", "question", "collection"]}
+    />
+  );
+}
+
+ +

Hide the collection picker and hard code the collection you want people to save stuff to

+ +

With static questions, you set a specific collection as the collection people can save items to, so that they don’t have bother picking a collection. To hard-code a collection:

+ +
    +
  1. Set isSaveEnabled to true.
  2. +
  3. Set targetCollection to the collection ID you want people to save items to.
  4. +
+ +

For more options, see Question props.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/config.html b/_site/docs/doc-update-detection/embedding/sdk/config.html new file mode 100644 index 000000000..4932e71cc --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/config.html @@ -0,0 +1,3195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - config | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - config

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +

To use the SDK in your app, you need to import the MetabaseProvider component and provide it with an authConfig object, like so:

+ +
const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL
+  authProviderUri: "https://app.example.com/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session
+});
+
+export default function App() {
+  return (
+    <MetabaseProvider
+      authConfig={authConfig}
+      theme={theme}
+      className="optional-class"
+    >
+      Hello World!
+    </MetabaseProvider>
+  );
+}
+
+ +

You can also pass additional props to MetabaseProvider:

+ +
    +
  • authConfig (Required). Defines how to authenticate with Metabase.
  • +
  • theme (Optional) See Appearance.
  • +
  • pluginsConfig (Optional). See Plugins.
  • +
  • eventHandlers (Optional). See Global event handlers.
  • +
  • className (Optional). Classes to be added to the wrapper element.
  • +
  • locale (Optional). Defines the display language. Accepts an ISO language code such as en or de.
  • +
  • loaderComponent (Optional). A custom loader component to display while the SDK is loading.
  • +
  • errorComponent (Optional). A custom error component to display when the SDK encounters an error.
  • +
  • allowConsoleLog (Optional). If true, log messages will be printed to the console.
  • +
+ +

Example config object passed to MetabaseProvider

+ +
import React from "react";
+import {
+  MetabaseProvider,
+  defineMetabaseAuthConfig,
+  defineMetabaseTheme,
+} from "@metabase/embedding-sdk-react";
+
+// Configure authentication
+const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL
+  authProviderUri: "https://app.example.com/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session
+});
+
+// See the "Customizing appearance" section for more information
+const theme = defineMetabaseTheme({
+  // Optional: Specify a font to use from the set of fonts supported by Metabase
+  fontFamily: "Lato",
+
+  // Optional: Match your application's color scheme
+  colors: {
+    brand: "#9B5966",
+    "text-primary": "#4C5773",
+    "text-secondary": "#696E7B",
+    "text-tertiary": "#949AAB",
+  },
+});
+
+export default function App() {
+  return (
+    <MetabaseProvider
+      authConfig={authConfig}
+      theme={theme}
+      className="optional-class"
+    >
+      Hello World!
+    </MetabaseProvider>
+  );
+}
+
+ +

Global event handlers

+ +

MetabaseProvider also supports eventHandlers.

+ +

Currently, we support:

+ +
    +
  • onDashboardLoad?: (dashboard: Dashboard | null) => void;. Triggers when a dashboard loads with all visible cards and their content
  • +
  • onDashboardLoadWithoutCards?: (dashboard: Dashboard | null) => void;. Triggers after a dashboard loads, but without its cards (at this stage only the dashboard title, tabs, and cards grid are rendered, but the contents of the cards have yet to load.
  • +
+ +
const handleDashboardLoad: SdkDashboardLoadEvent = dashboard => {
+  /* do whatever you need to do - e.g. send analytics events, show notifications */
+};
+
+const eventHandlers = {
+  onDashboardLoad: handleDashboardLoad,
+  onDashboardLoadWithoutCards: handleDashboardLoad,
+};
+
+return (
+  <MetabaseProvider authConfig={authConfig} eventHandlers={eventHandlers}>
+    {children}
+  </MetabaseProvider>
+);
+
+ +

Reloading Metabase components

+ +

In case you need to reload a Metabase component, for example, your users modify your application data and that data is used to render a question in Metabase. If you embed this question and want to force Metabase to reload the question to show the latest data, you can do so by using the key prop to force a component to reload.

+ +
// Inside your application component
+const [data, setData] = useState({});
+// This is used to force reloading Metabase components
+const [counter, setCounter] = useState(0);
+
+// This ensures we only change the `data` reference when it's actually changed
+const handleDataChange = newData => {
+  setData(prevData => {
+    if (isEqual(prevData, newData)) {
+      return prevData;
+    }
+
+    return newData;
+  });
+};
+
+useEffect(() => {
+  /**
+   * When you set `data` as the `useEffect` hook's dependency, it will trigger the effect
+   * and increment the counter which is used in a Metabase component's `key` prop, forcing it to reload.
+   */
+  if (data) {
+    setCounter(counter => counter + 1);
+  }
+}, [data]);
+
+return <InteractiveQuestion key={counter} questionId={yourQuestionId} />;
+
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/dashboards.html b/_site/docs/doc-update-detection/embedding/sdk/dashboards.html new file mode 100644 index 000000000..cc01154d9 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/dashboards.html @@ -0,0 +1,3411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - dashboards | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - dashboards

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +

You can embed an interactive, editable, or static dashboard.

+ +

Please keep in mind - embedding multiple instances of dashboards on the same page is not yet supported.

+ +

Embedding a dashboard

+ +

You can embed a dashboard using the one of the dashboard components:

+ +
    +
  • StaticDashboard
  • +
+ +

A lightweight dashboard component. Use this component when you want to display results without letting people interact with the data.

+ +
    +
  • InteractiveDashboard
  • +
+ +

A dashboard component with drill downs, click behaviors, and the ability to view and click into questions. Use this component when you want to allow people to explore their data.

+ +
    +
  • EditableDashboard
  • +
+ +

A dashboard component with the features available in the InteractiveDashboard component, as well as the ability to add and update questions, layout, and content within your dashboard. Use this component when you want to give people the ability to modify your dashboards, for example in an admin panel in your app.

+ +

Dashboard component props

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
dashboardIdnumber \| stringThe ID of the dashboard. This is either:
- the numerical ID when accessing a dashboard link, i.e. http://localhost:3000/dashboard/1-my-dashboard where the ID is 1
- the string ID found in the entity_id key of the dashboard object when using the API directly or using the SDK Collection Browser to return data
initialParameters**Record<string, string \| string[]>Query parameters for the dashboard. For a single option, use a string value, and use a list of strings for multiple options.
withTitlebooleanWhether the dashboard should display a title.
withCardTitlebooleanWhether the dashboard cards should display a title.
withDownloadsboolean \| nullWhether to hide the download button.
hiddenParameters**string[] \| nullA list of parameters to hide.
drillThroughQuestionHeight*number \| nullHeight of a question component when drilled from the dashboard to a question level.
questionPlugins*{ mapQuestionClickActions: Function } \| nullAdditional mapper function to override or add drill-down menu. See the implementing custom actions section for more details.
onLoad(dashboard: Dashboard \| null) => voidEvent handler that triggers after dashboard loads with all visible cards and their content.
onLoadWithoutCards(dashboard: Dashboard \| null) => voidEvent handler that triggers after dashboard loads, but without its cards - at this stage dashboard title, tabs and cards grid is rendered, but cards content is not yet loaded.
renderDrillThroughQuestion*() => ReactNodeA react component that renders a question’s layout shown after drilling through a question or clicking on a question card in the dashboard.
drillThroughQuestionProps*[InteractiveQuestionProps](./questions#question-props)Props for the drill-through question
+ +

* Not available for StaticDashboard.

+ +

** Combining initialParameters and hiddenParameters to filter data on the frontend is a security risk. Combining initialParameters and hiddenParameters to declutter the user interface is fine.

+ +

By default, dashboard components take full page height (100vh). You can override this with custom styles passed via style or className props.

+ +
<EditableDashboard
+  style={{
+    height: 800,
+    minHeight: "auto",
+  }}
+  dashboardId={dashboardId}
+/>
+
+ +

Example embedded dashboard with InteractiveDashboard component

+ +
import React from "react";
+import {
+  InteractiveDashboard,
+  MetabaseProvider,
+  defineMetabaseAuthConfig,
+} from "@metabase/embedding-sdk-react";
+
+const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://your-metabase.example.com",
+  authProviderUri: "https://your-app.example.com/sso/metabase",
+});
+
+export default function App() {
+  const dashboardId = 1; // This is the dashboard ID you want to embed
+  const initialParameters = {}; // Define your query parameters here
+
+  // choose parameter names that are in your dashboard
+  const hiddenParameters = ["location", "city"];
+
+  return (
+    <MetabaseProvider authConfig={authConfig}>
+      <InteractiveDashboard
+        dashboardId={dashboardId}
+        initialParameters={initialParameters}
+        withTitle={false}
+        withDownloads={false}
+        hiddenParameters={hiddenParameters}
+      />
+    </MetabaseProvider>
+  );
+}
+
+ +

Customizing drill-through question layout

+ +

When drilling through or clicking on a question card in the dashboard, you will be taken to the question view. By default, the question is shown in the default layout for interactive questions.

+ +

To customize the question layout, pass a renderDrillThroughQuestion prop to the InteractiveDashboard component, with the custom view as the child component.

+ +
<InteractiveDashboard
+  dashboardId={95}
+  renderDrillThroughQuestion={QuestionView}
+/>
+
+// You can use namespaced components to build the question's layout.
+const QuestionView = () => <InteractiveQuestion.Title />;
+
+ +

The questionView prop accepts a React component that will be rendered in the question view, which you can build with namespaced components within the InteractiveQuestion component. See customizing interactive questions for an example layout.

+ +

Dashboard plugins

+ +

dashboardCardMenu

+ +

This plugin allows you to add, remove, and modify the custom actions on the overflow menu of dashboard cards. The plugin appears as a dropdown menu on the top right corner of the card.

+ +

The plugin’s default configuration looks like this:

+ +
const plugins = {
+  dashboard: {
+    dashboardCardMenu: {
+      withDownloads: true,
+      withEditLink: true,
+      customItems: [],
+    },
+  },
+};
+
+ +

dashboardCardMenu: can be used in the InteractiveDashboard like this:

+ +
<InteractiveDashboard
+  dashboardId={1}
+  plugins={{
+    dashboard: {
+      dashboardCardMenu: () => null,
+    },
+  }}
+/>
+
+ +

Enabling/disabling default actions

+ +

To remove the download button from the dashcard menu, set withDownloads to false. To remove the edit link from the dashcard menu, set withEditLink to false.

+ +
const plugins = {
+  dashboard: {
+    dashboardCardMenu: {
+      withDownloads: false,
+      withEditLink: false,
+      customItems: [],
+    },
+  },
+};
+
+ +

Adding custom actions to the existing menu:

+ +

You can add custom actions to the dashcard menu by adding an object to the customItems array. Each element can either be an object or a function that takes in the dashcard’s question, and outputs a list of custom items in the form of:

+ +
type DashCardMenuItem = {
+  iconName: string;
+  label: string;
+  onClick: () => void;
+  disabled?: boolean;
+};
+
+ +

Here’s an example:

+ +
const plugins: MetabasePluginsConfig = {
+  dashboard: {
+    dashboardCardMenu: {
+      customItems: [
+        {
+          iconName: "chevronright",
+          label: "Custom action",
+          onClick: () => {
+            alert(`Custom action clicked`);
+          },
+        },
+        ({ question }) => {
+          return {
+            iconName: "chevronright",
+            label: "Custom action",
+            onClick: () => {
+              alert(`Custom action clicked ${question?.name}`);
+            },
+          };
+        },
+      ],
+    },
+  },
+};
+
+ +

Replacing the existing menu with your own component

+ +

If you want to replace the existing menu with your own component, you can do so by providing a function that returns a React component. This function also can receive the question as an argument.

+ +
const plugins: MetabasePluginsConfig = {
+  dashboard: {
+    dashboardCardMenu: ({ question }) => (
+      <button onClick={() => console.log(question.name)}>Click me</button>
+    ),
+  },
+};
+
+ +

Creating dashboards

+ +

Creating a dashboard could be done with useCreateDashboardApi hook or CreateDashboardModal component.

+ +

Hook

+ +
const { createDashboard } = useCreateDashboardApi();
+
+const handleDashboardCreate = async () => {
+  const dashboard = await createDashboard(props);
+
+  // do something with created empty dashboard, e.g., use the dashboard in EditableDashboard component
+};
+
+return <button onClick={handleDashboardCreate}>Create new dashboard</button>;
+
+ +

Props:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
namestring(required) Dashboard title
descriptionstring \| nullOptional dashboard description
collectionIdnumber \| 'root' \| 'personal'Collection in which to create a new dashboard. You can use predefined system values like root or personal.
+ +

Component

+ +
const [dashboard, setDashboard] = useState<MetabaseDashboard | null>(null);
+
+if (dashboard) {
+  return <EditableDashboard dashboardId={dashboard.id} />;
+}
+
+return <CreateDashboardModal onClose={handleClose} onCreate={setDashboard} />;
+
+ +

Supported component props:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
collectionId?number \| 'root' \| 'personal'Initial collection in which to create a dashboard. You can use predefined system values like root or personal.
onCreate(dashboard: Dashboard) => voidHandler to react on dashboard creation.
onClose() => voidHandler to close modal component
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/introduction.html b/_site/docs/doc-update-detection/embedding/sdk/introduction.html new file mode 100644 index 000000000..425d4e9a1 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/introduction.html @@ -0,0 +1,3167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +

With the Embedded analytics SDK, you can embed individual Metabase components with React (like standalone charts, dashboards, the query builder, and more). You can manage access and interactivity per component, and you have advanced customization for seamless styling.

+ +

Example apps built with the embedded analytics SDK

+ +

To give you an idea of what’s possible with the SDK, we’ve put together example sites at metaba.se/sdk-demo. Navigate between different shop websites. Check them out and poke around their products and analytics sections, as well as the New Question and New Dashboard options.

+ +

Pug and play example app built with embedded analytics SDK

+ +

Here’s the Shoppy source code.

+ +

Embedded analytics SDK prerequisites

+ +
    +
  • React application using React 18 or React 19.
  • +
  • Nodejs 20.x or higher.
  • +
  • Metabase version 1.52 or higher.
  • +
+ +

Quickstarts

+ + + +

Installation

+ +

To use the SDK, you’ll need to enable the SDK in Metabase, and install the SDK in your React app.

+ +

Enable the SDK in Metabase

+ +

Enable the Embedded analytics SDK by going to Admin settings > Settings > Embedding. Toggle on the SDK, and hit Configure. Enter the origins for your website or app where you want to allow SDK embedding, separated by a space. Localhost is automatically included.

+ +

Install the SDK in your React application

+ +

You can install the Embedded analytics SDK for React via npm. Make sure to use the dist-tag that corresponds to your Metabase version, example: 53-stable for Metabase 53:

+ +
npm install @metabase/embedding-sdk-react@53-stable
+
+ +

or with yarn:

+ +
yarn add @metabase/embedding-sdk-react@53-stable
+
+ +

Developing with the Embedded analytics SDK

+ +

Start with one of the quickstarts, then see these pages for more info on components, theming, and more.

+ + + +

Embedded analytics SDK source code

+ +

You can find the Embedded analytics SDK source code in the Metabase repo.

+ +

Changelog

+ +

View the SDK’s changelog:

+ + + +

Embedded analytics SDK on NPM

+ +

Check out the Metabase Embedded analytics SDK on NPM: metaba.se/sdk.

+ +

SDK limitations

+ +

The SDK doesn’t support:

+ +
    +
  • Verified content
  • +
  • Official collections
  • +
  • Subscriptions
  • +
  • Alerts
  • +
  • Server-side rendering (SSR)
  • +
  • Multiple interactive dashboards on the same application page. If you need to embed multiple dashboards on the same application page, you can embed static dashboards.
  • +
  • React 19
  • +
+ +

Issues, feature requests and support

+ +

Bugs and feature requests are tracked on GitHub.

+ +

You can upvote an existing feature request by leaving a thumbs up emoji reaction on the issue. Feel free to leave comments with context that could be useful. Read more.

+ +

Before creating new issues, please make sure an issue for your problem or feature request doesn’t already exist. +To seek help:

+ +
    +
  • Paid customers can contact our success team through the usual channels.
  • +
  • People using the open-source edition can post on our discussion forums.
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/next-js.html b/_site/docs/doc-update-detection/embedding/sdk/next-js.html new file mode 100644 index 000000000..e99c891c8 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/next-js.html @@ -0,0 +1,3299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - Using the SDK with Next.js | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - Using the SDK with Next.js

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +
+ +
+ + +
+
+ +

Some notes on using the Embedded analytics SDK with Next.js. The SDK is tested to work with Next.js 14, although it may work with other versions.

+ +

SDK components with Server Side Rendering (SSR) or React Server Components

+ +

For now, the SDK components are only supported for client-side rendering. To use the SDK components with server-side rendering, or with React Server components, you can either use a compatibility layer or manually wrap the components.

+ +

Compatibility layer for server-side rendering (SSR) (EXPERIMENTAL)

+ +

To use SDK components with Next.js, the SDK provides an experimental compatibility layer that wraps all the components with dynamic imports and disables SSR. To work with the app router, this compatibility layer uses use client.

+ +

To use the compatibility layer, change your imports from @metabase/embedding-sdk-react to @metabase/embedding-sdk-react/nextjs.

+ +

See a sample Next.js app that uses this compatibility layer.

+ +

Manual wrapping of the components

+ +

If you want to customize the loading of the components, you can create your own wrapper.

+ +

In your app, create a metabase directory, and add a EmbeddingSdkProvider.tsx file to that directory. This file will contain the provider with the appropriate configuration.

+ +
"use client";
+
+import {
+  MetabaseProvider,
+  defineMetabaseAuthConfig,
+} from "@metabase/embedding-sdk-react";
+
+const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: process.env.NEXT_PUBLIC_METABASE_INSTANCE_URL,
+  authProviderUri: process.env.NEXT_PUBLIC_METABASE_AUTH_PROVIDER_URI,
+});
+
+export const EmbeddingSdkProvider = ({
+  children,
+}: {
+  children: React.ReactNode;
+}) => {
+  return (
+    <MetabaseProvider authConfig={authConfig}>{children}</MetabaseProvider>
+  );
+};
+
+ +

Next, add an index.tsx file to that metabase directory. This file will include the use client directive, and it’ll export a lazy-loaded version of the EmbeddingSdkProvider with SSR disabled.

+ +
"use client";
+
+import dynamic from "next/dynamic";
+
+import type React from "react";
+
+// Lazy load the EmbeddingSdkProvider so and let it render children while it's being loaded
+export const EmbeddingSdkProviderLazy = ({
+  children,
+}: {
+  children: React.ReactNode;
+}) => {
+  const EmbeddingSdkProvider = dynamic(
+    () =>
+      import("./EmbeddingSdkProvider").then(m => {
+        return { default: m.EmbeddingSdkProvider };
+      }),
+    {
+      ssr: false,
+      loading: () => {
+        // render children while loading
+        return <div>{children}</div>;
+      },
+    },
+  );
+
+  return <EmbeddingSdkProvider>{children}</EmbeddingSdkProvider>;
+};
+
+// Wrap all components that you need like this:
+
+export const StaticQuestion = dynamic(
+  () => import("@metabase/embedding-sdk-react").then(m => m.StaticQuestion),
+  {
+    ssr: false,
+    loading: () => {
+      return <div>Loading...</div>;
+    },
+  },
+);
+
+export const StaticDashboard = dynamic(
+  () => import("@metabase/embedding-sdk-react").then(m => m.StaticDashboard),
+  {
+    ssr: false,
+    loading: () => {
+      return <div>Loading...</div>;
+    },
+  },
+);
+
+ +

You can now import components like so:

+ +
import { StaticQuestion } from "@/metabase"; // path to the folder created earlier
+
+export default function Home() {
+  return <StaticQuestion questionId={123} />;
+}
+
+ +

Handling authentication

+ +

App Router and Pages Router have different ways to define API routes. If you want to authenticate users from your server with JWT, you can follow the instructions below. But if you want to authenticate with API keys for local development, see Authenticating locally with API keys.

+ +

Using App Router

+ +

You can create a Route handler that signs people in to Metabase.

+ +

Create a new route.ts file in your app/* directory, for example app/sso/metabase/route.ts that corresponds to an endpoint at /sso/metabase.

+ +
import jwt from "jsonwebtoken";
+
+const METABASE_JWT_SHARED_SECRET = process.env.METABASE_JWT_SHARED_SECRET || "";
+const METABASE_INSTANCE_URL = process.env.METABASE_INSTANCE_URL || "";
+
+export async function GET() {
+  const token = jwt.sign(
+    {
+      email: user.email,
+      first_name: user.firstName,
+      last_name: user.lastName,
+      groups: [user.group],
+      exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration
+    },
+    // This is the JWT signing secret in your Metabase JWT authentication setting
+    METABASE_JWT_SHARED_SECRET,
+  );
+  const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`;
+
+  try {
+    const ssoResponse = await fetch(ssoUrl, { method: "GET" });
+    const ssoResponseBody = await ssoResponse.json();
+
+    return Response.json(ssoResponseBody);
+  } catch (error) {
+    if (error instanceof Error) {
+      return Response.json(
+        {
+          status: "error",
+          message: "authentication failed",
+          error: error.message,
+        },
+        {
+          status: 401,
+        },
+      );
+    }
+  }
+}
+
+ +

Then, pass this authConfig to MetabaseProvider

+ +
import { defineMetabaseAuthConfig } from "@metabase/embedding-sdk-react/nextjs";
+
+const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL
+  authProviderUri: "/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session
+});
+
+ +

Using Pages Router

+ +

You can create an API route that signs people in to Metabase.

+ +

Create a new metabase.ts file in your pages/api/* directory, for example pages/api/sso/metabase.ts that corresponds to an endpoint at /api/sso/metabase.

+ +
import type { NextApiRequest, NextApiResponse } from "next";
+import jwt from "jsonwebtoken";
+
+const METABASE_JWT_SHARED_SECRET = process.env.METABASE_JWT_SHARED_SECRET || "";
+const METABASE_INSTANCE_URL = process.env.METABASE_INSTANCE_URL || "";
+
+export default async function handler(
+  req: NextApiRequest,
+  res: NextApiResponse,
+) {
+  const token = jwt.sign(
+    {
+      email: user.email,
+      first_name: user.firstName,
+      last_name: user.lastName,
+      groups: [user.group],
+      exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration
+    },
+    // This is the JWT signing secret in your Metabase JWT authentication setting
+    METABASE_JWT_SHARED_SECRET,
+  );
+  const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`;
+
+  try {
+    const ssoResponse = await fetch(ssoUrl, { method: "GET" });
+    const ssoResponseBody = await ssoResponse.json();
+
+    res.status(200).json(ssoResponseBody);
+  } catch (error) {
+    if (error instanceof Error) {
+      res.status(401).json({
+        status: "error",
+        message: "authentication failed",
+        error: error.message,
+      });
+    }
+  }
+}
+
+ +

Then, pass this authConfig to MetabaseProvider

+ +
import { defineMetabaseAuthConfig } from "@metabase/embedding-sdk-react/nextjs";
+
+const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL
+  authProviderUri: "/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session
+});
+
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/plugins.html b/_site/docs/doc-update-detection/embedding/sdk/plugins.html new file mode 100644 index 000000000..5f7a4c877 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/plugins.html @@ -0,0 +1,3095 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - plugins | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - plugins

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +

The Metabase Embedded analytics SDK supports plugins to customize the behavior of components. These plugins can be used in a global context or on a per-component basis.

+ +

Global plugins

+ +

To use a plugin globally, add the plugin to the MetabaseProvider’s pluginsConfig prop:

+ +
<MetabaseProvider
+  authConfig={authConfig}
+  theme={theme}
+  pluginsConfig={{
+    mapQuestionClickActions: () => [], // Add your custom actions here
+  }}
+>
+  {children}
+</MetabaseProvider>
+
+ +

Component plugins

+ +

To use a plugin on a per-component basis, pass the plugin as a prop to the component:

+ +
<InteractiveQuestion
+  questionId={1}
+  plugins={{
+    mapQuestionClickActions: () => [],
+  }}
+/>
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/questions.html b/_site/docs/doc-update-detection/embedding/sdk/questions.html new file mode 100644 index 000000000..8b6f0f380 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/questions.html @@ -0,0 +1,3878 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - questions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - questions

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +

There are different ways you can embed questions:

+ +
    +
  • Static question. Embeds a chart. Clicking on the chart doesn’t do anything.
  • +
  • Interactive question. Clicking on the chart gives you the drill-through menu.
  • +
  • Query builder. Embeds the graphical query builder without a pre-defined query.
  • +
+ +

Embedding a static question

+ +

Static question

+ +

You can embed a static question using the StaticQuestion component.

+ +

The component has a default height, which can be customized by using the height prop. To inherit the height from the parent container, you can pass 100% to the height prop.

+ +
import React from "react";
+import {
+  MetabaseProvider,
+  StaticQuestion,
+  defineMetabaseAuthConfig,
+} from "@metabase/embedding-sdk-react";
+
+const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://your-metabase.example.com",
+  authProviderUri: "https://your-app.example.com/sso/metabase",
+});
+
+export default function App() {
+  const questionId = 1; // This is the question ID you want to embed
+
+  return (
+    <MetabaseProvider authConfig={authConfig}>
+      <StaticQuestion questionId={questionId} withChartTypeSelector={false} />
+    </MetabaseProvider>
+  );
+}
+
+ +

Embedding an interactive question

+ +

Interactive question

+ +

You can embed an interactive question using the InteractiveQuestion component.

+ +
import React from "react";
+import {
+  InteractiveQuestion,
+  MetabaseProvider,
+  defineMetabaseAuthConfig,
+} from "@metabase/embedding-sdk-react";
+
+const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://your-metabase.example.com",
+  authProviderUri: "https://your-app.example.com/sso/metabase",
+});
+
+export default function App() {
+  const questionId = 1; // This is the question ID you want to embed
+
+  return (
+    <MetabaseProvider authConfig={authConfig}>
+      <InteractiveQuestion questionId={questionId} />
+    </MetabaseProvider>
+  );
+}
+
+ +

Question props

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
entityTypeFilterstring array; options include “table”, “question”, “model”, “metric”(optional) An array that specifies which entity types are available in the data picker
heightnumber or string(optional) A number or string specifying a CSS size value that specifies the height of the component
initialSqlParametersRecord<string, string \| string[]>(optional) For SQL questions only. A mapping of SQL parameter names to parameter values, such as { product_id: "42"}
isSaveEnabledboolean(optional, default: true) Whether users can save the question
onBeforeSave() => void(optional) A callback function that triggers before saving. Only relevant when isSaveEnabled = true
onSave() => void(optional) A callback function that triggers when a user saves the question. Only relevant when isSaveEnabled = true
plugins{ mapQuestionClickActions: Function } or nullAdditional mapper function to override or add drill-down menu
questionIdnumber or string(required) The ID of the question. This is either:
- The numerical ID when accessing a question link, e.g., http://localhost:3000/question/1-my-question where the ID is 1
- The entity_id key of the question object. You can find a question’s Entity ID in the info panel when viewing a question
- new to show the notebook editor for creating new questions. isSaveEnabled must be true to allow saving the question
targetCollectionnumber | “root” | “personal”(optional) The collection to save the question to. This will hide the collection picker from the save modal. Only applicable to interactive questions
titleboolean | string | ReactNode | () => ReactNode(optional) Determines whether the question title is displayed, and allows a custom title to be displayed instead of the default question title. Shown by default. Only applicable to interactive questions when using the default layout
withChartTypeSelectorboolean(optional, default: true) Determines whether the chart type selector and corresponding settings button are shown. Only relevant when using the default layout
withResetButtonboolean(optional, default: true) Determines whether a reset button is displayed. Only relevant when using the default layout
+ +

Pass SQL parameters to SQL questions with initialSqlParameters

+ +

You can pass parameter values to questions defined with SQL via the initialSqlParameters prop, in the format of {parameter_name: parameter_value}. Learn more about SQL parameters.

+ +
<StaticQuestion
+  questionId={questionId}
+  initialSqlParameters={{ product_id: 50 }}
+/>
+
+ +

initialSqlParameters can’t be used with questions built using the query builder.

+ +

Customizing interactive questions

+ +

By default, the Embedded analytics SDK provides a default layout for interactive questions that allows you to view your questions, apply filters and aggregations, and access functionality within the query builder.

+ +

Here’s an example of using the InteractiveQuestion component with its default layout:

+ +
<InteractiveQuestion questionId={95} />
+
+ +

To customize the layout, use namespaced components within the InteractiveQuestion component. For example:

+ +
<div
+  className="App"
+  style={{
+    width: "100%",
+    maxWidth: "1600px",
+    height: "800px",
+    margin: "0 auto",
+  }}
+>
+  <MetabaseProvider authConfig={authConfig} theme={theme}>
+    <InteractiveQuestion questionId={95}>
+      <div
+        style={{
+          display: "flex",
+          flexDirection: "column",
+          alignItems: "center",
+          justifyContent: "center",
+          width: "100%",
+        }}
+      >
+        <div style={{ display: "grid", placeItems: "center", width: "100%" }}>
+          <InteractiveQuestion.Title />
+          <InteractiveQuestion.ResetButton />
+        </div>
+        <div
+          style={{
+            display: "flex",
+            alignItems: "center",
+            justifyContent: "flex-start",
+            overflow: "hidden",
+            width: "100%",
+          }}
+        >
+          <div style={{ width: "100%" }}>
+            <InteractiveQuestion.QuestionVisualization />
+          </div>
+          <div style={{ display: "flex", flex: 1, overflow: "scroll" }}>
+            <InteractiveQuestion.Summarize />
+          </div>
+        </div>
+        <div
+          style={{ display: "flex", flexDirection: "column", width: "100%" }}
+        >
+          <InteractiveQuestion.Filter />
+        </div>
+      </div>
+    </InteractiveQuestion>
+  </MetabaseProvider>
+</div>
+
+ +

Interactive question components

+ +

These components are available via the InteractiveQuestion namespace (e.g., <InteractiveQuestion.Filter />).

+ +

* signifies a required prop

+ +

InteractiveQuestion.BackButton

+ +

A navigation button that returns to the previous view. Only renders when onNavigateBack prop from InteractiveQuestion is available.

+ +

Uses Mantine ActionIcon props under the hood, as well as:

+ + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
classNamestringCustom CSS class name for styling the component
styleReact.CSSPropertiesInline styles to apply to the component
+ +

InteractiveQuestion.Breakout

+ +

A set of badges for managing data groupings (breakouts).

+ +

No props. Uses question context for breakout functionality.

+ +

InteractiveQuestion.BreakoutDropdown

+ +

Dropdown button for the Breakout component.

+ +

Uses Popover props except onClose, children, and opened under the hood, as well as:

+ + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
classNamestringCustom CSS class name for styling the component
styleReact.CSSPropertiesInline styles to apply to the component
+ +

InteractiveQuestion.ChartTypeDropdown

+ +

Dropdown for selecting the visualization type (bar chart, line chart, table, etc.). Automatically updates to show recommended visualization types for the current data.

+ +

Uses Mantine Menu props under the hood, as well as:

+ + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
classNamestringCustom CSS class name for styling the component
styleReact.CSSPropertiesInline styles to apply to the component
+ +

InteractiveQuestion.ChartTypeSelector

+ +

Detailed chart type selection interface with recommended visualization options.

+ +

Uses Mantine Stack props under the hood, as well as:

+ + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
classNamestringCustom CSS class name for styling the component
styleReact.CSSPropertiesInline styles to apply to the component
+ +

InteractiveQuestion.Editor

+ +

Advanced query editor that provides full access to question configuration. Includes filtering, aggregation, custom expressions, and joins.

+ +

Replaces deprecated InteractiveQuestion.Notebook

+ + + + + + + + + + + + + + + + +
PropTypeDescription
onApply() => voidCallback function executed when changes are applied
+ +

InteractiveQuestion.EditorButton

+ +

Replaces deprecated InteractiveQuestion.NotebookButton

+ +

Toggle button for showing/hiding the Editor interface. In custom layouts, the EditorButton must have an onClick handler or the button won’t do anything when clicked.

+ +

Uses Mantine ActionIcon props under the hood, as well as:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
isOpenbooleanWhether the editor is currently open
classNamestringCustom CSS class name for styling the component
styleReact.CSSPropertiesInline styles to apply to the component
+ +

InteractiveQuestion.Filter

+ +

A set of interactive filter badges that allow adding, editing, and removing filters. Displays current filters as badges with an “Add another filter” option.

+ + + + + + + + + + + + + + + + +
PropTypeDescription
withColumnItemIconbooleanWhether to show column icons in the filter interface
+ +

InteractiveQuestion.FilterDropdown

+ +

A dropdown button for the Filter component.

+ + + + + + + + + + + + + + + + +
PropTypeDescription
withColumnItemIconbooleanWhether to show column icons in the filter interface
+ +

InteractiveQuestion.QuestionSettings

+ +

Settings panel for configuring visualization options like axes, colors, and formatting.

+ +

No props. Uses question context for settings.

+ +

InteractiveQuestion.QuestionSettingsDropdown

+ +

Dropdown button that contains the QuestionSettings component.

+ +

Uses Popover props except onClose and opened under the hood, as well as:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
heightReact.CSSProperties[“height”]Height for the dropdown menu
classNamestringCustom CSS class name for styling the component
styleReact.CSSPropertiesInline styles to apply to the component
+ +

InteractiveQuestion.QuestionVisualization

+ +

The main visualization component that renders the question results as a chart, table, or other visualization type.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
heightnumber | stringHeight for visualization
widthnumber | stringWidth for visualization
classNamestringCustom CSS class name for styling the component
styleReact.CSSPropertiesInline styles to apply to the component
+ +

InteractiveQuestion.ResetButton

+ +

Button to reset question modifications. Only appears when there are unsaved changes to the question.

+ +

Uses Mantine Button props under the hood, as well as:

+ + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
classNamestringCustom CSS class name for styling the component
styleReact.CSSPropertiesInline styles to apply to the component
+ +

InteractiveQuestion.SaveButton

+ +

Button for saving question changes. Only enabled when there are unsaved modifications to the question.

+ +

Note: Currently, in custom layouts, the SaveButton must have an onClick handler or the button will not do anything when clicked.

+ +

Uses Mantine Button props under the hood, as well as:

+ + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
classNamestringCustom CSS class name for styling the component
styleReact.CSSPropertiesInline styles to apply to the component
+ +

InteractiveQuestion.SaveQuestionForm

+ +

Form for saving a question, including title and description. When saved:

+ +
    +
  • For new questions: Calls onCreate prop from InteractiveQuestion
  • +
  • For existing questions: Calls onSave prop from InteractiveQuestion
  • +
  • Both callbacks receive the updated question object
  • +
  • Form can be cancelled via the onCancel prop
  • +
+ + + + + + + + + + + + + + + + +
PropTypeDescription
onCancel() => voidCallback function executed when save is cancelled
+ +

InteractiveQuestion.Summarize

+ +

Interface for adding and managing data summaries (like counts, sums, averages). Displays as a set of badges.

+ +

No props. Uses question context for summarization functionality.

+ +

InteractiveQuestion.SummarizeDropdown

+ +

Dropdown button for the Summarize component.

+ +

Uses Popover props except onClose, children, and opened under the hood, as well as:

+ + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
classNamestringCustom CSS class name for styling the component
styleReact.CSSPropertiesInline styles to apply to the component
+ +

InteractiveQuestion.DownloadWidget

+ +

Provides a UI widget for downloading data in different formats (CSV, XLSX, JSON, and PNG depending on the visualization).

+ +

No props

+ +

InteractiveQuestion.DownloadWidgetDropdown

+ +

Provides a button that contains a dropdown that shows the DownloadWidget.

+ +

Uses Popover props under the hood, as well as:

+ + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
classNamestringCustom CSS class name for styling the component
styleReact.CSSPropertiesInline styles to apply to the component
+ +

InteractiveQuestion.Title

+ +

Displays a title based on the question’s state. Shows:

+ +
    +
  • The question’s display name if it’s saved
  • +
  • An auto-generated description for ad-hoc questions (non-native queries)
  • +
  • “New question” as fallback or for new/native queries
  • +
+ + + + + + + + + + + + + + + + + + + + + +
PropTypeDescription
classNamestringCustom CSS class name for styling the component
styleCSSPropertiesInline styles to apply to the component
+ +

Interactive question plugins

+ +

You can use plugins to add custom functionality to your questions.

+ +

mapQuestionClickActions

+ +

This plugin allows you to add custom actions to the click-through menu of an interactive question. You can add and +customize the appearance and behavior of the custom actions.

+ +
// You can provide a custom action with your own `onClick` logic.
+const createCustomAction = clicked => ({
+  buttonType: "horizontal",
+  name: "client-custom-action",
+  section: "custom",
+  type: "custom",
+  icon: "chevronright",
+  title: "Hello from the click app!!!",
+  onClick: ({ closePopover }) => {
+    alert(`Clicked ${clicked.column?.name}: ${clicked.value}`);
+    closePopover();
+  },
+});
+
+// Or customize the appearance of the custom action to suit your need.
+const createCustomActionWithView = clicked => ({
+  name: "client-custom-action-2",
+  section: "custom",
+  type: "custom",
+  view: ({ closePopover }) => (
+    <button
+      className="tw-text-base tw-text-yellow-900 tw-bg-slate-400 tw-rounded-lg"
+      onClick={() => {
+        alert(`Clicked ${clicked.column?.name}: ${clicked.value}`);
+        closePopover();
+      }}
+    >
+      Custom element
+    </button>
+  ),
+});
+
+const plugins = {
+  /**
+   * You will have access to default `clickActions` that Metabase renders by default.
+   * So you could decide if you want to add custom actions, remove certain actions, etc.
+   */
+  mapQuestionClickActions: (clickActions, clicked) => {
+    return [
+      ...clickActions,
+      createCustomAction(clicked),
+      createCustomActionWithView(clicked),
+    ];
+  },
+};
+
+const questionId = 1; // This is the question ID you want to embed
+
+return (
+  <MetabaseProvider authConfig={authConfig} pluginsConfig={plugins}>
+    <InteractiveQuestion questionId={questionId} />
+  </MetabaseProvider>
+);
+
+ +

Prevent people from saving changes to an InteractiveQuestion

+ +

To prevent people from saving changes to an interactive question, or from saving changes as a new question, you can set isSaveEnabled={false}:

+ +
import React from "react";
+import {
+  InteractiveQuestion,
+  MetabaseProvider,
+  defineMetabaseAuthConfig,
+} from "@metabase/embedding-sdk-react";
+
+const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://your-metabase.example.com",
+  authProviderUri: "https://your-app.example.com/sso/metabase",
+});
+
+export default function App() {
+  return (
+    <MetabaseProvider authConfig={authConfig}>
+      <InteractiveQuestion questionId={1} isSaveEnabled={false} />
+    </MetabaseProvider>
+  );
+}
+
+ +

Embedding the query builder for creating new questions

+ +

Query builder

+ +

You can embed the query builder for creating new questions by passing the questionId="new" prop to the InteractiveQuestion component. You can use the children prop to customize the layout for creating new questions.

+ +
import React from "react";
+import {
+  InteractiveQuestion,
+  MetabaseProvider,
+  defineMetabaseAuthConfig,
+} from "@metabase/embedding-sdk-react";
+
+const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://your-metabase.example.com",
+  authProviderUri: "https://your-app.example.com/sso/metabase",
+});
+
+export default function App() {
+  return (
+    <MetabaseProvider authConfig={authConfig}>
+      <InteractiveQuestion questionId="new" />
+    </MetabaseProvider>
+  );
+}
+
+ +

To customize the question editor’s layout, use the InteractiveQuestion component directly with a custom children prop.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/quickstart-cli.html b/_site/docs/doc-update-detection/embedding/sdk/quickstart-cli.html new file mode 100644 index 000000000..65e35e557 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/quickstart-cli.html @@ -0,0 +1,3181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - CLI quickstart | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - CLI quickstart

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +

We built a single command to spin up a Metabase and help you get an embedded dashboard in your app. This setup with API keys won’t work in production; it’s only intended for you to quickly try out the SDK on your local machine. A production setup requires a Pro/Enterprise license, and SSO with JWT.

+ +

Prerequisites

+ +
    +
  • Docker (should be up and running on your machine)
  • +
  • Node.js 20.x LTS or higher.
  • +
  • License (Optional - only if you want to try out multi-tenancy).
  • +
  • Database (you can connect to your app’s database).
  • +
+ +

You don’t need a running Metabase; the tool will set up a Metabase for you on Docker.

+ +

The quickstart CLI command

+ +

Change into your React application and run:

+ +
npx @metabase/embedding-sdk-react@latest start
+
+ +

The CLI tool will walk you through the setup. There are a fair number of pieces to put together, so here’s an overview of what the command does:

+ + + +

Prereq check

+ +

The tool will check for the following:

+ +
    +
  • You’ve run the command in the top-level directory of your React application.
  • +
  • You’ve installed the SDK (if you haven’t, the CLI will install the SDK for you and add it as a dependency in your package.json).
  • +
  • You have Docker up and running on your machine.
  • +
+ +

Database connection (optional)

+ +

The tool will ask if you have a database to connect to. Use the arrow keys to select Yes or No. The tool will use this database to generate an embedded dashboard.

+ +

If you answer no, the script will use the Sample Database that ships with Metabase to create a dashboard to embed.

+ +

If you select Yes, the tool will prompt you to connect to a database. Pick your database’s engine. You’ll need to provide database’s host, port, username, and password. The tool will connect to the database, and prompt you to select tables from your database to embed. Pick 1-3 tables. If you want to see multi-tenancy in action, pick a table with user IDs in it. Metabase will X-ray these tables to create a dashboard to embed.

+ +

Metabase setup

+ +

The tool will ask you for an email address to create the first admin account in Metabase. Doesn’t have to be a real email address (the tool doesn’t set up a SMTP server); the email address is just required for logging in to the Metabase that the tool will set up.

+ +

Next, the tool will spin up a Metabase on Docker. This takes a bit. To see the Docker container’s status, use the docker ps command. Or use the time to reflect on good choices you’ve made recently.

+ +

Once Metabase is up and running, the tool will create an admin user with the email you provided, and generate an API key for that Metabase.

+ +

The tool will then prompt you to pick 1-3 tables to embed. You can press to select, to toggle all, to invert selection, and to proceed.

+ +

Permissions setup with multi-tenancy (optional)

+ +

If you have a Pro/EE license, the tool can set up permissions. To get a license, sign up for a free trial of self-hosted Metabase Pro.

+ +

If you opted to set up multi-tenancy and connected to your own database, the tool will ask you for the column you want to use to sandbox the table (e.g., a user ID column). Metabase will sandbox data based on the values in that column.

+ +

The tool will also set up a mock Express server to handle the JWTs. The tool will ask you where it should save the server code (default: ./mock-server). It’ll install the server’s dependencies with npm install.

+ +

You’ll need to start the mock server in another terminal session. Change into the mock server’s directory and run:

+ +
npm run start
+
+ +

React components setup

+ +

Next, the tool will generate example React components files. By default, the tool will save them in ./src/components/metabase in your React app, though the tool will prompt you to save them to a different directory if you want (e.g., ./src/analytics). +It generates a couple of demo components for you to try out theming and user switching:

+ +
    +
  • AnalyticsDashboard - a dashboard component that embeds a Metabase dashboard.
  • +
  • AnalyticsPage - a page that embeds a dashboard with a wrapped provider. In a real application, you must add the MetabaseProvider separately to your app’s root App component (or where you would’ve added your other providers).
  • +
  • ThemeSwitcher - switch between light and dark themes.
  • +
  • UserSwitcher - switch between fake users.
  • +
  • AnalyticsProvider - a provider that adds the demo state for the example theme switcher and user switcher components.
  • +
  • EmbeddingProvider - a provider that wraps the MetabaseProvider with demo themes and auth configuration.
  • +
+ +

You can delete these files once you’ve played around with the tool, and are ready to setup your own theming and user management.

+ +

Add the Metabase/React components to your app

+ +

You’ll need to add the Metabase/React components to your app. Add an import to your client app, like so:

+ +
import { AnalyticsPage } from "./components/metabase/analytics-page";
+
+ +

Make sure the from path is valid (depending on your app, you may need to move the components to a new directory).

+ +

Then you’ll need to add the <AnalyticsPage /> component to a page in your app. Something like:

+ +
function App() {
+  return (
+    <div className="App" style={{ width: "1200px", height: "800px" }}>
+      <AnalyticsPage />
+    </div>
+  );
+}
+
+export default App;
+
+ +

Behold: Metabase is embedded in your app

+ +

Start your app, and visit the page where you added the <AnalyticsPage /> component. You should see an embedded dashboard.

+ +

You can also check out the Metabase the tool set up. The Metabase should be running at http://localhost:3366. You can find your login credentials at METABASE_LOGIN.json.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/quickstart-with-sample-app.html b/_site/docs/doc-update-detection/embedding/sdk/quickstart-with-sample-app.html new file mode 100644 index 000000000..0aa99a2ca --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/quickstart-with-sample-app.html @@ -0,0 +1,3311 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - quickstart with sample app | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - quickstart with sample app

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +

This guide sets up the embedded analytics SDK with a sample React app, but you can follow along with your own application.

+ +
+ +
+ + +
+
+ +

Prerequisites

+ + + +

Two ways to set up the sample app with Metabase

+ + + +

Quick setup with Docker

+ +

This quick setup will run a Docker container with the sample app and a sample Metabase.

+ +
    +
  1. Copy .env.docker.example to .env.docker.
  2. +
  3. In the .env.docker file, replace <your_enterprise_token> with your premium embedding token.
  4. +
  5. In the top-level directory, run: +
     yarn start
    +
    +
  6. +
+ +

This script will:

+ +
    +
  • Pull a Metabase Docker image and run it in a container.
  • +
  • Set up JWT SSO in Metabase.
  • +
  • Build and run the sample application with an embedded interactive question.
  • +
+ +

The app will start on http://localhost:4400.

+ +

That’s it! You should be up and running.

+ +

If you want to log in to the sample Metabase this command set up, visit http://localhost:4300. You can log in with email and password as Rene Descartes:

+ +
    +
  • email: rene@example.com
  • +
  • password: foobarbaz
  • +
+ +

Walkthrough setup

+ +

We’re going to do some setup in Metabase, and then in the sample application. You can also bring your own Metabase, in which case you can skip the installation step.

+ +

Here’s a quick overview of what you’ll be doing:

+ +

Set up Metabase for embedding

+ +
    +
  1. Install Metabase Enterprise Edition (if you haven’t already)
  2. +
  3. Activate your license
  4. +
  5. Enable embedding
  6. +
  7. Enable SSO with JWT
  8. +
+ +

Start up the sample application

+ +
    +
  1. Get the sample application.
  2. +
  3. Set up the application environment.
  4. +
  5. Run the app server to handle authentication with JWT and serve the embedded Metabase components.
  6. +
  7. Run the client application that will contain Metabase components built with the SDK.
  8. +
+ +

And then fiddle around with styling.

+ +

Let’s go.

+ +

Install Metabase Enterprise Edition

+ +

You can run Metabase Pro on a Cloud plan with a free trial.

+ +

Or run it locally. Here’s a docker one-liner:

+ +
docker run -d -p 3000:3000 --name metabase metabase/metabase-enterprise:latest
+
+ +

You can also download the JAR, and run it like so:

+ +
java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

By default, Metabase will run at http://localhost:3000.

+ +

If you get stuck, check out our installation docs.

+ +

Activate your license

+ +

To enable SSO with JWT when self-hosting, you’ll need to activate your license. Metabase Pro plans on Cloud take care of this for you.

+ +

Enable embedding in Metabase

+ +

From any Metabase page, click on the gear icon in the upper right and select Admin Settings > Settings > Embedding.

+ +

Turn on:

+ +
    +
  • Embedded analytics SDK
  • +
  • Static embedding
  • +
+ +

Otherwise, this whole thing is hopeless.

+ +

Enable SSO with JWT

+ +

From any Metabase page, click on the gear icon in the upper right and select Admin Settings > Settings > Authentication.

+ +

On the card that says JWT, click the Setup button.

+ +

JWT Identity provider URI

+ +

In JWT IDENTITY PROVIDER URI field, paste

+ +
localhost:9090/sso/metabase
+
+ +

Or substitute your Cloud URL for localhost.

+ +

String used by the JWT signing key

+ +

Click the Generate key button.

+ +

Copy the key and paste it in your .env file into the env var METABASE_JWT_SHARED_SECRET.

+ +

The application server will use this key to sign tokens so Metabase knows the application’s requests for content are authorized.

+ +

Save and enable JWT

+ +

Be sure to hit the Save and enable button, or all is void.

+ +

Set up the sample application

+ +

Clone the Metabase Node JS React SDK embedding sample app.

+ +
git clone git@github.com:metabase/metabase-nodejs-react-sdk-embedding-sample.git
+
+ +

Check out the branch that corresponds to your Metabase version

+ +

Check out the branch in the metabase-nodejs-react-sdk-embedding-sample repo that corresponds to your Metabase version.

+ +

E.g., if you’re running Metabase 1.53, make sure the sample app repo is on the 53-stable branch. You can find your Metabase version in the Metabase UI by clicking on the gears icon in the upper right and selecting About Metabase.

+ +

To switch to another branch, run git checkout <branch-name>, e.g.:

+ +
git checkout 52-stable
+
+ +

Set up the application environment

+ +

In the sample app’s main directory, copy the .env.example template to .env.

+ +
cp .env.example .env
+
+ +

In .env, make sure VITE_METABASE_INSTANCE_URL and METABASE_INSTANCE_URL point to your Metabase instance URL, e.g., http://localhost:3000.

+ +

Your .env will look something like:

+ +
# FRONTEND
+CLIENT_PORT=3100
+VITE_METABASE_INSTANCE_URL="http://localhost:3000"
+VITE_AUTH_PROVIDER_URI="http://localhost:9090/sso/metabase"
+
+# BACKEND
+AUTH_PROVIDER_PORT=9090
+METABASE_INSTANCE_URL="http://localhost:3000"
+METABASE_JWT_SHARED_SECRET="TODO"
+
+ +

Set up the application server

+ +

Change into the server directory:

+ +
cd server
+
+ +

Install packages:

+ +
npm install
+
+ +

Start the server:

+ +
npm start
+
+ +

Set up the client application

+ +

In a different terminal, change into the client directory:

+ +
cd client
+
+ +

Install dependencies:

+ +
npm install
+
+ +

This command will install the Metabase embedded analytics SDK, in addition to the application’s other dependencies.

+ +

You can also install a different version of the SDK. Just make sure that the major version of the SDK matches the major version of the Metabase you’re using.

+ +

Start the client app:

+ +
npm start
+
+ +

Your browser should automatically open the app. By default, the app runs on http://localhost:3100.

+ +

At this point, you should be up and running

+ +

In your app, you’ll see an embedded InteractiveQuestion component.

+ +
<MetabaseProvider authConfig={authConfig} theme={theme}>
+  <InteractiveQuestion questionId={questionId} />
+</MetabaseProvider>
+
+ +

Embedded Metabase components

+ +

Next steps

+ +

To style the components, try changing some of the theme options in the client app at client/src/App.jsx. For more on theming, check out Appearance.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/quickstart.html b/_site/docs/doc-update-detection/embedding/sdk/quickstart.html new file mode 100644 index 000000000..7a45628d2 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/quickstart.html @@ -0,0 +1,3150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - quickstart | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - quickstart

+ +

This guide walks you through how to set up the Embedded analytics SDK in your application with your Metabase using API keys.

+ +

This setup:

+ +
    +
  • Is only for evaluation (so you can see how the SDK works).
  • +
  • Only works on localhost when developing your app (though your Metabase doesn’t need to be running locally).
  • +
  • Works with both the Enterprise and Open Source editions of Metabase, both self-hosted and on Metabase Cloud.
  • +
+ +

If you want to use the SDK in production, however, you’ll also need to set up JWT SSO authentication, which requires a Pro or Enterprise plan. To enable JWT SSO when you’re self-hosting Metabase, you’ll need to run the Enterprise Edition Docker image or JAR, and activate your license.

+ +

Prerequisites

+ + + +

If you don’t have a Metabase up and running, check out the Quickstart CLI.

+ +

If you don’t want to use your own application code, check out our quickstart with a sample app.

+ +

Overview

+ +

To embed a dashboard in your app using the SDK, you’ll need to:

+ +
    +
  1. Enable the SDK in Metabase
  2. +
  3. Create an API key in Metabase
  4. +
  5. Install the SDK in your app
  6. +
  7. Embed SDK components in your app
  8. +
  9. View your embedded Metabase dashboard
  10. +
+ +

1. Enable the SDK in Metabase

+ +

In Metabase, click on the gear icon in the upper right and navigate to Admin Settings > Settings > Embedding and enable the Embedded analytics SDK.

+ +

2. Create an API key in Metabase

+ +

Still in the Admin’s Settings tab, navigate to the Authentication section in the sidebar and click on the API keys tab. Create a new API key.

+ +
    +
  • Key name: “Embedded analytics SDK” (just to make the key easy to identify).
  • +
  • Group: select “Admin” (since this is only for local testing).
  • +
+ +

3. Install the SDK in your app

+ +

When installing the NPM package, it’s critical to use the npm dist-tag that corresponds to the major version of your Metabase. For example, if your Metabase is version 1.53.x, you’d run 53-stable. See SDK versioning.

+ +

Via NPM:

+ +
npm install @metabase/embedding-sdk-react@53-stable
+
+ +

Via Yarn:

+ +
yarn add @metabase/embedding-sdk-react@53-stable
+
+ +

4. Embed SDK components in your app

+ +

In your app, import the SDK components, like so:

+ +
import {
+  InteractiveDashboard,
+  MetabaseProvider,
+  defineMetabaseAuthConfig,
+} from "@metabase/embedding-sdk-react";
+
+/**
+ * This creates an auth config to pass to the `MetabaseProvider` component.
+ * You'll need to replace the `metabaseInstanceUrl` and the `apiKey` values.
+ */
+const authConfig = defineMetabaseAuthConfig({
+  metabaseInstanceUrl: "https://metabase.example.com",
+  apiKey: "YOUR_API_KEY",
+});
+
+/**
+ * Now embed your first dashboard. In this case, we're embedding the dashboard with ID 1.
+ * On new Metabases, ID 1 will be the example dashboard, but feel free to use a different dashboard ID.
+ */
+export default function App() {
+  return (
+    <MetabaseProvider authConfig={authConfig}>
+      <InteractiveDashboard dashboardId={1} />
+    </MetabaseProvider>
+  );
+}
+
+ +

5. View your embedded Metabase dashboard

+ +

Run your app and visit the page with the embedded dashboard.

+ +

Embedded example dashboard

+ +

Next steps

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/appearance/customizing-loader-and-components.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/appearance/customizing-loader-and-components.tsx new file mode 100644 index 000000000..37abcf102 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/appearance/customizing-loader-and-components.tsx @@ -0,0 +1,25 @@ +import type { MetabaseAuthConfig } from "@metabase/embedding-sdk-react"; +// [] +import { + MetabaseProvider, + StaticDashboard, +} from "@metabase/embedding-sdk-react"; +// [] + +const authConfig = {} as MetabaseAuthConfig; + +const Example = () => { + return ( + // [] + ] + authConfig={authConfig} + // [] + loaderComponent={() =>
Analytics is loading...
} + errorComponent={({ message }) =>
There was an error: {message}
} + > + +
+ // [] + ); +}; diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/appearance/theme.ts b/_site/docs/doc-update-detection/embedding/sdk/snippets/appearance/theme.ts new file mode 100644 index 000000000..b8aa1460f --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/appearance/theme.ts @@ -0,0 +1,195 @@ +import { defineMetabaseTheme } from "@metabase/embedding-sdk-react"; + +const theme = defineMetabaseTheme({ + // Specify a font to use from the set of fonts supported by Metabase. + // You can set the font to "Custom" to use the custom font + // configured in your Metabase instance. + fontFamily: "Lato", + + // Override the base font size for every component. + // This does not usually need to be set, as the components + // inherit the font size from the parent container, such as the body. + fontSize: "16px", + + // Override the base line height for every component. + lineHeight: 1.5, + + // Match your application's color scheme + colors: { + // The primary color of your application + brand: "#9B5966", + + // Lighter variation of the brand color. Used for hover and accented elements. + "brand-hover": "#DDECFA", + + // Lightest variation of the brand color. Used for hover and accented elements. + "brand-hover-light": "#EEF6FC", + + // The color of text that is most prominent + "text-primary": "#4C5773", + + // The color of text that is less prominent + "text-secondary": "#696E7B", + + // The color of text that is least prominent + "text-tertiary": "#949AAB", + + // Default background color + background: "#FFFFFF", + + // Slightly muted background color. + "background-secondary": "#EDF2F5", + + // Slightly darker background color used for hover and accented elements + "background-hover": "#F9FBFC", + + // Muted background color used for disabled elements, such as disabled buttons and inputs. + "background-disabled": "#F3F5F7", + + // Color used for borders + border: "#EEECEC", + + // Color used for filters context + filter: "#7172AD", + + // Color used for aggregations and breakouts context + summarize: "#88BF4D", + + // Color used to indicate successful actions and positive values/trends + positive: "#BADC58", + + // Color used to indicate dangerous actions and negative values/trends + negative: "#FF7979", + + /** Color used for popover shadows */ + shadow: "rgba(0,0,0,0.08)", + + // Overrides the chart colors. Supports up to 8 colors + // Limitation: this does not affect charts with custom series color + charts: [ + // can either be a hex code + "#9B59B6", + + // or a color object. tint and shade represents lighter and darker variations + // only base color is required, while tint and shade are optional + { base: "#E74C3C", tint: "#EE6B56", shade: "#CB4436" }, + ], + }, + + components: { + // Dashboard + dashboard: { + // Background color for all dashboards + backgroundColor: "#2F3640", + + // Border color of the dashboard grid, shown only when editing dashboards. + // Defaults to `colors.border` + gridBorderColor: "#EEECEC", + + card: { + // Background color for all dashboard cards + backgroundColor: "#2D2D30", + + // Apply a border color instead of shadow for dashboard cards. + // Unset by default. + border: "1px solid #EEECEC", + }, + }, + + // Question + question: { + // Background color for all questions + backgroundColor: "#2E353B", + + // Toolbar of the default interactive question layout + toolbar: { + backgroundColor: "#F3F5F7", + }, + }, + + // Tooltips + tooltip: { + // Tooltip text color. + textColor: "#FFFFFF", + + // Secondary text color shown in the tooltip, e.g. for tooltip headers and percentage changes. + secondaryTextColor: "#949AAB", + + // Tooltip background color. + backgroundColor: "#2E353B", + + // Tooltip background color for focused rows. + focusedBackgroundColor: "#0A0E10", + }, + + // Data table + table: { + cell: { + // Text color of cells, defaults to `text-primary` + textColor: "#4C5773", + + // Default background color of cells, defaults to `background` + backgroundColor: "#FFFFFF", + + // Font size of cell values, defaults to ~12.5px + fontSize: "12.5px", + }, + + idColumn: { + // Text color of ID column, defaults to `brand` + textColor: "#9B5966", + + // Background color of ID column, defaults to a lighter shade of `brand` + backgroundColor: "#F5E9EB", + }, + }, + + // Number chart + number: { + // Value displayed on number charts. + // This also applies to the primary value in trend charts. + value: { + fontSize: "24px", + lineHeight: "21px", + }, + }, + + // Cartesian chart + cartesian: { + // Padding around the cartesian charts. + // Uses CSS's `padding` property format. + padding: "4px 8px", + }, + + // Pivot table + pivotTable: { + cell: { + // Font size of cell values, defaults to ~12px + fontSize: "12px", + }, + + // Pivot row toggle to expand or collapse row + rowToggle: { + textColor: "#FFFFFF", + backgroundColor: "#95A5A6", + }, + }, + + collectionBrowser: { + breadcrumbs: { + expandButton: { + textColor: "#8118F4", + backgroundColor: "#767D7C", + hoverTextColor: "#CE8C8C", + hoverBackgroundColor: "#69264B", + }, + }, + }, + + // Popover are used in components such as click actions in interactive questions. + popover: { + // z-index of the popover. Useful for embedding components in a modal. defaults to 4. + zIndex: 4, + }, + }, +}); diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-api-key.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-api-key.tsx new file mode 100644 index 000000000..ccc26238a --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-api-key.tsx @@ -0,0 +1,17 @@ +import { + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfigApiKey = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://metabase.example.com", + apiKey: "YOUR_API_KEY", +}); + +export default function App() { + return ( + + Hello World! + + ); +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-base.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-base.tsx new file mode 100644 index 000000000..d0e174f7e --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-base.tsx @@ -0,0 +1,8 @@ +import { defineMetabaseAuthConfig } from "@metabase/embedding-sdk-react"; + +// [] +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", // Required: Your Metabase instance URL + authProviderUri: "https://your-app.example.com/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session +}); +// [] diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-jwt.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-jwt.tsx new file mode 100644 index 000000000..ceb0d429e --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/auth-config-jwt.tsx @@ -0,0 +1,20 @@ +import { defineMetabaseAuthConfig } from "@metabase/embedding-sdk-react"; + +const yourToken = "token"; + +// [] +// Pass this configuration to MetabaseProvider. +// Wrap the fetchRequestToken function in useCallback if it has dependencies to prevent re-renders. +const authConfig = defineMetabaseAuthConfig({ + fetchRequestToken: async url => { + const response = await fetch(url, { + method: "GET", + headers: { Authorization: `Bearer ${yourToken}` }, + }); + + return await response.json(); + }, + metabaseInstanceUrl: "http://localhost:3000", + authProviderUri: "http://localhost:9090/sso/metabase", +}); +// [] diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server-cors.ts b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server-cors.ts new file mode 100644 index 000000000..3fb221ed1 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server-cors.ts @@ -0,0 +1,41 @@ +import cors from "cors"; +import express from "express"; +import session from "express-session"; + +const PORT = 3000; +const SESSION_SECRET = "SECRET"; + +const app = express(); +const metabaseAuthHandler = () => {}; + +// [] +// Middleware + +// If your FE application is on a different domain from your BE, you need to enable CORS +// by setting Access-Control-Allow-Credentials to true and Access-Control-Allow-Origin +// to your FE application URL. +// +// Limitation: We currently only support setting one origin in Authorized Origins in Metabase for CORS. +app.use( + cors({ + credentials: true, + }), +); + +app.use( + session({ + secret: SESSION_SECRET, + resave: false, + saveUninitialized: true, + cookie: { secure: false }, + }), +); + +app.use(express.json()); + +// routes +app.get("/sso/metabase", metabaseAuthHandler); +app.listen(PORT, () => { + console.log(`API running at http://localhost:${PORT}`); +}); +// [] diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server.ts b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server.ts new file mode 100644 index 000000000..3971d5ce4 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/express-server.ts @@ -0,0 +1,65 @@ +import express from "express"; +import cors from "cors"; +import session from "express-session"; +import jwt from "jsonwebtoken"; +import fetch from "node-fetch"; + +// Replace this with your Metabase URL +const METABASE_INSTANCE_URL = "YOUR_METABASE_URL_HERE"; +// Replace this with the JWT signing secret you generated when enabling +// JWT SSO in your Metabase. +const METABASE_JWT_SHARED_SECRET = "YOUR_SECRET_HERE"; + +const app = express(); + +app.get("/sso/metabase", async (req, res) => { + // Usually, you would grab the user from the current session + // Here it's hardcoded for demonstration purposes + // Example: + // const { user } = req.session; + const user = { + email: "rene@example.com", + firstName: "Rene", + lastName: "Descartes", + group: "Customer", + }; + + if (!user) { + console.log("no user"); + res.status(401).json({ + status: "error", + message: "not authenticated", + }); + + return; + } + + const token = jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + groups: [user.group], + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration + }, + METABASE_JWT_SHARED_SECRET, + ); + const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`; + console.log("Hitting MB SSO endpoint", ssoUrl); + + try { + const response = await fetch(ssoUrl, { method: "GET" }); + const session = await response.text(); + + console.log("Received session", session); + res.status(200).set("Content-Type", "application/json").end(session); + } catch (error) { + if (error instanceof Error) { + res.status(401).json({ + status: "error", + message: "authentication failed", + error: error.message, + }); + } + } +}); diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/get-auth-status.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/get-auth-status.tsx new file mode 100644 index 000000000..0c8db4349 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/authentication/get-auth-status.tsx @@ -0,0 +1,18 @@ +import { + InteractiveQuestion, + useMetabaseAuthStatus, +} from "@metabase/embedding-sdk-react"; + +const Example = () => { + // [] + const auth = useMetabaseAuthStatus(); + + if (auth.status === "error") { + return
Failed to authenticate: {auth.error.message}
; + } + + if (auth.status === "success") { + return ; + } + // [] +}; diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/collections/collection-browser.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/collections/collection-browser.tsx new file mode 100644 index 000000000..4b09f1563 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/collections/collection-browser.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { CollectionBrowser } from "@metabase/embedding-sdk-react"; + +export default function App() { + const collectionId = 123; // This is the collection ID you want to browse + const handleItemClick = item => { + console.log("Clicked item:", item); + }; + + return ( + + ); +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/config/config-base.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/config/config-base.tsx new file mode 100644 index 000000000..90d7d3522 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/config/config-base.tsx @@ -0,0 +1,25 @@ +import { + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const theme = {}; + +// [] +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL + authProviderUri: "https://app.example.com/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session +}); + +export default function App() { + return ( + + Hello World! + + ); +} +// [] diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/config/config-with-event-handlers.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/config/config-with-event-handlers.tsx new file mode 100644 index 000000000..85eda0eb1 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/config/config-with-event-handlers.tsx @@ -0,0 +1,30 @@ +import type { PropsWithChildren } from "react"; +import { + MetabaseProvider, + type SdkDashboardLoadEvent, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "", + authProviderUri: "", +}); + +const Example = ({ children }: PropsWithChildren) => { + // [] + const handleDashboardLoad: SdkDashboardLoadEvent = dashboard => { + /* do whatever you need to do - e.g. send analytics events, show notifications */ + }; + + const eventHandlers = { + onDashboardLoad: handleDashboardLoad, + onDashboardLoadWithoutCards: handleDashboardLoad, + }; + + return ( + + {children} + + ); + // [] +}; diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/config/config-with-theme.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/config/config-with-theme.tsx new file mode 100644 index 000000000..619e0d22a --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/config/config-with-theme.tsx @@ -0,0 +1,38 @@ +import React from "react"; +import { + MetabaseProvider, + defineMetabaseAuthConfig, + defineMetabaseTheme, +} from "@metabase/embedding-sdk-react"; + +// Configure authentication +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL + authProviderUri: "https://app.example.com/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session +}); + +// See the "Customizing appearance" section for more information +const theme = defineMetabaseTheme({ + // Optional: Specify a font to use from the set of fonts supported by Metabase + fontFamily: "Lato", + + // Optional: Match your application's color scheme + colors: { + brand: "#9B5966", + "text-primary": "#4C5773", + "text-secondary": "#696E7B", + "text-tertiary": "#949AAB", + }, +}); + +export default function App() { + return ( + + Hello World! + + ); +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/config/reload-metabase-provider.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/config/reload-metabase-provider.tsx new file mode 100644 index 000000000..6c9e3a8cf --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/config/reload-metabase-provider.tsx @@ -0,0 +1,37 @@ +import { useEffect, useState } from "react"; +import { InteractiveQuestion } from "@metabase/embedding-sdk-react"; +import { isEqual } from "underscore"; + +const yourQuestionId = 1; + +const Example = () => { + // [] + // Inside your application component + const [data, setData] = useState({}); + // This is used to force reloading Metabase components + const [counter, setCounter] = useState(0); + + // This ensures we only change the `data` reference when it's actually changed + const handleDataChange = newData => { + setData(prevData => { + if (isEqual(prevData, newData)) { + return prevData; + } + + return newData; + }); + }; + + useEffect(() => { + /** + * When you set `data` as the `useEffect` hook's dependency, it will trigger the effect + * and increment the counter which is used in a Metabase component's `key` prop, forcing it to reload. + */ + if (data) { + setCounter(counter => counter + 1); + } + }, [data]); + + return ; + // [] +}; diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/create-dashboard.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/create-dashboard.tsx new file mode 100644 index 000000000..24e22cd95 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/create-dashboard.tsx @@ -0,0 +1,41 @@ +import { useState } from "react"; +import { + CreateDashboardModal, + EditableDashboard, + type MetabaseDashboard, + useCreateDashboardApi, +} from "@metabase/embedding-sdk-react"; + +const ExampleHook = () => { + const props = { + name: "New dashboard", + description: null, + collectionId: 1, + }; + + // [] + const { createDashboard } = useCreateDashboardApi(); + + const handleDashboardCreate = async () => { + const dashboard = await createDashboard(props); + + // do something with created empty dashboard, e.g., use the dashboard in EditableDashboard component + }; + + return ; + // [] +}; + +const ExampleComponent = () => { + const handleClose = () => {}; + + // [] + const [dashboard, setDashboard] = useState(null); + + if (dashboard) { + return ; + } + + return ; + // [] +}; diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-drill-through-question-layout.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-drill-through-question-layout.tsx new file mode 100644 index 000000000..a5066bd2e --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-drill-through-question-layout.tsx @@ -0,0 +1,18 @@ +import { + InteractiveDashboard, + InteractiveQuestion, +} from "@metabase/embedding-sdk-react"; + +const Example = () => ( + // [] + + // [] +); + +// [] +// You can use namespaced components to build the question's layout. +const QuestionView = () => ; +// [] diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-height.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-height.tsx new file mode 100644 index 000000000..1957db5be --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/custom-height.tsx @@ -0,0 +1,15 @@ +import { EditableDashboard } from "@metabase/embedding-sdk-react"; + +const dashboardId = 1; + +const Example = () => ( + // [] + + // [] +); diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/interactive-dashboard.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/interactive-dashboard.tsx new file mode 100644 index 000000000..4d7270549 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/interactive-dashboard.tsx @@ -0,0 +1,31 @@ +import React from "react"; +import { + InteractiveDashboard, + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", + authProviderUri: "https://your-app.example.com/sso/metabase", +}); + +export default function App() { + const dashboardId = 1; // This is the dashboard ID you want to embed + const initialParameters = {}; // Define your query parameters here + + // choose parameter names that are in your dashboard + const hiddenParameters = ["location", "city"]; + + return ( + + + + ); +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/plugins.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/plugins.tsx new file mode 100644 index 000000000..439e80a48 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/dashboards/plugins.tsx @@ -0,0 +1,105 @@ +import { + InteractiveDashboard, + type MetabasePluginsConfig, +} from "@metabase/embedding-sdk-react"; + +const dashboardId = 1; + +const ExampleBase1 = () => { + // [] + const plugins = { + dashboard: { + dashboardCardMenu: { + withDownloads: true, + withEditLink: true, + customItems: [], + }, + }, + }; + // [] + + return ; +}; + +const ExampleBase2 = () => ( + // [] + null, + }, + }} + /> + // [] +); + +const ExampleDefaultActions = () => { + // [] + const plugins = { + dashboard: { + dashboardCardMenu: { + withDownloads: false, + withEditLink: false, + customItems: [], + }, + }, + }; + // [] + + return ; +}; + +// [] +type DashCardMenuItem = { + iconName: string; + label: string; + onClick: () => void; + disabled?: boolean; +}; +// [] + +const ExampleCustomActions = () => { + // [] + const plugins: MetabasePluginsConfig = { + dashboard: { + dashboardCardMenu: { + customItems: [ + { + iconName: "chevronright", + label: "Custom action", + onClick: () => { + alert(`Custom action clicked`); + }, + }, + ({ question }) => { + return { + iconName: "chevronright", + label: "Custom action", + onClick: () => { + alert(`Custom action clicked ${question?.name}`); + }, + }; + }, + ], + }, + }, + }; + // [] + + return ; +}; + +const ExampleCustomActionsMenu = () => { + // [] + const plugins: MetabasePluginsConfig = { + dashboard: { + dashboardCardMenu: ({ question }) => ( + + ), + }, + }; + // [] + + return ; +}; diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/EmbeddingSdkProvider.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/EmbeddingSdkProvider.tsx new file mode 100644 index 000000000..02cc7ba8b --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/EmbeddingSdkProvider.tsx @@ -0,0 +1,2 @@ +// Required to properly resolve import in `manual-wrapping-entrypoint.tsx` snippet +export { EmbeddingSdkProvider } from "./manual-wrapping-embedded-sdk-provider"; diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/app-router-authentication-api-route.ts b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/app-router-authentication-api-route.ts new file mode 100644 index 000000000..2a4f1e140 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/app-router-authentication-api-route.ts @@ -0,0 +1,50 @@ +// [] +import jwt from "jsonwebtoken"; +// [] + +const user = { + email: "rene@example.com", + firstName: "Rene", + lastName: "Descartes", + group: "Customer", +}; + +// [] +const METABASE_JWT_SHARED_SECRET = process.env.METABASE_JWT_SHARED_SECRET || ""; +const METABASE_INSTANCE_URL = process.env.METABASE_INSTANCE_URL || ""; + +export async function GET() { + const token = jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + groups: [user.group], + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration + }, + // This is the JWT signing secret in your Metabase JWT authentication setting + METABASE_JWT_SHARED_SECRET, + ); + const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`; + + try { + const ssoResponse = await fetch(ssoUrl, { method: "GET" }); + const ssoResponseBody = await ssoResponse.json(); + + return Response.json(ssoResponseBody); + } catch (error) { + if (error instanceof Error) { + return Response.json( + { + status: "error", + message: "authentication failed", + error: error.message, + }, + { + status: 401, + }, + ); + } + } +} +// [] diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/authentication-auth-config.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/authentication-auth-config.tsx new file mode 100644 index 000000000..d1e0299a4 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/authentication-auth-config.tsx @@ -0,0 +1,6 @@ +import { defineMetabaseAuthConfig } from "@metabase/embedding-sdk-react/nextjs"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL + authProviderUri: "/sso/metabase", // Required: An endpoint in your app that signs the user in and returns a session +}); diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/declarations.d.ts b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/declarations.d.ts new file mode 100644 index 000000000..4b7134cba --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/declarations.d.ts @@ -0,0 +1,4 @@ +// Required to properly resolve the `import { StaticQuestion } from "@/metabase";` in `manual-wrapping-usage.tsx` snippet +declare module "@/metabase" { + export { StaticQuestion } from "@metabase/embedding-sdk-react/nextjs"; +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-embedded-sdk-provider.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-embedded-sdk-provider.tsx new file mode 100644 index 000000000..b65e5b8d4 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-embedded-sdk-provider.tsx @@ -0,0 +1,33 @@ +// [] +"use client"; + +import { + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: process.env.NEXT_PUBLIC_METABASE_INSTANCE_URL, + authProviderUri: process.env.NEXT_PUBLIC_METABASE_AUTH_PROVIDER_URI, +}); + +export const EmbeddingSdkProvider = ({ + children, +}: { + children: React.ReactNode; +}) => { + return ( + {children} + ); +}; +// [] + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace NodeJS { + interface ProcessEnv { + readonly NEXT_PUBLIC_METABASE_INSTANCE_URL: string; + readonly NEXT_PUBLIC_METABASE_AUTH_PROVIDER_URI: string; + } + } +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-entrypoint.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-entrypoint.tsx new file mode 100644 index 000000000..67a66ba53 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-entrypoint.tsx @@ -0,0 +1,52 @@ +// [] +"use client"; + +import dynamic from "next/dynamic"; + +import type React from "react"; + +// Lazy load the EmbeddingSdkProvider so and let it render children while it's being loaded +export const EmbeddingSdkProviderLazy = ({ + children, +}: { + children: React.ReactNode; +}) => { + const EmbeddingSdkProvider = dynamic( + () => + import("./EmbeddingSdkProvider").then(m => { + return { default: m.EmbeddingSdkProvider }; + }), + { + ssr: false, + loading: () => { + // render children while loading + return
{children}
; + }, + }, + ); + + return {children}; +}; + +// Wrap all components that you need like this: + +export const StaticQuestion = dynamic( + () => import("@metabase/embedding-sdk-react").then(m => m.StaticQuestion), + { + ssr: false, + loading: () => { + return
Loading...
; + }, + }, +); + +export const StaticDashboard = dynamic( + () => import("@metabase/embedding-sdk-react").then(m => m.StaticDashboard), + { + ssr: false, + loading: () => { + return
Loading...
; + }, + }, +); +// [] diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-usage.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-usage.tsx new file mode 100644 index 000000000..9e92b8417 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/manual-wrapping-usage.tsx @@ -0,0 +1,5 @@ +import { StaticQuestion } from "@/metabase"; // path to the folder created earlier + +export default function Home() { + return ; +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/pages-router-authentication-api-route.ts b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/pages-router-authentication-api-route.ts new file mode 100644 index 000000000..7566938c6 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/next-js/pages-router-authentication-api-route.ts @@ -0,0 +1,49 @@ +// [] +import type { NextApiRequest, NextApiResponse } from "next"; +import jwt from "jsonwebtoken"; +// [] + +const user = { + email: "rene@example.com", + firstName: "Rene", + lastName: "Descartes", + group: "Customer", +}; + +// [] +const METABASE_JWT_SHARED_SECRET = process.env.METABASE_JWT_SHARED_SECRET || ""; +const METABASE_INSTANCE_URL = process.env.METABASE_INSTANCE_URL || ""; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse, +) { + const token = jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + groups: [user.group], + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration + }, + // This is the JWT signing secret in your Metabase JWT authentication setting + METABASE_JWT_SHARED_SECRET, + ); + const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`; + + try { + const ssoResponse = await fetch(ssoUrl, { method: "GET" }); + const ssoResponseBody = await ssoResponse.json(); + + res.status(200).json(ssoResponseBody); + } catch (error) { + if (error instanceof Error) { + res.status(401).json({ + status: "error", + message: "authentication failed", + error: error.message, + }); + } + } +} +// [] diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/plugins/component-plugins.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/plugins/component-plugins.tsx new file mode 100644 index 000000000..9dc8e0c12 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/plugins/component-plugins.tsx @@ -0,0 +1,12 @@ +import { InteractiveQuestion } from "@metabase/embedding-sdk-react"; + +const Example = () => ( + // [] + [], + }} + /> + // [] +); diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/plugins/global-plugins.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/plugins/global-plugins.tsx new file mode 100644 index 000000000..a1dedccee --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/plugins/global-plugins.tsx @@ -0,0 +1,23 @@ +import type { PropsWithChildren } from "react"; +import { + type MetabaseAuthConfig, + MetabaseProvider, + type MetabaseTheme, +} from "@metabase/embedding-sdk-react"; + +const authConfig = {} as MetabaseAuthConfig; +const theme = {} as MetabaseTheme; + +const Example = ({ children }: PropsWithChildren) => ( + // [] + [], // Add your custom actions here + }} + > + {children} + + // [] +); diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/customize-interactive-question.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/customize-interactive-question.tsx new file mode 100644 index 000000000..9ff7afa7a --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/customize-interactive-question.tsx @@ -0,0 +1,69 @@ +import { + InteractiveQuestion, + type MetabaseAuthConfig, + MetabaseProvider, + type MetabaseTheme, +} from "@metabase/embedding-sdk-react"; + +const authConfig = {} as MetabaseAuthConfig; +const theme = {} as MetabaseTheme; + +const ExampleDefaultInteractiveQuestion = () => ( + // [] + + // [] +); + +const ExampleCustomizedInteractiveQuestion = () => ( + // [] +
+ + +
+
+ + +
+
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+ // [] +); diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/disable-question-save.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/disable-question-save.tsx new file mode 100644 index 000000000..365a669ae --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/disable-question-save.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { + InteractiveQuestion, + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", + authProviderUri: "https://your-app.example.com/sso/metabase", +}); + +export default function App() { + return ( + + + + ); +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/initial-sql-parameters.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/initial-sql-parameters.tsx new file mode 100644 index 000000000..5ef24b887 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/initial-sql-parameters.tsx @@ -0,0 +1,12 @@ +import { StaticQuestion } from "@metabase/embedding-sdk-react"; + +const questionId = 1; + +const Example = () => ( + // [] + + // [] +); diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question-plugins.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question-plugins.tsx new file mode 100644 index 000000000..62e7331b9 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question-plugins.tsx @@ -0,0 +1,65 @@ +import { + InteractiveQuestion, + type MetabaseAuthConfig, + MetabaseProvider, +} from "@metabase/embedding-sdk-react"; + +const authConfig = {} as MetabaseAuthConfig; + +const Example = () => { + // [] + // You can provide a custom action with your own `onClick` logic. + const createCustomAction = clicked => ({ + buttonType: "horizontal", + name: "client-custom-action", + section: "custom", + type: "custom", + icon: "chevronright", + title: "Hello from the click app!!!", + onClick: ({ closePopover }) => { + alert(`Clicked ${clicked.column?.name}: ${clicked.value}`); + closePopover(); + }, + }); + + // Or customize the appearance of the custom action to suit your need. + const createCustomActionWithView = clicked => ({ + name: "client-custom-action-2", + section: "custom", + type: "custom", + view: ({ closePopover }) => ( + + ), + }); + + const plugins = { + /** + * You will have access to default `clickActions` that Metabase renders by default. + * So you could decide if you want to add custom actions, remove certain actions, etc. + */ + mapQuestionClickActions: (clickActions, clicked) => { + return [ + ...clickActions, + createCustomAction(clicked), + createCustomActionWithView(clicked), + ]; + }, + }; + + const questionId = 1; // This is the question ID you want to embed + + return ( + + + + ); + // [] +}; diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question.tsx new file mode 100644 index 000000000..2d564bc2b --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/interactive-question.tsx @@ -0,0 +1,21 @@ +import React from "react"; +import { + InteractiveQuestion, + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", + authProviderUri: "https://your-app.example.com/sso/metabase", +}); + +export default function App() { + const questionId = 1; // This is the question ID you want to embed + + return ( + + + + ); +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/new-question.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/new-question.tsx new file mode 100644 index 000000000..a81f7c216 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/new-question.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { + InteractiveQuestion, + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", + authProviderUri: "https://your-app.example.com/sso/metabase", +}); + +export default function App() { + return ( + + + + ); +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/static-question.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/static-question.tsx new file mode 100644 index 000000000..b309088b2 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/questions/static-question.tsx @@ -0,0 +1,21 @@ +import React from "react"; +import { + MetabaseProvider, + StaticQuestion, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://your-metabase.example.com", + authProviderUri: "https://your-app.example.com/sso/metabase", +}); + +export default function App() { + const questionId = 1; // This is the question ID you want to embed + + return ( + + + + ); +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/components/metabase/analytics-page.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/components/metabase/analytics-page.tsx new file mode 100644 index 000000000..58ce956a8 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/components/metabase/analytics-page.tsx @@ -0,0 +1 @@ +export const AnalyticsPage = () => null; diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/example.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/example.tsx new file mode 100644 index 000000000..b340c9a6b --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart-cli/example.tsx @@ -0,0 +1,15 @@ +// [] +import { AnalyticsPage } from "./components/metabase/analytics-page"; +// [] + +// [] +function App() { + return ( +
+ +
+ ); +} + +export default App; +// [] diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart-with-sample-app/example.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart-with-sample-app/example.tsx new file mode 100644 index 000000000..ed5393228 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart-with-sample-app/example.tsx @@ -0,0 +1,19 @@ +import { + InteractiveQuestion, + type MetabaseAuthConfig, + MetabaseProvider, + type MetabaseTheme, +} from "@metabase/embedding-sdk-react"; + +const authConfig = {} as MetabaseAuthConfig; +const theme = {} as MetabaseTheme; + +const questionId = 1; + +const Example = () => ( + // [] + + + + // [] +); diff --git a/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart/example.tsx b/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart/example.tsx new file mode 100644 index 000000000..4d332275f --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/snippets/quickstart/example.tsx @@ -0,0 +1,26 @@ +import { + InteractiveDashboard, + MetabaseProvider, + defineMetabaseAuthConfig, +} from "@metabase/embedding-sdk-react"; + +/** + * This creates an auth config to pass to the `MetabaseProvider` component. + * You'll need to replace the `metabaseInstanceUrl` and the `apiKey` values. + */ +const authConfig = defineMetabaseAuthConfig({ + metabaseInstanceUrl: "https://metabase.example.com", + apiKey: "YOUR_API_KEY", +}); + +/** + * Now embed your first dashboard. In this case, we're embedding the dashboard with ID 1. + * On new Metabases, ID 1 will be the example dashboard, but feel free to use a different dashboard ID. + */ +export default function App() { + return ( + + + + ); +} diff --git a/_site/docs/doc-update-detection/embedding/sdk/version.html b/_site/docs/doc-update-detection/embedding/sdk/version.html new file mode 100644 index 000000000..749242c3b --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/sdk/version.html @@ -0,0 +1,3095 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedded analytics SDK - versions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedded analytics SDK - versions

+ +
+
+ + + + + + + +

Embedded analytics SDK is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). + You can, however, play around with the SDK on your local machine without a license by using API keys to authenticate your embeds.

+
+
+ +

The SDK stable version tracks with the Metabase version.

+ +

So, for example, if you’re on Metabase 53 (0.53.x, 1.53.x), any version 0.53.x of the @metabase/embedding-sdk-react npm package will be compatible.

+ +

To simplify things, we publish dist-tags for each stable Metabase version. For example, to install the latest version of the SDK compatible with Metabase 53, run:

+ +
npm install @metabase/embedding-sdk-react@53-stable
+
+ +

To grab the latest version of the SDK that works with Metabase nightly builds, use the canary dist-tag.

+ +

Minimum SDK version

+ +

52 is the minimum version supported for the Embedded analytics SDK.

+ +

Version pinning when using the SDK with Metabase Cloud

+ +

To pin your version of Metabase, go to Admin settings > Settings > Embedding. Go to the Embedded analytics SDK card and scroll to Version pinning and click Request version pinning.

+ +

Version pinning requirements

+ +

To pin a version of Metabase, you must:

+ +
    +
  • Be on Metabase Cloud (obviously)
  • +
  • Be on the Pro or Enterprise plans
  • +
+ +

Why you’d want to pin your Metabase Cloud version

+ +

Normally, Metabase Cloud upgrades your Metabase as new versions roll out so that you don’t have to deal with upgrades.

+ +

But if you’re using the SDK with Metabase Cloud, you’ll want to upgrade manually to make sure your embeds don’t break when you upgrade both your Metabase and your SDK version.

+ +

To upgrade manually, you can pin your Metabase version so that it stays in sync with the SDK version you’re using. That way you can choose when to upgrade your Metabase.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/signed-embedding-parameters.html b/_site/docs/doc-update-detection/embedding/signed-embedding-parameters.html new file mode 100644 index 000000000..f5f3a8db1 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/signed-embedding-parameters.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/embedding/signed-embedding.html b/_site/docs/doc-update-detection/embedding/signed-embedding.html new file mode 100644 index 000000000..6e1ed4b9f --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/signed-embedding.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/embedding/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts b/_site/docs/doc-update-detection/embedding/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts new file mode 100644 index 000000000..4398043b1 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/snippets/interactive-embedding-quick-start-guide/sso-with-jwt.ts @@ -0,0 +1,116 @@ +import express from "express"; +// [] +import jwt from "jsonwebtoken"; +// [] + +const app = express(); + +const METABASE_INSTANCE_URL = "YOUR_METABASE_URL_HERE"; +const METABASE_JWT_SHARED_SECRET = "YOUR_SECRET_HERE"; + +type User = { + email: string; + firstName: string; + lastName: string; +}; + +declare module "express-session" { + interface SessionData { + user: User; + } +} + +// [] +function restrict(req, res, next) { + if (req.session.user) { + next(); + } else { + req.session.returnTo = req.originalUrl; + req.session.error = "Access denied!"; + res.redirect("/login"); + } +} +// [] + +// [] +const signUserToken = user => + jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration + }, + METABASE_JWT_SHARED_SECRET, + ); +// [] + +const userGroupsExample = () => { + // [] + const signUserToken = user => + jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + groups: ["Customer-Acme"], + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration + }, + METABASE_JWT_SHARED_SECRET, + ); + // [] +}; + +const userAttributeExample = () => { + // [] + const signUserToken = user => + jwt.sign( + { + email: user.email, + first_name: user.firstName, + last_name: user.lastName, + // hard-coded account ID added to this object + // just to test sandboxing with Metabase's Sample Database: Invoices table + account_id: 28, + groups: ["Customer-Acme"], + exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration + }, + METABASE_JWT_SHARED_SECRET, + ); + // [] +}; + +// [] +app.get("/sso/metabase", restrict, (req, res) => { + const ssoUrl = new URL("/auth/sso", METABASE_INSTANCE_URL); + ssoUrl.searchParams.set("jwt", signUserToken(req.session.user)); + ssoUrl.searchParams.set("return_to", req.query.return_to?.toString() ?? "/"); + + res.redirect(ssoUrl.href); +}); +// [] + +app.get("/sso/metabase", restrict, (req, res) => { + const ssoUrl = new URL("/auth/sso", METABASE_INSTANCE_URL); + ssoUrl.searchParams.set("jwt", signUserToken(req.session.user)); + + // [] + ssoUrl.searchParams.set( + "return_to", + `${req.query.return_to ?? "/"}?logo=false&top_nav=false`, + ); + // [] + + res.redirect(ssoUrl.href); +}); + +// [] +app.get("/analytics", restrict, (req, res) => { + const METABASE_DASHBOARD_PATH = "/dashboard/entity/[Entity ID]"; // e.g., `/dashboard/1` or `/dashboard/entity/nXg0q7VOZJp5a3_hceMRk` + const iframeUrl = `/sso/metabase?return_to=${METABASE_DASHBOARD_PATH}`; + + res.send( + ``, + ); +}); +// [] diff --git a/_site/docs/doc-update-detection/embedding/start.html b/_site/docs/doc-update-detection/embedding/start.html new file mode 100644 index 000000000..158124f4c --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/start.html @@ -0,0 +1,3075 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Embedding overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Embedding overview

+ +

Introduction

+ +

What is embedding, and how does it work?

+ +

Interactive embedding

+ +

The solution to self-service customer analytics: embed the full Metabase app in your app. Interactive embedding integrates with your data permissions to let people slice and dice data on their own using Metabase’s query builder.

+ +

Interactive embedding quickstart

+ +

You’ll embed the full Metabase application in your app. Once logged in, people can view a Metabase dashboard in your web app, and be able to use the full Metabase application to explore their data, and only their data.

+ +

Embedded analytics SDK

+ +

With the Embedded analytics SDK, you can embed individual Metabase components with React (like standalone charts, dashboards, the query builder, and more). You can manage access and interactivity per component, and you have advanced customization for seamless styling.

+ +

Embedded analytics SDK quickstart

+ +

Jump to a SDK quickstart with a sample React application.

+ +

Static embedding

+ +

Also known as Signed Embedding, Static embedding is a secure way to embed charts and dashboards. Static embeds are view only; people won’t be able to drill-through charts and tables.

+ +

Parameters for static embeds

+ +

You can pass parameters between Metabase and your website via the embedding URL to specify how Metabase items should look and behave inside the iframe on your website.

+ +

Public embeds

+ +

Admins can also create unsecured public links or embeds of questions and dashboards.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/static-embedding-parameters.html b/_site/docs/doc-update-detection/embedding/static-embedding-parameters.html new file mode 100644 index 000000000..256e1147d --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/static-embedding-parameters.html @@ -0,0 +1,3364 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Parameters for static embeds | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Parameters for static embeds

+ +

Also known as: parameters for signed embeds, or standalone embeds.

+ +

Parameters are pieces of information that are passed between Metabase and your website via the embedding URL. You can use parameters to specify how Metabase items should look and behave inside the iframe on your website.

+ + + +

Types of parameters

+ +

Parameters can be signed or unsigned.

+ +

Signed parameters

+ +

Signed parameters, such as filter names and values, must be added to your server code.

+ + + +

Unsigned parameters

+ +

Unsigned parameters, such as appearance settings, should be added directly to your iframe’s src attribute.

+ + + +

Adding a filter widget to a static embed

+ +

You can use editable parameters to add filter widgets to embedded dashboards or SQL questions.

+ +
    +
  1. Go to your dashboard or SQL question. Make sure you’ve set up a dashboard filter or SQL variable.
  2. +
  3. Click on the sharing icon > Embed this item in an application.
  4. +
  5. Under Parameters, you’ll find the names of your dashboard filters or SQL variables.
  6. +
  7. Select Editable for each parameter that should get a filter widget on your embed.
  8. +
  9. Click Publish to save your changes.
  10. +
  11. Add or update the code on your server to match the code generated by Metabase.
  12. +
+ +

Editable parameters are responsible for passing filter values from the embedded filter widget (displayed on the iframe) through to the filters on your original dashboard or SQL question (in your Metabase).

+ +

You can’t disable parameters when the original question or dashboard requires a value

+ +

If the filter on a dashboard or question is set to Always require a value, you won’t be able to disable the parameter when embedding.

+ +

Populating an embedded filter widget with a default value

+ +

If you want to set a default value for your editable filter widget, you can pass that default value to the corresponding parameter name in your iframe’s src attribute:

+ +
your_embedding_url?parameter_name=value
+
+ +

Let’s say your embedded dashboard has a filter connected to an editable parameter called “Breakfast”. If you want to set the default value for the “Breakfast” filter to “Scrambled eggs”:

+ +
your_embedding_url?breakfast=Scrambled_eggs
+
+ +

To specify default values for more than one filter, separate the filters with ampersands (&):

+ +
your_embedding_url?breakfast=Scrambled_eggs&lunch=Grilled_cheese
+
+ +

You can set multiple default values for a filter by separating the key=value pairs with ampersands (&):

+ +
your_embedding_url?breakfast=Scrambled_eggs&breakfast=Bacon
+
+ +

Hiding filter widgets from a static embed

+ +

If you have a lot of editable parameters (resulting in a lot of filter widgets), you can hide them from your static embed by adding #hide_parameters to the end of the URL in your iframe’s src attribute:

+ +
your_embedding_url#hide_parameters=parameter_name
+
+ +

For example, if you want to hide a filter called “Breakfast” from your embedded dashboard:

+ +
your_embedding_url#hide_parameters=breakfast
+
+ +

You can hide multiple filter widgets by separating the parameter names with commas:

+ +
your_embedding_url#hide_parameters=breakfast,lunch
+
+ +

You can also simultaneously assign a parameter a default value and hide its filter widget:

+ +
your_embedding_url?breakfast=Scrambled_eggs#hide_parameters=breakfast
+
+ +

Unsigned parameter syntax

+ +

Whenever you’re adding a parameter to the embedding URL in your iframe’s src attribute, note that:

+ +
    +
  • Parameter names are lowercase.
  • +
  • Parameter values are case-sensitive (the values must match your data).
  • +
  • Spaces should be replaced by underscores.
  • +
+ +

Restricting data in a static embed with locked parameters

+ +

If you want to restrict the data that’s displayed in an embedded dashboard or SQL question, you can set up a locked parameter. A locked parameter filters the data in a dashboard or SQL question before the results are displayed to people in a static embed.

+ +
    +
  1. Go to your dashboard or SQL question. Make sure you’ve set up a dashboard filter or SQL variable.
  2. +
  3. Click on the sharing icon > Embed this item in an application.
  4. +
  5. Under Parameters, you’ll find the names of your dashboard filters or SQL variables.
  6. +
  7. Select Locked for each parameter that you want to restrict your data with.
  8. +
  9. Optional: select a value under Preview locked parameters to see what the restricted data looks like.
  10. +
  11. Click Publish to save your changes.
  12. +
  13. Add or update the code on your server to match the code generated by Metabase.
  14. +
+ +

You can use locked parameters to display filtered data based on attributes captured by your web server, such as a username or a tenant ID. For more examples, see the reference apps repo.

+ +

Locked parameters will apply the selected filter values to your original dashboard or SQL question, but they won’t be displayed as filter widgets on your embed. Locked parameters may also limit the values that are shown in your editable filter widgets.

+ +

If you just want to require a value for the parameter, you could set the filter as editable and configure the underlying question or dashboard to always require a value.

+ +

Updating a locked parameter

+ +

Things to keep in mind if you need to make changes to your locked parameters.

+ +

Include all locked parameters in your server code

+ +

Once you publish a chart or dashboard with a locked parameter, you must include the name of the locked parameter in your server code. If you exclude the parameter name, the logs will gently remind you: You must specify a value for :parameter in the JWT.

+ +

To turn off a locked parameter, pass an empty array as its value in the JWT

+ +

If you don’t want the locked filter to apply, you can pass an empty array, [], as the value for the parameter in the JWT.

+ +

Make sure the filter name matches the locked parameter name

+ +

If you change the name of a query builder filter that’s used as a locked parameter, make sure to update the parameter’s name and value(s) in your server code as well. If your locked parameter is connected to a SQL variable, you don’t need to change the parameter’s name and value(s).

+ +

Multiple locked parameters or multiple values

+ +

The values for the locked parameter in your server code should match your filter’s values exactly. The best way to set multiple locked parameters, or pass multiple values to a locked parameter, is to pick a filter value under Preview locked parameters and preview the server code generated by Metabase.

+ +

Using multiple locked parameters together will filter with AND, not OR. If you only want to apply a subset of the locked parameters, you must tell Metabase to ignore the other locked parameters.

+ +

Locked parameters limit the values available to other editable parameters

+ +

Because locked parameters filter data before the results are displayed in the embed, locked parameters limit the values available to other, editable filter widgets.

+ +

For example, say you’re embedding a dashboard with two filters, State and City. If you lock the State parameter with the value “Vermont”, Metabase will only display the City filter widget on the dashboard, and the dropdown menu for that City filter widget will be limited to cities in Vermont. While you don’t explicitly link the two filters, the two filters behave implicitly like linked filters.

+ +

Locked parameters on dashboards with SQL questions

+ +

If your locked parameter is linked to a dashboard filter that’s in turn linked to a SQL question, you’ll only be able to choose a single value for your locked parameter.

+ +

For example, let’s say you have a dashboard filter called “Breakfast” with the values “Hash browns”, “Muffin”, and “Waffles”. If the “Breakfast” filter is linked to any SQL questions on the dashboard, you’ll only be able to choose one of the options for a locked parameter linked to the “Breakfast” filter.

+ +

Using locked parameters to power custom widgets in your app

+ +

Because Metabase doesn’t display locked parameters as filter widgets, you can use locked parameters to power custom filter widgets that you build in your app. You may want to build your own filter widget(s) to:

+ +
    +
  • Make the widgets more consistent with the look and feel of your application.
  • +
  • Include custom logic. For example, to have a filter widget remember recent values.
  • +
  • Reuse one dashboard in different ways in different parts of your app. For example, you may have a dashboard with multiple locked parameters, and use one parameter in one case, and another parameter in another case. Like a sales dashboard that in one part of your app is locked by “region”, in another by “team”.
  • +
+ +

Customizing the appearance of a static embed

+ +

Look and feel: appearance settings on static embed

+ +

You can change the appearance of an embedded item by adding hash parameters (e.g., #theme=night) to the end of the URL in your iframe’s src attribute.

+ +

For example, the following embedding URL will display an embedded item in dark mode, without a border, and with its original title:

+ +
your_embedding_url#theme=night&bordered=false&titled=true
+
+ +

You can preview appearance settings from your question or dashboard’s embedded appearance settings.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter namePossible values
backgroundtrue (default), false. Dashboards only.
borderedtrue (default), false.
locale\*E.g., locale=ko. See list of locales
titledtrue (default), false.
themenull (default), night. theme=transparent should work, but is deprecated (see Transparent backgrounds)
refresh (dashboard only)integer (seconds, e.g., refresh=60).
font*font name
downloads**true (default), false.
+ +

* Available on Pro and Enterprise plans

+ +

** Disabling downloads is available on Pro and Enterprise plans.

+ +

For global appearance settings, such as the colors and fonts used across your entire Metabase instance, see Customizing Metabase’s appearance.

+ +

Setting the language for a static embed

+ +
+
+ + + + + + + +

Locales for static embeds is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

To change the UI language for a static embed, you can set its locale. For example, to set a public link’s language to Korean, you could append #locale=ko.

+ +
https://metabase.example.com/public/dashboard/7b6e347b-6928-4aff-a56f-6cfa5b718c6b?category=&city=&state=#locale=ko
+
+ +

If you have multiple params, separated them with an ampersand &:

+ +
category=Gadget&state=Vermont#theme=night&locale=ko
+
+ +

The locale param only changes the language for Metabase UI elements. The content’s language is defined by whomever created the item. So for example Metabase wouldn’t translate the name of a question, but Metabase would translate the UI text “Export to PDF”.

+ +

Transparent backgrounds for embeds

+ +

Making an embed transparent depends on the type of embed:

+ +
    +
  • Dashboards: set background=false. The background parameter can be combined with the theme parameter (e.g., background=false&theme=night).
  • +
  • Questions: set theme=transparent (deprecated, but still supported).
  • +
+ +

Disable downloads for an embedded question or dashboard

+ +
+
+ + + + + + + +

Disabling downloads is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

By default, Metabase will include a Download button on embedded questions, and an Export to PDF option on embedded dashboards. You can remove the option to download results by setting downloads=false in the embedding URL in the iframe’s src attribute, see customizing the appearance of static embeds.

+ +

If the download option is missing when you expected it to be available, check that the URL in the src attribute for your iframe has the parameter downloads=true.

+ +

Maximum request size

+ +

The maximum length of a static embedding URL (including all parameters) is the value of your MB_JETTY_REQUEST_HEADER_SIZE environment variable. The default is 8192 bytes.

+ +

If your static embedding URL exceeds the maximum header size, you’ll see a log message like URI too long. You can update the environment variable to accept larger headers. If you’re using a proxy server, you may need to set a corresponding property on the server as well.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/static-embedding.html b/_site/docs/doc-update-detection/embedding/static-embedding.html new file mode 100644 index 000000000..81f8fef1c --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/static-embedding.html @@ -0,0 +1,3269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Static embedding | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Static embedding

+ +

Also known as: standalone embedding, or signed embedding.

+ + + +

In general, embedding works by displaying a Metabase URL inside an iframe in your website. A static embed (or signed embed) is an iframe that’s loading a Metabase URL secured with a signed JSON Web Token (JWT). Metabase will only load the URL if the request supplies a JWT signed with the secret shared between your app and your Metabase. The JWT also includes a reference to the resource to load, e.g., the dashboard ID, and any values for locked parameters.

+ +

You can’t use static embeds with data sandboxes, drill-through, and user-specific data isn’t captured in usage analytics because signed JWTs don’t create user sessions (server-side sessions). For those features, check out interactive embedding.

+ +

You can, however, restrict data in static embeds for specific people or groups by locking parameters.

+ +

How static embedding works

+ +

If you want to set up interactive Metabase filters in your iframe, your web server will need to make requests to Metabase for updated data each time a website visitor updates the filter widget.

+ +

To ask for updated data from Metabase, your web server will generate a new Metabase embedding URL. For example, if a website visitor enters the value “true” in an embedded filter widget, your web server will generate a new embedding URL with an extra parameter:

+ +
your_metabase_embedding_url?filter=true
+
+ +

To prevent people from editing the embedding URL to get access to other parts of your Metabase (e.g., by changing the parameter to filter=company_secrets), your web server will add a signed JWT to the new embedding URL:

+ +
your_metabase_embedding_url/your_signed_jwt?filter=true
+
+ +

The signed JWT is generated using your Metabase secret key. The secret key tells Metabase that the request for filtered data can be trusted, so it’s safe to display the results at the new embedding URL. Note that this secret key is shared for all static embeds, so whoever has access to that key will have access to all embedded artifacts.

+ +

If you want to embed charts with additional interactive features, like drill-down and self-service querying, see Interactive embedding.

+ +

Turning on the embedding feature in Metabase

+ +
    +
  1. Go to Settings > Admin settings > Embedding.
  2. +
  3. Toggle the Enable embedding.
  4. +
+ +

Making a question or dashboard embeddable

+ +

Sharing button to embed dashboard

+ +

To create a static embed:

+ +
    +
  1. Go to the question or dashboard that you want to embed in your website.
  2. +
  3. Click on the sharing icon.
  4. +
  5. Select Embed.
  6. +
  7. Select Static embedding.
  8. +
  9. Optional: customize the appearance of the embed
  10. +
  11. Optional: Add parameters to the embed.
  12. +
  13. Click Publish.
  14. +
+ +

Preview

+ +

Adding the embedding URL to your website

+ +

The embedding URL for a question or dashboard is the Metabase URL that’ll be displayed in your website’s iframe. It’s generated by your web server using your Metabase site URL, signed JWT, and parameters:

+ +
metabase_site_url/embed/question/your_jwt_token?parameter_name=value
+
+ +

Once you’ve made a question or dashboard embeddable, you’ll need to put the embedding URL for that question or dashboard on your website:

+ +
    +
  1. Go to the question or dashboard > sharing icon > Embed.
  2. +
  3. Make any changes and copy the code.
  4. +
  5. Preview the code
  6. +
  7. Add the code to the server code that builds your website.
  8. +
  9. Add the frontend code to the code that generates the page where you want the embedded item to appear.
  10. +
+ +

For more examples, see our reference apps repo.

+ +

Previewing the code for an embed

+ +
    +
  1. Go to the question or dashboard > sharing icon > Embed this item in an application.
  2. +
  3. Click Code.
  4. +
  5. In the top code block, you’ll find the sample code for your web server. You’ll also find the iframe snippet to plug into your HTML template or single page app.
  6. +
+ +

When you make changes to the look and feel or parameter preview settings, Metabase will update the code and highlight the changes. Make sure to copy these changes to your actual server code.

+ +

Code samples for embedding

+ +

Metabase generates server code for:

+ +
    +
  • Clojure
  • +
  • Node.js
  • +
  • Python
  • +
  • Ruby
  • +
+ +

For iframe snippets:

+ +
    +
  • ERB
  • +
  • JSX
  • +
  • Mustache
  • +
  • Pug/Jade
  • +
+ +

If you serialize your Metabase, use Entity IDs in your static embeds

+ +

Using Entity IDs in your static embeds will make sure that the IDs are stable when exporting from one Metabase and importing to another Metabase.

+ +

To use an Entity ID in a static embed, all you need to do is edit the resource map in the payload used to sign your token. Replace the item’s (autopopulated) ID with its Entity ID and you’re done.

+ +

So, in the code below you’d change the { question: <ID> } to:

+ +
const payload = {
+  resource: { question: <Entity ID goes here> },
+  params: {},
+  exp: Math.round(Date.now() / 1000) + (10 * 60) // 10 minute expiration
+};
+
+ +

If you don’t serialize your Metabase, don’t worry about which ID you use; both will work just fine.

+ +

Editing an embedded question or dashboard

+ +

If you change the parameters of your embedded item:

+ +
    +
  1. After making your changes, copy the code Metabase generates.
  2. +
  3. Click Publish again.
  4. +
  5. Update the code on your server so that it matches the code generated by Metabase.
  6. +
+ +

Disabling embedding for a question or dashboard

+ +

You can find a list of all static embeds of questions and dashboards from Admin settings > Embedding > Static embedding > Manage.

+ +
    +
  1. Visit the embeddable question or dashboard.
  2. +
  3. Click on the sharing icon (square with an arrow pointing to the top right).
  4. +
  5. Select Embed.
  6. +
  7. Select Static embedding
  8. +
  9. Click Unpublish.
  10. +
+ +

Customizing the appearance of static embeds

+ +

See Customizing appearance of static embeds

+ +

Auto-refreshing the results of an embedded dashboard

+ +
+

Auto-refreshing is only available for dashboards, not questions.

+
+ +

To refresh the results of a dashboard at a specific cadence, you can parameterize the embedded URL with refresh. For example, to set an embedded dashboard to refresh every 60 seconds, you would append refresh=60 to the URL.

+ +

For example, the following code for generating an iframe URL for a dashboard would display the dashboard’s title and refresh its results every 60 seconds.

+ +
var iframeUrl =
+  METABASE_SITE_URL + "/embed/dashboard/" + token + "#titled=true&refresh=60";
+
+ +

For the full list options you can parameterize, see customizing the appearance of a static embed.

+ +

Removing the “Powered by Metabase” banner

+ +

Powered by Metabase

+ +

The banner appears on static embeds created with Metabase’s open-source version. To remove the banner, you’ll need to upgrade to a Pro or Enterprise plan.

+ +

Regenerating the static embedding secret key

+ +

Your embedding secret key is used to sign JWTs for all of your embedding URLs.

+ +
    +
  1. Go to Settings > Admin settings > Embedding.
  2. +
  3. On the Static embedding card, click on Manage.
  4. +
  5. Under Regenerate secret key, click Regenerate key.
  6. +
+ +

This key is shared across all static embeds. Whoever has access to this key could get access to all embedded artifacts, so keep this key secure. If you regenerate this key, you’ll need to update your server code with the new key.

+ +

Resizing dashboards to fit their content

+ +

Dashboards are a fixed aspect ratio, so if you’d like to ensure they’re automatically sized vertically to fit their contents you can use the iFrame Resizer script. Metabase serves a copy for convenience:

+ +
<script src="http://metabase.example.com/app/iframeResizer.js"></script>
+<iframe
+  src="http://metabase.example.com/embed/dashboard/TOKEN"
+  onload="iFrameResize({}, this)"
+></iframe>
+
+ +

Due to iframe-resizer’s licensing changes, we recommend that you use iframe-resizer version 4.3.2 or lower.

+ +

Custom destinations on dashboards in static embeds

+ +

You can only use the URL option for custom destinations on dashboards with static embedding. External URLs will open in a new tab or window.

+ +

You can propagate filter values into the external URL, unless the filter is locked.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/embedding/tsconfig.json b/_site/docs/doc-update-detection/embedding/tsconfig.json new file mode 100644 index 000000000..fd6209b24 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "paths": { + "@metabase/embedding-sdk-react": ["../../resources/embedding-sdk"], + "@metabase/embedding-sdk-react/*": ["../../resources/embedding-sdk/dist/nextjs.d.ts"] + }, + "allowJs": true, + "checkJs": true, + "moduleDetection": "force", + "noEmit": true, + "noImplicitAny": false + }, + "include": ["./**/snippets"] +} diff --git a/_site/docs/doc-update-detection/embedding/whitelabeling.html b/_site/docs/doc-update-detection/embedding/whitelabeling.html new file mode 100644 index 000000000..f05bdac44 --- /dev/null +++ b/_site/docs/doc-update-detection/embedding/whitelabeling.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide.html b/_site/docs/doc-update-detection/enterprise-guide.html new file mode 100644 index 000000000..9664adb8b --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/activating-the-enterprise-edition.html b/_site/docs/doc-update-detection/enterprise-guide/activating-the-enterprise-edition.html new file mode 100644 index 000000000..114cd93ce --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/activating-the-enterprise-edition.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/audit.html b/_site/docs/doc-update-detection/enterprise-guide/audit.html new file mode 100644 index 000000000..81bb78ef2 --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/audit.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/authenticating-with-jwt.html b/_site/docs/doc-update-detection/enterprise-guide/authenticating-with-jwt.html new file mode 100644 index 000000000..27ef7c08f --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/authenticating-with-jwt.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/authenticating-with-saml-azure-ad.html b/_site/docs/doc-update-detection/enterprise-guide/authenticating-with-saml-azure-ad.html new file mode 100644 index 000000000..fd412581a --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/authenticating-with-saml-azure-ad.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/authenticating-with-saml.html b/_site/docs/doc-update-detection/enterprise-guide/authenticating-with-saml.html new file mode 100644 index 000000000..5edcca848 --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/authenticating-with-saml.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/cache.html b/_site/docs/doc-update-detection/enterprise-guide/cache.html new file mode 100644 index 000000000..33a9961db --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/cache.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/customize-embeds.html b/_site/docs/doc-update-detection/enterprise-guide/customize-embeds.html new file mode 100644 index 000000000..f05bdac44 --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/customize-embeds.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/dashboards-subscriptions.html b/_site/docs/doc-update-detection/enterprise-guide/dashboards-subscriptions.html new file mode 100644 index 000000000..6e64cbb2c --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/dashboards-subscriptions.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/data-sandboxes.html b/_site/docs/doc-update-detection/enterprise-guide/data-sandboxes.html new file mode 100644 index 000000000..62c039fe9 --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/data-sandboxes.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/fonts.html b/_site/docs/doc-update-detection/enterprise-guide/fonts.html new file mode 100644 index 000000000..8fb13bef7 --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/fonts.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/full-app-embedding.html b/_site/docs/doc-update-detection/enterprise-guide/full-app-embedding.html new file mode 100644 index 000000000..b845c0ecd --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/full-app-embedding.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/saml-auth0.html b/_site/docs/doc-update-detection/enterprise-guide/saml-auth0.html new file mode 100644 index 000000000..d909ad02a --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/saml-auth0.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/saml-google.html b/_site/docs/doc-update-detection/enterprise-guide/saml-google.html new file mode 100644 index 000000000..695ba8625 --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/saml-google.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/saml-keycloak.html b/_site/docs/doc-update-detection/enterprise-guide/saml-keycloak.html new file mode 100644 index 000000000..673bf1afc --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/saml-keycloak.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/serialization.html b/_site/docs/doc-update-detection/enterprise-guide/serialization.html new file mode 100644 index 000000000..baf660333 --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/serialization.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/sql-snippets.html b/_site/docs/doc-update-detection/enterprise-guide/sql-snippets.html new file mode 100644 index 000000000..b872be6fe --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/sql-snippets.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/tools.html b/_site/docs/doc-update-detection/enterprise-guide/tools.html new file mode 100644 index 000000000..873a8df14 --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/tools.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/enterprise-guide/whitelabeling.html b/_site/docs/doc-update-detection/enterprise-guide/whitelabeling.html new file mode 100644 index 000000000..f05bdac44 --- /dev/null +++ b/_site/docs/doc-update-detection/enterprise-guide/whitelabeling.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/exploration-and-organization/collections.html b/_site/docs/doc-update-detection/exploration-and-organization/collections.html new file mode 100644 index 000000000..a79db0a21 --- /dev/null +++ b/_site/docs/doc-update-detection/exploration-and-organization/collections.html @@ -0,0 +1,3193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Collections | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Collections

+ +

After your team has been using Metabase for a while, you’ll probably end up with lots of saved questions and dashboards.

+ +

Our analytics

+ +

Collections are the main way to organize questions, dashboards, and models. You can think of them like folders or directories. You can nest collections in other collections, and move collections around. One thing to note is that a single item, like a question or dashboard, can only be in one collection at a time (excluding parent collections).

+ +

Collection types

+ +

Regular collections

+ +

They’re like file-system folders. You can put stuff in them.

+ +

Official collections

+ +
+
+ + + + + + + +

Official collections is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Official collections

+ +

Metabase admins can designate collections as “official” with the following effects:

+ +
    +
  • These collections have a yellow badge to let people know that the items in the collection are the ones people should be looking at (or whatever “official” means to you).
  • +
  • Questions in Official collections added to Dashboards that are not in Official collections will show an Official badge next to their name on the Dashboard.
  • +
  • Questions and dashboards in Official collections are also more likely to show up at the top of search results.
  • +
+ +

Pairing Official badges with verified items can help everyone in your Metabase sort out which questions people can trust.

+ +

To add an Official badge to a collection, an admin can visit the collection and click on the dot dot dot menu () and select Make collection official. Admins can also remove an Official badge in the same menu. Admins can also mark a collection as Official or not when they first create the collection.

+ +

Collection permissions

+ +

Administrators can give you different kinds of access to each collection:

+ +
    +
  • View access: you can see the collection and its contents, but you can’t modify anything or put anything new into the collection.
  • +
  • Curate access: you can edit, move, or delete the collection and its contents. You can also move or save new things in it and create new collections inside of it, and can also pin items in the collection to the top of the screen. Only administrators can edit permissions for collections, however.
  • +
  • No access: you can’t see the collection or its contents. If you have access to a dashboard, but it contains questions that are saved in a collection you don’t have access to, those questions will show a permissions notification instead of the chart or table.
  • +
+ +

Your personal collection

+ +

In addition to the collections you and your teammates have made, you’ll also always have your own personal collection that only you and administrators can see. To find it, click on the “browse all items” button on the homepage and click on “my personal collection” in the list of collections.

+ +

You can use your personal collection as a scratch space to put experiments and explorations that you don’t think would be particularly interesting to the rest of your team, or as a work-in-progress space where you can work on things and then move them to a shared place once they’re ready.

+ +

To share items in your personal collection, for example to add a question in your personal collection to a dashboard in a public collection, you’ll first need to move that item to a public collection.

+ +

Pinned items

+ +

In each collection, you can pin important or useful dashboards, models, and questions to make them stick to the top of the screen. Pinned items will also be displayed as large cards to make them stand out well.

+ +

Pins

+ +

To pin and un-pin things in a collection, you need to have Curate permissions for that collection.

+ +
    +
  • +

    To pin an item, find the item on the collection page, go into the three dot menu (), and select Pin this.

    +
  • +
  • +

    To unpin a pinned item, hover over the pinned card, go to the three dot menu (), and select Unpin.

    +
  • +
+ +

For pinned questions, you can also choose whether to display the visualization from the three dot menu ().

+ +

Show pinned viz

+ +

Pinned items will appear pinned for all people looking at the collection. If you just want to organize your favorite items, you should bookmark them (only you can see your bookmarks).

+ +

Moving items from collection to collection

+ +

To move an item from one collection to another, just click and drag it onto the collection where you want it to go. You can also click on the the three dot menu () menu to the right of the item and pick the Move action.

+ +

If you’re trying to move several things at once, click on the checkboxes next to the items’ icons to select them, then click the Move action that pops up at the bottom of the screen.

+ +

Selecting questions

+ +

Note that you have to have Curate permission for the collection that you’re moving a question into and the collection you’re moving the question out of. Metabase admins can move items into (and out of) anyone’s personal collection.

+ +

Moving questions into dashboards

+ +

You can move any question from a collection to a dashboard (and vice versa). Visit a question, click on the three-dot menu () and select Move. Pick a destination and your question will enjoy its new home.

+ +

Bulk-moving questions into dashboards

+ +

If a collection has questions that have been added to dashboards in that collection, you can move the questions into their dashboards to declutter the collection.

+ +

To bulk-move questions into their dashboards, visit a collection page, click on the three-dot menu (), and select Move questions into their dashboards. Metabase will pop up a modal to let you know what’s going on:

+ +
    +
  • If a question only appears in a single dashboard in this collection, it’ll be moved into that dashboard to declutter the collection.
  • +
  • Permissions won’t change.
  • +
+ +

You can preview the changes before initiating the move. Hit the preview button to see which questions will be moved into which dashboards. No questions will be moved into dashboards they weren’t already added to. All this move does is “save” the questions to the dashboard rather than the collection.

+ +

In general, you want to save questions to dashboards unless you know people will want to re-use that question in multiple dashboards.

+ +

Cleaning up collections

+ +
+
+ + + + + + + +

Collection cleanup is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

It’s possible to ask too many questions. Fortunately, you can clean up collections by trashing items that people haven’t even looked at for a period of time. Cleaning up old questions and dashboards can keep your Metabase from getting too cluttered, and you can always resurrect items from the trash if you need to.

+ +

On a collection page, click on the three-dot menu () and select Clear out unused items. Metabase will pull up a modal where you can select unused items to move to the trash. You can set how long items need to go unnoticed before they’re culled by setting Not used in over, which you can set to trash items from one month ago to over two years ago. There’s also a toggle to include/exclude items in sub-collections.

+ +

Events and timelines

+ +

You can add events to collections, and organize those events into timelines. See Events and timelines.

+ +

Uploading data

+ +

You can upload data to collections. See Uploading data]

+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/exploration-and-organization/content-verification.html b/_site/docs/doc-update-detection/exploration-and-organization/content-verification.html new file mode 100644 index 000000000..eb258c915 --- /dev/null +++ b/_site/docs/doc-update-detection/exploration-and-organization/content-verification.html @@ -0,0 +1,3112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Content verification | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Content verification

+ +
+
+ + + + + + + +

Content verification is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Verified icon

+ +

Admins can verify items to let others know that the content is accurate and up to date.

+ +

Benefits of verifying an item

+ +
    +
  • Verified items get a fancy blue checkmark next to them.
  • +
  • They show up higher in search suggestions and results.
  • +
  • The models and metrics browsers allow you to filter for verified items.
  • +
+ +

Verified models toggle

+ +

Verifying items

+ +

To verify an item, an admin can click on the three-dot menu () in the upper right when viewing that item and select: Verify this item.

+ +

Verify this dashboard

+ +

Removing verification status

+ +

To remove verification from an item, admins can:

+ +
    +
  1. Visit the item.
  2. +
  3. Click on the three-dot menu ().
  4. +
  5. Select remove verification.
  6. +
+ +

Changes to queries require re-verification

+ +

If anyone makes any changes to a question, metric, or model’s query, Metabase will remove the verification status (the check mark will disappear). The logic here is that changing the results in any way should require re-verification.

+ +

Dashboards verification works a little differently (since there’s no underlying query). Dashboard verification is sticky; you can modify a verified dashboard and it’ll retain its verified status.

+ +

Verifiable items

+ +

Admins can verify the following items:

+ + + +

Dashboard verification status has no affect on its questions. Questions must be verified independently.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/exploration-and-organization/data-model-reference.html b/_site/docs/doc-update-detection/exploration-and-organization/data-model-reference.html new file mode 100644 index 000000000..148468b09 --- /dev/null +++ b/_site/docs/doc-update-detection/exploration-and-organization/data-model-reference.html @@ -0,0 +1,3073 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Data reference | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Data reference

+ +

You can open the data reference from:

+ +
    +
  • The Metabase sidebar > Browse > Databases > Learn about our data.
  • +
  • Hovering over a table in the data browser and clicking on the book icon that appears.
  • +
  • The native/SQL > Book icon.
  • +
+ +

Browse data reference

+ +

The data reference is a collection of pages organized by database, then tables in that database (the same structure you use to pick data). The data reference section is a great place to find information about the data types of columns in your data.

+ +

Data reference in the native editor

+ +

Sometimes when you’re writing a query, you might forget the exact names of different tables or columns, or which table contains what. That’s where the Data reference comes in handy.

+ +

To bring up the data reference panel in the native/SQL editor, click on the open book icon.

+ +

This panel lists all the databases you have access to, and the models and tables, and the fields inside of them.

+ +

Data reference sidebar

+ +

Click on the model or table you would like to explore further to see a description of it and a list of all the columns it has. Each table or column will only contain a description if your admin wrote something in the Table Metadata section of the Admin Panel.

+ +

If you click on a column you’re interested in, you’ll see a description of its contents, as well as a list of sample values for columns that don’t have a huge number of distinct values.

+ +

Connections

+ +

In the data reference sidebar, under Connections, you can find a list of table relationships (defined by foreign keys).

+ +

If a foreign key relationship exists in your database, but doesn’t show up in your Metabase, your Metabase admin will need to update your Metabase Table Metadata.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/exploration-and-organization/delete-and-restore.html b/_site/docs/doc-update-detection/exploration-and-organization/delete-and-restore.html new file mode 100644 index 000000000..40898b5b6 --- /dev/null +++ b/_site/docs/doc-update-detection/exploration-and-organization/delete-and-restore.html @@ -0,0 +1,3291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Delete and restore | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Delete and restore

+ +

Sometimes your questions, dashboards, models, or collections outlive their usefulness. You can send outdated items to Trash.

+ +

Move to trash

+ +

Items in Trash won’t show up in search (unless you use advanced search filters), and you won’t be able to use them to create new questions and dashboards.

+ +

Moving items to Trash isn’t permanent; you’ll be able to restore them to their original parent collection, or move them to another collection. But if you’d like to delete items permanently, you can do that too.

+ +

Deleting an item will affect any dashboards, subscriptions, or SQL questions that depend on that item, so be careful!

+ +

See items in Trash

+ +

You can find Trash at the bottom of the left navigation sidebar below all the collections:

+ +

Trash

+ +

You can think of Trash as a special type of collection. In Trash, you can see deleted items from the collections that you have Curate permissions on. You can order deleted items by type (questions, dashboards, etc), time it was deleted, and who deleted it.

+ +

You;’ll be able to see the contents of deleted dashboards, questions, and models in Trash, but you won’t be able to modify them.

+ +

Search in Trash

+ +

To find items in Trash, you can use advanced search with a “Search items in trash” toggle.

+ +

Deleting and restoring items

+ +

To move an item (question, dashboard, model, or collection) to Trash:

+ +
    +
  1. Go to the question you want to delete;
  2. +
  3. Click on the three dots menu;
  4. +
  5. Select “Move to trash”.
  6. +
+ +

When a collection is moved to the trash, Metabase moves all items in the collection to the trash as well.

+ +

You’ll still be able to see the contents of the items in Trash, but you won’t be able to modify them or use them as a source for other questions.

+ +

If you need to delete multiple items from the same collection, you can delete them in bulk:

+ +
    +
  1. Go to the collection containing items you want to delete;
  2. +
  3. Click the checkboxes next to the items to select them;
  4. +
  5. Select “Move to trash”
  6. +
+ +

To restore an item:

+ +
    +
  1. Go to Trash;
  2. +
  3. Find the item you’d like to delete. You can sort deleted items to make it easier to find the item, or search for your question in Trash;
  4. +
  5. Click on the checkbox next to the item to select it;
  6. +
  7. Select “Restore”.
  8. +
+ +
+

Restoring a collection will also restore all the items from that collection.

+
+ +

If the item’s original parent collection has been deleted as well, you won’t see an option to Restore. You’ll still be able to move the it from Trash to a different collection.

+ +

Cleaning up collections

+ +

To move older, unused items in bulk to the trash, check out cleaning up collections.

+ + + +

Deleting or restoring an item will affect other items that depend on that item.

+ +

Questions

+ +

What happens to related items when you delete a question?

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Related itemIn TrashPermanently deletedRestored
DashboardCard removedCard removedCard restored
Question based on deleted questionWorks normallyBreaks with Card not found errorWorks normally
AlertsRemovedRemovedNot restored
+ +

Dashboards

+ +

What happens to related items when you delete a dashboard?

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Related itemIn TrashPermanently deletedRestored
Questions saved to that dashboardMoved to trashDeletedRestored
Questions not saved to that dashboardWorks normallyWorks normallyWorks normally
SubscriptionsDeactivatedDeactivatedRestored
Custom homepageRevert to default homepageRevert to default homepageRestored
+ +

Model

+ +

What happens to related items when you delete a model?

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Related itemIn TrashPermanently deletedRestored
Question based on deleted questionWorks normallyBreaks with Card not found errorReactivated
DashboardCard removedCard removedCard restored
ActionWorks normallyDeletedWorks normally
+ +

Collections

+ +

What happens to related items when you delete a collection?

+ + + + + + + + + + + + + + + + + + +
Related itemIn TrashPermanently deletedRestored
All items and subcollections in the collectionIn TrashN/ARestored
+ +
+

You can’t permanently delete collections

+
+ +

Permanently deleting items

+ +

Moving an item to Trash doesn’t delete the item completely: you’ll be able to restore the item from the Trash.

+ +

To permanently delete an item:

+ +
    +
  1. Go to Trash;
  2. +
  3. Find the item you’d like to delete;
  4. +
  5. Click on the checkbox next to the item to select it;
  6. +
  7. Select “Permanently delete”. If you click this button, you won’t be able to recover the item. It’ll be lost to the void.
  8. +
+ +
+

You can’t permanently delete collections

+
+ +

Deleting and restoring events and timelines

+ +

Events and timelines can be archived and unarchived. See Archiving Events and timelines.

+ +

You won’t see archived Events and Timelines in Trash. To see archived events and timelines, you need to access them from the collection’s page.

+ +

Deleting and restoring Snippets

+ +

Snippets can be archived and unarchived. See Archiving Snippets.

+ +

You won’t see archived Snippets in Trash. To see archived Snippets, you need to access them from the Snippet menu.

+ +

Deleting segments

+ +

Segments can be retired. See Retiring Segments.

+ +

You won’t see retired Segments in Trash.

+ +

Deleting subscriptions and alerts

+ +

See Deleting a subscription and Deleting alerts.

+ +

Deleting databases

+ +

See Deleting databases.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/exploration-and-organization/events-and-timelines.html b/_site/docs/doc-update-detection/exploration-and-organization/events-and-timelines.html new file mode 100644 index 000000000..6e80ecee5 --- /dev/null +++ b/_site/docs/doc-update-detection/exploration-and-organization/events-and-timelines.html @@ -0,0 +1,3184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Events and timelines | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Events and timelines

+ +

A lot of discussions around data have a moment when someone asks a question related to a specific point in time: “Wait, what’s the spike in March again?”, or “When did the new widget launch?”

+ +

Events and timelines are a way to capture that chronological knowledge and make it available when you need it, in context (that is, when you’re viewing a chart). Events are a great way to store institutional knowledge about what happened and when, so people (including yourself three months from now) won’t have to figure out (again) why the line chart spiked back in March.

+ +

Events

+ +

An event on a time series

+ +

An event is basically a date + a title + a description + an icon. You can add events to Metabase to show important milestones, launches, or anything else, right alongside your data.

+ +

Metabase will only display events on time series charts when viewing an individual question. Metabase won’t display events on charts in dashboard cards.

+ +

Timelines

+ +

Timelines are groups of events associated with a collection.

+ +

Timeline sidebar

+ +

For example, you may want to have a timeline that contains important email or sales dates, or an outages timeline that tracks downtime. You can move events between timelines, and move timelines from collection to collection.

+ +

Collections can have timelines, and timelines can contain events. In practice what this means is that events you’ve added to a timeline will show up on time series questions stored in the same collection as that timeline.

+ +
    +
  • If you don’t explicitly create a timeline yet, but you do create events, Metabase will automatically create a timeline for you (which acts as the default timeline for the collection).
  • +
  • You can have multiple timelines for the same collection.
  • +
  • Timelines associated with collections do not apply to that collection’s sub-collections.
  • +
+ +

Adding events when viewing a collection

+ +

When viewing a collection, you can view, add, or edit events by clicking on the calendar icon in the upper right.

+ +

In a collection, view or add events by clicking on the calendar icon

+ +

Once you create an event, the event will show up in charts in the collection, provided:

+ +
    +
  • The date of the event falls within the chart’s time range.
  • +
  • The timeline is visible (more on that below).
  • +
+ +

You’ll see an icon along the x-axis that plots the event. A vertical line will extend from the event to show when the data plotted on the chart intersects with the event.

+ +

An event on a chart

+ +

Adding events when viewing a question

+ +

If your question is a time series, you can click on the Calendar in the bottom right of the question, and Metabase will open the timeline sidebar. Metabase will list any timelines and their events that fall in the range of your time series. You can:

+ +
    +
  • Toggle timeline visibility (including timelines from other collections)
  • +
  • Add a new event (even if you haven’t saved the question yet).
  • +
  • Edit, move, or archive an event.
  • +
+ +

Viewing events and timelines on a chart from a different collection

+ +

If you’re viewing a question with a time series chart from a different collection, you can temporarily apply a timeline to the chart by clicking on the calendar icon in the bottom right of the question and selecting the timeline and events you want to display.

+ +

These selections are temporary; if you reload the question, Metabase will drop the events from the chart.

+ +

To hide the timeline and its events on a chart

+ +

To temporarily hide the events from a chart:

+ +
    +
  1. Click on the calendar icon in the bottom right.
  2. +
  3. Uncheck the timeline or event.
  4. +
+ +

Your selections will reset on reload.

+ +

To permanently hide the timeline and its events, you’ll need to archive the timeline. Alternatively, you could move the question to a different collection.

+ +

Edit an event

+ +

Edit an event

+ +

To edit an event:

+ +
    +
  1. Click the calendar icon in the top right of a collection.
  2. +
  3. Go to the timeline that contains the event, click on the event’s three-dot menu ().
  4. +
  5. Select: +
      +
    • Edit event: its title, description, and icon.
    • +
    • Move event: to another timeline.
    • +
    • Archive event: to hide the event from charts.
    • +
    +
  6. +
+ +

Archiving timelines

+ +

To archive a timeline:

+ +
    +
  1. Go to the timeline’s collection and click on the calendar icon in the top right.
  2. +
  3. Select the timeline, then click on the three-dot menu (). If the collection only has one timeline, click on the three-dot menu ().
  4. +
  5. Select Edit timeline details.
  6. +
  7. Click on the red Archive timeline and all events.
  8. +
+ +

View archived events and timelines

+ +
+

Archived events and timelines can only be viewed from the collection. They don’t show up in the Trash.

+
+ +

To view (and resurrect) archived timelines and events:

+ +
    +
  1. Click on the Calendar icon in the relevant collection.
  2. +
  3. Click on the three-dot menu menu.
  4. +
  5. Select View archived timelines. Metabase will display archived events or timelines.
  6. +
  7. If you want to unarchive an item, click on the three-dot menu next to the event or timeline and select the Unarchive option.
  8. +
+ +

To permanently delete an archived event or timeline, click on the three-dot menu () and select Delete.

+ +

Then you can delete the archived events from the View archived events modal, or timelines from the View archived timelines modal.

+ +

Event and timeline permissions

+ +

Event and timeline permissions depend on your collection permissions.

+ +
    +
  • View access: you can view the collection’s events and timelines. You can also temporarily apply timelines and events to time series in other collections.
  • +
  • Curate access. Anyone with curate access to a collection can add events and timelines to that collection.
  • +
+ +

Make a timeline and its events available for everyone

+ +

If you want the event and timeline to be available to everyone, create the timeline in a collection that the All Users group has access to, as by default everyone is in the All Users group.

+ +

Note that for questions outside of that collection, you can only temporarily apply those timelines to charts. The timelines won’t appear automatically when you reload the chart.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/exploration-and-organization/exploration.html b/_site/docs/doc-update-detection/exploration-and-organization/exploration.html new file mode 100644 index 000000000..83480c00a --- /dev/null +++ b/_site/docs/doc-update-detection/exploration-and-organization/exploration.html @@ -0,0 +1,3176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Basic exploration | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Basic exploration

+ +

See what your teammates have made

+ +

As long as you’re not the very first user in your team’s Metabase, the easiest way to start exploring your data is by looking at dashboards, charts, and lists that your teammates have already created. The best place to start is by checking out any dashboards that might be pinned on your home page, or in collections you have access to.

+ +

Command palette

+ +

The command palette lets you create new things, search your content, or jump to anywhere in your Metabase.

+ +

To bring up the command palette, hit cmd/ctrl + k. That’s cmd + k for Macs, or ctrl + k for Windows PCs.

+ +

You can use the command palette to:

+ +
    +
  • Create new things (like new questions and dashboards)
  • +
  • Find things (saved questions, dashboards, models, etc.)
  • +
  • Find and jump to Admin and account settings.
  • +
+ +

So anytime you want to do or find anything in Metabase, just hit cmd/ctrl + k and start typing what you want to do.

+ +
+

The command palette is currently unavailable in interactive embedding contexts.

+
+ + + +

To filter your search results, hit cmd/ctrl + k to bring up the command palette and enter your search term. The first result is a link to “Search and filter all X results”.

+ +

Search results

+ +

Searches take into account items’ titles, descriptions, and other metadata — you can even search the contents of your SQL queries. For example, you can search for things like SELECT escape_pod FROM mothership and find that one question you worked on six months ago. The results will display which collection each item is saved in, what kind of object it is, and whether it’s pinned. Note that you’ll only ever see items in that are in collections you have permission to view.

+ +

You can search by:

+ +
    +
  • Content type: dashboard, question, model, collection, database, table.
  • +
  • Creator: who made the thing.
  • +
  • Last editor: who made the last saved change on the thing.
  • +
  • Creation date: when the thing entered our universe.
  • +
  • Last edit date: when someone last cared enough to update the thing.
  • +
  • Verified items only. Only show items that have been verified.
  • +
  • Search the contents of native queries: search through the SQL/native code in questions.
  • +
  • Search items in trash: include the depths of oblivion in your search.
  • +
+ +

Browse your databases

+ +
+

Whether a group has access to the database browser depends on the group’s Create queries permission.

+
+ +

Browse databases

+ +

The left sidebar lists your databases, models, and metrics.

+ +

Pro and Enterprise plans include the ability to filter for verified models and metrics.

+ +

The database browser will list all the databases connected to your Metabase. Hover over a table and click on the bolt icon to X-ray the table, or click on the book icon to view more info about the table: its fields and their descriptions (if any), what questions are based on that table, and more.

+ +

To learn more, see Exploring data with Metabase’s data browser.

+ +

Exploring collections

+ +

Collections in Metabase are a lot like folders. They’re where Metabase keeps all your team’s dashboards and charts.

+ +

A collection

+ +

Your teammates might have pinned some items to the top of your collection.

+ + + +

Collections have a list of any other items that are saved within them, and you can see what other collections are saved inside of the current one by checking out the navigation sidebar.

+ +

Exploring dashboards

+ +

Dashboards are a set of questions and text cards that you want to be able to refer to regularly.

+ +

If you click on a part of a chart, such as a bar in a bar chart, or a dot on a line chart, you’ll see the Action menu, with actions you can take to dive deeper into that result, branch off from it in a different direction, or see automatic insights to X-ray the data.

+ +

Drill-through menu

+ +

In this example of orders by product category per month, clicking on a data point on this line chart gives us the ability to:

+ +
    +
  • See these Orders: See a list of the orders for a particular month.
  • +
  • See this month by week.
  • +
  • Break out by …: See things like the Gizmo orders in June 2023 broken out by the status of the customer (e.g., new or VIP). Different charts will have different breakout options, such as Location and Time.
  • +
  • Automatic insights: See orders for a particular category over a shorter time range.
  • +
  • Filter by this value: update the chart based on the value you clicked: equal to, less than, greater than, or not equal to.
  • +
+ +
+

Note that while charts created with SQL currently only have limited drill-through menu, you can add SQL questions to a dashboard and customize their click behavior. You can send people to a custom destination (like another dashboard or an external URL), or have the clicked value update a dashboard filter.

+
+ +

Clicking on a table cell will often allow you to filter the results using a comparison operator, like =, >, or <. For example, you can click on a table cell, and select the less than operator < to filter for values that are less than the selected value.

+ +

Comparison operator filters

+ +

Lastly, clicking on the ID of an item in a table gives you the option to go to a detail view for that single record. For example, you can click on a customer’s ID to see the profile view for that customer.

+ +

Detail view

+ +

When you add questions to a dashboard, you can have even more control over what happens when people click on your chart. In addition to the default drill-through menu, you can add a custom destination or update a filter. Check out interactive dashboards.

+ +

Bookmarks

+ +

Bookmarks are a way to quickly get back to things you visit frequently (or have been working on recently). Bookmarked items show up in the main navigation sidebar above collections.

+ +

To bookmark an item, look for the ribbon icon in the upper right corner of the item’s page. You can bookmark:

+ +
    +
  • Questions
  • +
  • Models
  • +
  • Dashboards
  • +
  • Collections
  • +
+ +

To add or remove a bookmark from an item, click on the three-dot menu () next to the item in the collection.

+ +

Some things to remember with bookmarks:

+ +
    +
  • Bookmarks are personal; other people can’t see your bookmarks. If you want to highlight something for everyone, you’ll want to put it in an official collection and/or pin the item in the collection (see collections).
  • +
  • If you end up bookmarking a lot of items, you can collapse the bookmarks section in the sidebar (or remove the bookmarks that are just getting in your way).
  • +
  • Items that you bookmark will get a boost in your search results (but not the search results of other people).
  • +
  • To reorder bookmarks, simply drag and drop them in the sidebar.
  • +
+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/exploration-and-organization/history.html b/_site/docs/doc-update-detection/exploration-and-organization/history.html new file mode 100644 index 000000000..8e818879f --- /dev/null +++ b/_site/docs/doc-update-detection/exploration-and-organization/history.html @@ -0,0 +1,3063 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +History | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

History

+ +

For questions, dashboards, and models, Metabase keeps a version history for the previous fifteen versions of that item. You can view changes, and revert to previous versions.

+ +

Viewing tracked changes

+ +
    +
  1. Go to your question, dashboard, or model.
  2. +
  3. Click the info icon.
  4. +
  5. Click on the History tab.
  6. +
  7. The History tab will display the item’s history of up to 15 versions.
  8. +
+ +

Metabase will keep track of a version each time you save, move, revert, move to Trash, or verify an item.

+ +

Reverting to previous versions

+ +
    +
  1. Go to your question, dashboard, or model.
  2. +
  3. Click the info icon (an i in a circle).
  4. +
  5. A sidebar will appear with up to fifteen previous versions.
  6. +
  7. Click on the back arrow beside a version to revert your item to that point in time.
  8. +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/DataReference.png b/_site/docs/doc-update-detection/exploration-and-organization/images/DataReference.png new file mode 100644 index 000000000..9912bd827 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/DataReference.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/append-data.png b/_site/docs/doc-update-detection/exploration-and-organization/images/append-data.png new file mode 100644 index 000000000..df5046c6b Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/append-data.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/automatic-insights.png b/_site/docs/doc-update-detection/exploration-and-organization/images/automatic-insights.png new file mode 100644 index 000000000..24cb911ca Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/automatic-insights.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/browse-data-x-ray.png b/_site/docs/doc-update-detection/exploration-and-organization/images/browse-data-x-ray.png new file mode 100644 index 000000000..c1c8a8380 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/browse-data-x-ray.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/browse-data.png b/_site/docs/doc-update-detection/exploration-and-organization/images/browse-data.png new file mode 100644 index 000000000..47b9e402e Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/browse-data.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/collection-detail.png b/_site/docs/doc-update-detection/exploration-and-organization/images/collection-detail.png new file mode 100644 index 000000000..f54c9f844 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/collection-detail.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/comparison-operator-filters.png b/_site/docs/doc-update-detection/exploration-and-organization/images/comparison-operator-filters.png new file mode 100644 index 000000000..e43d51fe3 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/comparison-operator-filters.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/data-reference.png b/_site/docs/doc-update-detection/exploration-and-organization/images/data-reference.png new file mode 100644 index 000000000..cfca7fa3b Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/data-reference.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/detail-view.png b/_site/docs/doc-update-detection/exploration-and-organization/images/detail-view.png new file mode 100644 index 000000000..2f5ed3f84 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/detail-view.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/edit-an-event.png b/_site/docs/doc-update-detection/exploration-and-organization/images/edit-an-event.png new file mode 100644 index 000000000..5ba8358f3 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/edit-an-event.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/event-calendar.png b/_site/docs/doc-update-detection/exploration-and-organization/images/event-calendar.png new file mode 100644 index 000000000..00659553c Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/event-calendar.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/event-on-a-time-series.png b/_site/docs/doc-update-detection/exploration-and-organization/images/event-on-a-time-series.png new file mode 100644 index 000000000..ba472e324 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/event-on-a-time-series.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/example-event.png b/_site/docs/doc-update-detection/exploration-and-organization/images/example-event.png new file mode 100644 index 000000000..440199cd8 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/example-event.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/move-to-trash.png b/_site/docs/doc-update-detection/exploration-and-organization/images/move-to-trash.png new file mode 100644 index 000000000..71f39c267 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/move-to-trash.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/official-collection.png b/_site/docs/doc-update-detection/exploration-and-organization/images/official-collection.png new file mode 100644 index 000000000..f882ac1e8 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/official-collection.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/our-analytics-page.png b/_site/docs/doc-update-detection/exploration-and-organization/images/our-analytics-page.png new file mode 100644 index 000000000..2be512d7e Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/our-analytics-page.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/pinned-items.png b/_site/docs/doc-update-detection/exploration-and-organization/images/pinned-items.png new file mode 100644 index 000000000..cb03f09de Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/pinned-items.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/pinned-show-viz.png b/_site/docs/doc-update-detection/exploration-and-organization/images/pinned-show-viz.png new file mode 100644 index 000000000..e6e06dfd6 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/pinned-show-viz.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/question-checkbox.png b/_site/docs/doc-update-detection/exploration-and-organization/images/question-checkbox.png new file mode 100644 index 000000000..ad9371b3a Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/question-checkbox.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/search-results.png b/_site/docs/doc-update-detection/exploration-and-organization/images/search-results.png new file mode 100644 index 000000000..b2efa426d Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/search-results.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/timeline-sidebar.png b/_site/docs/doc-update-detection/exploration-and-organization/images/timeline-sidebar.png new file mode 100644 index 000000000..cb96cd016 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/timeline-sidebar.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/trash.png b/_site/docs/doc-update-detection/exploration-and-organization/images/trash.png new file mode 100644 index 000000000..c7f581a8e Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/trash.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/verified-icon.png b/_site/docs/doc-update-detection/exploration-and-organization/images/verified-icon.png new file mode 100644 index 000000000..1b6ccf96f Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/verified-icon.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/verified-only.png b/_site/docs/doc-update-detection/exploration-and-organization/images/verified-only.png new file mode 100644 index 000000000..d07d696f8 Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/verified-only.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/verify-this-dashboard.png b/_site/docs/doc-update-detection/exploration-and-organization/images/verify-this-dashboard.png new file mode 100644 index 000000000..a1887a5df Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/verify-this-dashboard.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/images/x-ray-example.png b/_site/docs/doc-update-detection/exploration-and-organization/images/x-ray-example.png new file mode 100644 index 000000000..393680d0d Binary files /dev/null and b/_site/docs/doc-update-detection/exploration-and-organization/images/x-ray-example.png differ diff --git a/_site/docs/doc-update-detection/exploration-and-organization/start.html b/_site/docs/doc-update-detection/exploration-and-organization/start.html new file mode 100644 index 000000000..6e4495b05 --- /dev/null +++ b/_site/docs/doc-update-detection/exploration-and-organization/start.html @@ -0,0 +1,3075 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Organization overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Organization overview

+ +

Tools for finding things and keeping your Metabase organized.

+ +

Basic exploration

+ +

Find data, explore questions and dashboards, and bookmark your favorites.

+ +

Collections

+ +

Organize questions, dashboards, and models with collections.

+ +

History

+ +

View changes to a question, dashboard or model and revert to previous versions.

+ +

Delete and restore items

+ +

Move outdated outdated questions, models, and dashboards to trash, or delete them permanently.

+ +

Data reference

+ +

Documentation that helps you understand your data sources: tables, columns, metrics, and more.

+ +

Events and timelines

+ +

Add events to timelines to annotate charts.

+ +

X-ray your data

+ +

X-rays are a fast and easy way to get automatic insights and explorations of your data.

+ +

Content verification

+ +

Admins can verify items to let people know the data is accurate and up to date.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/exploration-and-organization/uploads.html b/_site/docs/doc-update-detection/exploration-and-organization/uploads.html new file mode 100644 index 000000000..ad65fa423 --- /dev/null +++ b/_site/docs/doc-update-detection/exploration-and-organization/uploads.html @@ -0,0 +1,3087 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Uploading data | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Uploading data

+ +

If an admin has set up uploads, you can upload CSV data by clicking on the Upload icon in the top right of the collection page.

+ +

Upload CSV data.

+ +

Create, append, or replace models with uploads

+ +

When you upload a CSV file, Metabase may ask to select a destination for that upload (depending on whether there are other uploads).

+ +

If your CSV has the same columns as a model from a previously uploaded file, you can append data to that model. Otherwise, you can create a new model. if you want to:

+ + + +

Metabase will create a model that contains that CSV data, as well as the model’s underlying table.

+ +

Uploads will only be available if your admin has enabled uploads for your Metabase, and you’re in a group with Unrestricted access to the schema used to store those uploads. See Uploading data.

+ +

Appending to a model created by an upload

+ +

You can upload additional CSV data to an existing model created by a previous CSV upload.

+ +

Append data to existing upload model

+ +

The uploaded CSV must have the same column name, order, and type as the columns in the model. Metabase will look for a header row to check that the column names are the same. So if you split a large CSV into multiple CSVs, make sure to include header rows for all of the files.

+ +

When appending, Metabase will simply insert the rows into the underlying table, which will update the model that sits on top of that table. If you have duplicate rows from one upload to the next, Metabase will preserve those duplicate rows.

+ +

The upload icon will only be visible on models created by uploads.

+ +

Replacing the data of an uploaded model

+ +

Instead of deleting a model and recreating it, you can replace the underlying data with an updated spreadsheet.

+ +

Like appending to uploaded models, replacing the uploaded CSV data with a new CSV file requires the columns and headings to match.

+ +

If you delete the uploaded table, you won’t be able to replace the model’s data.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/exploration-and-organization/x-rays.html b/_site/docs/doc-update-detection/exploration-and-organization/x-rays.html new file mode 100644 index 000000000..875daf9bd --- /dev/null +++ b/_site/docs/doc-update-detection/exploration-and-organization/x-rays.html @@ -0,0 +1,3107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +X-rays | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

X-rays

+ +

X-rays are a way to get automatic insights and explorations of your data.

+ +

Get automatic insights when clicking on a chart

+ +

One great way to explore your data in general in Metabase is to click on points of interest in charts and selecting Automatic insights.

+ +

Automatic insights in the drill-through menu

+ +

Metabase will give you some options:

+ +
    +
  • X-ray
  • +
  • Compare to the rest
  • +
+ +

In both cases, Metabase will take a look at the fields in that table or model, and automatically generate charts that summarize the data based on the data types it finds.

+ +

Here’s an example X-ray:

+ +

Example X-ray of the products table

+ +

X-raying models and tables

+ +

Browse data X-ray

+ +

Another great way to get to know your data is by X-raying your models and tables.

+ +
    +
  • Table X-rays: From the left nav, click on Browse Data, pick a database, hover over a table card, and click the lightning bolt icon table to view an X-ray of the table.
  • +
  • Model X-rays: Click on the ellipses for a model and select X-ray this.
  • +
+ +

X-rays in the data reference

+ +

You can also view an X-ray by browsing to a table and clicking on the lightning bolt icon. Click on the Browse Data button in the top navigation, select a database, and hover over a table to see the icon.

+ +

From the Browse Data page, you can also click on Learn about our data to view the Data Reference section. From here you can navigate through databases, tables, columns, metrics, or segments, and you can click on the X-ray link in the left sidebar to see an X-ray of the item you’re currently viewing.

+ +

Data Reference X-ray

+ +

Exploring newly added data sources

+ +

If you’re an administrator, when you first connect a database to Metabase, Metabot will offer to show you some automatic explorations of your newly connected data.

+ +

Browsing through suggested X-rays

+ +

Depending on the X-ray you’re currently viewing, you’ll see suggestions that will let you:

+ +
    +
  • Zoom out: view an X-ray of the table the current X-ray is based on.
  • +
  • Zoom in: see a more detailed X-ray about a field or dimension of the current X-ray.
  • +
  • Related: X-ray some related data, like a metric based on the current table, or a different table related to the current one.
  • +
+ +

Saving X-rays

+ +

If you come across an X-ray that’s particularly interesting, you can save its cards and filters as a dashboard by clicking the green Save this button. Metabase will create a new dashboard and save it to the Automatically generated dashboards collection (though you can move the dashboard to any collection you have curate access to).

+ +

Disabling X-rays

+ +

If for some reason X-rays aren’t a good fit for your team or your data, administrators can turn them off completely by clicking on the gear icon in the upper right and going to Admin settings > Settings > General and toggling the option to Enable X-ray features.

+ +

If you pin any dashboards in the “Our Analytics” collection, Metabase will hide the X-ray suggestions that appear on the homepage.

+ +

Admins can also manually remove these suggestions by clicking on the Customize button in the upper right and selecting a dashboard as your homepage. Changing the home page won’t disable the X-ray features in the rest of Metabase.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/faq.html b/_site/docs/doc-update-detection/faq.html new file mode 100644 index 000000000..9664adb8b --- /dev/null +++ b/_site/docs/doc-update-detection/faq.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/images/metabase-logo.svg b/_site/docs/doc-update-detection/images/metabase-logo.svg new file mode 100644 index 000000000..c34b2a063 --- /dev/null +++ b/_site/docs/doc-update-detection/images/metabase-logo.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/images/metabase-product-screenshot.png b/_site/docs/doc-update-detection/images/metabase-product-screenshot.png new file mode 100644 index 000000000..1d150efa0 Binary files /dev/null and b/_site/docs/doc-update-detection/images/metabase-product-screenshot.png differ diff --git a/_site/docs/doc-update-detection/index.html b/_site/docs/doc-update-detection/index.html new file mode 100644 index 000000000..f29345121 --- /dev/null +++ b/_site/docs/doc-update-detection/index.html @@ -0,0 +1,3444 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Metabase documentation | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+ + +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Metabase documentation

+ +

Metabase dashboard

+ +

Metabase is an open-source business intelligence platform. You can use Metabase to ask questions about your data, or embed Metabase in your app to let your customers explore their data on their own.

+ +

First steps

+ +

Metabase Cloud

+ +

The easiest way to get started with Metabase is to sign up for a free trial of Metabase Cloud. You get support, backups, upgrades, an SMTP server, SSL certificate, SoC2 Type 2 security auditing, and more (plus your money goes toward improving Metabase). Check out our quick overview of cloud vs self-hosting. If you need to, you can always switch to self-hosting Metabase at any time (or vice versa).

+ +

Installing Metabase

+ +

Run as a JAR, using Docker, or on Metabase Cloud.

+ +

Setting up Metabase

+ +

Once installed, set up your Metabase and connect to your data.

+ +

Getting started

+ +

With your data connected, get started asking questions, creating dashboards, and sharing your work.

+ +

A tour of Metabase

+ +

Metabase is a deep product with a lot of tools to simplify business intelligence, from embeddable charts and interactive dashboards, to GUI and SQL editors, to auditing and data sandboxing, and more.

+ +

Documentation topics

+ +

Metabase’s reference documentation.

+ +

Installation

+ + + +

Databases

+ + + +

Questions

+ + + +

Query builder

+ + + +

SQL and native queries

+ + + +

Visualizing data

+ + + +

Dashboards

+ + + +

Data modeling

+ + + +

Actions

+ + + +

Organization

+ + + +

People

+ + + + + + + +

Permissions

+ + + +

Embedding

+ + + +

Configuration

+ + + +

Tools

+ + + +

Cloud

+ + + +

Metabase API

+ + + +

Troubleshooting

+ + + +

Developer guide

+ + + +

Getting help

+ +

Troubleshooting

+ + + +

Tutorials and guides

+ +

Learn Metabase has a ton of articles on how to use Metabase, data best practices, and more.

+ +

More resources

+ +

Discussion

+ +

Share and connect with other Metabasers.

+ +

Metabase Cloud

+ +

For docs specific to Metabase Cloud plans.

+ +

Community stories

+ +

Practical advice from our community.

+ +

Metabase blog

+ +

News, updates, and ideas.

+ +

Customers

+ +

Real companies, real data, real stories.

+ +

Metabase Twitter

+ +

We tweet stuff.

+ +

Source code repository on GitHub

+ +

Follow us on GitHub.

+ +

List of releases

+ +

A list of all Metabase releases, including both the Enterprise Edition and the Open Source Edition.

+ +

Developers guide

+ +

Contribute to the Metabase open source project!

+ +

Data and Business Intelligence Glossary

+ +

Data jargon explained.

+ +

Metabase Experts

+ +

If you’d like more technical resources to set up your data stack with Metabase, connect with a Metabase Expert.

+ +

hello from the new site +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi +hi

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/information-collection.html b/_site/docs/doc-update-detection/information-collection.html new file mode 100644 index 000000000..9f07e609c --- /dev/null +++ b/_site/docs/doc-update-detection/information-collection.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/installation-and-operation/accessibility.html b/_site/docs/doc-update-detection/installation-and-operation/accessibility.html new file mode 100644 index 000000000..3a6d44bfc --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/accessibility.html @@ -0,0 +1,3064 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Accessibility in Metabase | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Accessibility in Metabase

+ +

While we’re working to make a product that is easy to use and inclusive to all, we’re not yet fully compliant with the U.S. federal government’s Section 508 standards or the Web Content Accessibility Guidelines (WCAG) 2.1 at Level AA. We expect to build on our current state in the future, and as of today these are some general notes on our state of compliance:

+ +
    +
  • Navigation and screen readers: Most information is presented in a way to ensure it can be accessed by screen readers. Metabase lacks a mechanism to allow screen readers to bypass repetitive navigation elements efficiently. Many interactive elements, functionalities, tooltip content, non-modal dialogs and custom form controls are not operable for screen reader users.
  • +
  • Non-text content: While Metabase provides text alternatives for most non-text elements, some functional images either lack descriptions or have incomplete alt text.
  • +
  • Keyboard navigation: Most form elements are keyboard-accessible, but certain interactive components, such as custom controls and non-modal dialogs, may lack full keyboard operability.
  • +
  • Focus management: In some cases, keyboard focus does not follow a logical order, and certain interactive elements lack a visible focus indicator.
  • +
  • Tables and data visualization: Data tables do not consistently include programmatically defined row and column headers, impacting screen reader interpretation.
  • +
  • Motion and animations: Metabase includes minimal transition animations. If the prefers-reduced-motion CSS setting is enabled in the OS, Metabase disables animations. However, we have not yet conducted full testing to confirm that all animations meet the recommended flicker rate threshold (between 2 Hz and 55 Hz).
  • +
  • Language and labels: Some form elements lack explicit labels, and primary language settings do not update programmatically when changed.
  • +
  • Assistive technology compatibility: Metabase is a React-based web application, which means it requires JavaScript to function and may not be fully operable with all assistive technologies.
  • +
  • Error handling and form validation: Some form fields do not provide clear error messages, and required fields are not always programmatically marked as mandatory. This may impact users relying on screen readers or other assistive technologies.
  • +
  • Contrast and visual accessibility: While most UI elements meet contrast requirements, some text and interactive elements have insufficient color contrast, making them difficult to read for users with low vision or color blindness.
  • +
  • Resizing and responsive behavior: Most content can be resized up to 200% without loss of information, but some elements do not reflow properly, potentially causing overlap or cutoff content when text spacing is adjusted.
  • +
  • Hover and tooltip behavior: Some tooltips and additional information elements appear on hover but are not easily dismissible using a keyboard, which may present challenges for keyboard-only users and screen readers.
  • +
  • Status messages and notifications: While some dynamically generated status messages are accessible, others are not consistently conveyed to assistive technologies like screen readers, which could make it difficult for users to receive important system feedback.
  • +
  • Consistent page titles and headings: Some pages lack descriptive or unique titles, which may make navigation more challenging for screen reader users who rely on clear page identification.
  • +
+ +

If you’re interested in helping us address these gaps, check out our developers’ guide.

+ +

To request a copy of our VPAT, contact us at help@metabase.com.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/activating-the-enterprise-edition.html b/_site/docs/doc-update-detection/installation-and-operation/activating-the-enterprise-edition.html new file mode 100644 index 000000000..8041dbe56 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/activating-the-enterprise-edition.html @@ -0,0 +1,3153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Activating your Metabase commercial license | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Activating your Metabase commercial license

+ +

The paid Pro and Enterprise editions of Metabase are distinct from the free Open Source edition and the Starter version of Metabase Cloud.

+ +

If you’re running on Metabase Cloud

+ +

If you’ve signed up for or upgraded to a Pro or Enterprise plan on Metabase Cloud, all of this will be taken care of for you.

+ +

If you’re self-hosting Metabase

+ +

To use your Pro/Enterprise features, you’ll need to do two things:

+ +
    +
  • Download Metabase Enterprise Edition
  • +
  • Enter your license.
  • +
+ +

You can get a license by signing up for a free trial of the Pro or Enterprise edition plans, both of which can be self-hosted or hosted on Metabase Cloud.

+ +

Download the Enterprise edition

+ + + +

You’ll also need to set up a dedicated application database to store your Metabase data.

+ +

Activate your license

+ +

There are two ways to activate your license when self-hosting Metabase:

+ +
    +
  • When Metabase is running: go to Settings > Admin settings, and click License and Billing in the lefthand sidebar. Paste in your license token under License and click Activate.
  • +
+ +

OR

+ + + +

Upgrading from a self-hosted Metabase Open Source Edition to a Pro or Enterprise plan

+ +

To get all the features available when upgrading to a self-hosted Pro or Enterprise plan, you’ll need to:

+ +
    +
  1. Change to the Metabase Enterprise Edition (that goes for both the Pro and Enterprise plans).
  2. +
  3. Activate your license.
  4. +
+ +

Assuming you’ve been using a production application database, you’ll want to:

+ +
    +
  1. Back up your application database.
  2. +
  3. Download the Enterprise Edition version that corresponds with your current Metabase version. So if you’re running the Docker image for , you should switch to the Docker image for . To see a list of available versions for both the Open Source and Enterprise Editions, check out Metabase releases.
  4. +
  5. Stop your current Metabase Open Source edition.
  6. +
  7. Swap in the Enterprise Edition Docker image or jar that you downloaded.
  8. +
  9. Start your Metabase like you normally would using the new Enterprise Edition image or jar. You don’t need to do anything with your application database (which you’ve backed up in step one, right?).
  10. +
  11. Activate your license. You won’t be able to use any of the new features until you’ve activated your license.
  12. +
+ +

Migrating to the Enterprise Edition will keep all of your questions, dashboards, people, settings — everything in your existing Metabase.

+ +

And don’t stress. You won’t lose any of your work, and if you get stuck, we’re here to help.

+ +

Validating your token

+ +

To validate your token and maintain access to Pro/Enterprise features, your Metabase needs to be able to access the Internet, specifically:

+ +
https://token-check.metabase.com/api/[token-id]/v2/status
+
+ +

(substituting [token-id] with your token ID).

+ +

If your Metabase can’t validate the token, it’ll disable the Pro/Enterprise features, but will continue to work normally as if you were running the Open Source edition.

+ +

If you can’t expose your Metabase to the internet, talk to us about our air-gapped Metabase.

+ +

Routing outbound Metabase traffic through a proxy

+ +

In case you need to route outbound Metabase traffic through a proxy on your network, use the following command when starting Metabase:

+ +
java -Dhttps.proxyHost=[your proxy's hostname or ip] -Dhttps.proxyPort=[your proxy's port] -jar metabase.jar
+
+ +

or if you’re using containers, then you need to use the JAVA_TOOL_OPTIONS environment variable:

+ +
JAVA_TOOL_OPTIONS=-Dhttps.proxyHost=[your proxy's hostname or ip] -Dhttps.proxyPort=[your proxy's port]
+
+ +

Depending on your organization’s setup, you may need to take additional configuration steps. If the command above doesn’t work for you, we recommend reaching out to your internal infrastructure or dev ops teams for assistance.

+ +

IP addresses to whitelist

+ +

If you’re hosting Metabase behind a firewall that blocks outgoing connections, you must allow outbound stateful connections to port 443 on the all of the following IP addresses:

+ +
23.23.111.13
+44.199.18.109
+44.212.138.188
+
+ +

To verify your license with a token check to token-check.metabase.com, your Metabase will make GET HTTP requests to these IP addresses and parse their responses. If you can’t allow outbound connections for security reasons, please contact us.

+ +

Note about Zscaler deployments

+ +

When Metabase is deployed inside infrastructure that uses Zscaler, you should do the following:

+ +
    +
  1. Contact your networking team and let them know that Metabase will need to perform token checks in order for paid features to work. If you need an air-gapped version of Metabase, contact us.
  2. +
  3. Make sure Zscaler isn’t acting as a proxy or DNS for the server where Metabase is running. Metabase needs a direct connection to the token check service without any gateway acting as a proxy.
  4. +
  5. Make sure the server where Metabase is running isn’t using Zscaler root CA certificates for all websites. Otherwise, the Java virtual machine where Metabase runs will determine that the certificate authority is incorrect.
  6. +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/advanced-topics-for-running-Metabase-in-AWS-ElasticBeanstalk.html b/_site/docs/doc-update-detection/installation-and-operation/advanced-topics-for-running-Metabase-in-AWS-ElasticBeanstalk.html new file mode 100644 index 000000000..add30644a --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/advanced-topics-for-running-Metabase-in-AWS-ElasticBeanstalk.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/installation-and-operation/backing-up-metabase-application-data.html b/_site/docs/doc-update-detection/installation-and-operation/backing-up-metabase-application-data.html new file mode 100644 index 000000000..2b9ea1bbe --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/backing-up-metabase-application-data.html @@ -0,0 +1,3085 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Backing up Metabase | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Backing up Metabase

+ +

Avoid losing your application data (all of your questions, dashboards, collections and so on) by backing up your data.

+ +

Metabase uses a single SQL database for all of its runtime application data, so all you need to do is back up that database and you’re good to go. You can use that backup to restore your Metabase installation if anything goes wrong (like during an upgrade).

+ +

Backing up the default H2 database

+ +

If you didn’t specify an application database using environment variables when you launched Metabase, Metabase will have created an embedded H2 database in its directory.

+ +

But if you’re at the point where you have questions and dashboards that you want to keep, you should consider migrating to a production-ready database before you upgrade.

+ +

If you’re just using Metabase for personal use and want to keep your application data, here’s what you’ll need to do.

+ +

If you’re running the Metabase Docker image

+ +

If you’re running Docker, you should already have switched to a production-ready database.

+ +

Before migrating to a production application database, you should copy the H2 app db file out of the Docker container. For example, if the container is called metabase, you’d run:

+ +
docker cp metabase:/metabase.db/metabase.db.mv.db ./
+
+ +

The above command would copy the database file to the directory you ran the command from. You can also create a copy of this H2 file and use it to migrate the data to a production-ready database. See Migrating from H2.

+ +

If you’re running the Metabase JAR

+ +
    +
  1. Navigate to your Metabase directory.
  2. +
  3. If your Metabase is running, stop the Metabase process. You can either close the terminal or kill the process with CTRL-C. If you are running the process as a service, then stop the service.
  4. +
  5. Copy the application database file (called metabase.db.mv.db) and keep that copy somewhere safe. That’s it.
  6. +
  7. Restart Metabase: java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar or start the service again.
  8. +
+ +

Amazon RDS for the application database

+ +

Amazon has its own best practices on how to backup and restore RDS databases, so we’ll defer to them. We recommend that you enable automated RDS Backups.

+ +

Instructions can be found in the Amazon RDS User Guide.

+ +

Self-hosted PostgreSQL database

+ +

If you’re hosting your own PostgreSQL database, simply follow PostgreSQL’s instructions for backing up your database.

+ +

As long as you have a dump of the Metabase database, you should be good to go.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/commands.html b/_site/docs/doc-update-detection/installation-and-operation/commands.html new file mode 100644 index 000000000..fb58359d1 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/commands.html @@ -0,0 +1,3211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Metabase CLI | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Metabase CLI

+ +

Metabase ships with some handy CLI commands. To view a list of commands, run the Metabase jar followed by help.

+ +
java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar help
+
+ +

Metabase will print out the help text for available commands.

+ +

api-documentation

+ +

Generate a markdown file containing documentation for all API endpoints. This is written to a file called docs/api.html.

+ +

driver-methods | driver-methods _docs

+ +

Print a list of all multimethods available for a driver to implement. Add _docs to include their docstrings.

+ +

config-template

+ +

Generates a Markdown file with documentation and an example configuration file in YAML. The YAML template includes Metabase settings and their defaults. Metabase will save the file as docs/configuring-metabase/config-template.md.

+ +

drop-entity-ids

+ +

Drop Entity IDs for instances of serializable models. Useful for migrating from v1 serialization (x.46 and earlier) to v2 (x.47+).

+ +

dump path & options

+ +

Note: this command is deprecated. Use export instead.

+ +

Serializes Metabase instance into directory path.

+ +

Options:

+ +
    +
  • -u, --user EMAIL - Export collections owned by the specified user
  • +
  • -s, --state (active|all) - When set to active, do not dump archived entities. Default behavior is all
  • +
  • --include-entity-id - Include entity_id property in all dumped entities. Default: false
  • +
+ +

dump-to-h2 h2-filename & opts

+ +

Transfer data from existing database to newly created H2 DB with specified filename. Target H2 file is deleted before dump, unless the –keep-existing flag is given.

+ +

Options:

+ +
    +
  • -k, --keep-existing - Do not delete target H2 file if it exists
  • +
  • -p, --dump-plaintext - Do not encrypt dumped contents
  • +
+ +

environment-variables-documentation

+ +

Generates a markdown file containing documentation for environment variables relevant to configuring Metabase. The command only includes environment variables registered as defsettings. For a full list of environment variables, see https://www.metabase.com/docs/latest/configuring-metabase/environment-variables.

+ +

export path & options

+ +
+
+ + + + + + + +

Serialization is only available on Pro and Enterprise plans + + (only on self-hosted plans). +

+
+
+ +

Serialize Metabase instance into directory at path.

+ +

Options:

+ +
    +
  • -c, --collection ID - Export only specified ID(s). Use commas to separate multiple IDs. You can pass Entity IDs with eid:<...> as a prefix
  • +
  • -C, --no-collections - Do not export any content in collections
  • +
  • -S, --no-settings - Do not export settings.yaml
  • +
  • -D, --no-data-model - Do not export any data model entities; useful for subsequent exports
  • +
  • -f, --include-field-values - Include field values along with field metadata
  • +
  • -s, --include-database-secrets - Include database connection details (in plain text; use caution)
  • +
  • -e, --continue-on-error - Do not break execution on errors
  • +
  • --full-stacktrace - Output full stacktraces on errors
  • +
+ +

help command-name | help

+ +

Show this help message listing valid Metabase commands. Use help command-name for specific command details.

+ +

import path & options

+ +
+
+ + + + + + + +

Serialization is only available on Pro and Enterprise plans + + (only on self-hosted plans). +

+
+
+ +

Load serialized Metabase instance as created by the export command from directory path.

+ +

Options:

+ +
    +
  • -e, --continue-on-error - Do not break execution on errors
  • +
  • --full-stacktrace - Output full stacktraces on errors
  • +
+ +

load path & options

+ +

Note: this command is deprecated. Use import instead.

+ +

Load serialized Metabase instance as created by dump command from directory path.

+ +

Options:

+ +
    +
  • -m, --mode (skip|update) - Update or skip on conflicts. Default: skip
  • +
  • -e, --on-error (continue|abort) - Abort or continue on error. Default: continue
  • +
+ +

load-from-h2 | load-from-h2 h2-connection-string

+ +

Transfer data from existing H2 database to the newly created MySQL or Postgres DB specified by env vars.

+ +

migrate direction

+ +

Run database migrations. Valid options for direction are up, force, down, print, or release-locks.

+ +

profile

+ +

Start Metabase the usual way and exit. Useful for profiling Metabase launch time.

+ +

reset-password email-address

+ +

Reset the password for a user with email-address.

+ +

rotate-encryption-key new-key

+ +

Rotate the encryption key of a metabase database. The MB_ENCRYPTION_SECRET_KEY environment variable has to be set to the current key, and the parameter new-key has to be the new key. new-key has to be at least 16 chars.

+ +

remove-encryption

+ +

Decrypts data in the metabase database. The MB_ENCRYPTION_SECRET_KEY environment variable has to be set to the current key.

+ +

seed-entity-ids

+ +

Add Entity IDs for instances of serializable models that don’t already have them.

+ +

version

+ +

Print version information about Metabase and the current system.

+ +

Additional useful commands

+ +

H2 SQL Shell

+ +

Open an SQL shell for the Metabase H2 DB:

+ +
java -cp metabase.jar org.h2.tools.Shell -url jdbc:h2:/path/to/metabase.db
+
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/configuring-application-database.html b/_site/docs/doc-update-detection/installation-and-operation/configuring-application-database.html new file mode 100644 index 000000000..4ee68538c --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/configuring-application-database.html @@ -0,0 +1,3205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Configuring the Metabase application database | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Configuring the Metabase application database

+ +

The application database is where Metabase stores information about user accounts, questions, dashboards, and any other data needed to run the Metabase application. This app DB is distinct from the database where you store your data, also known as your data warehouse. For connecting to your data warehouse, see Connecting to a supported database.

+ +

For production, we recommend using PostgreSQL as your Metabase application database.

+ +
    +
  • PostgreSQL (recommended for production)
  • +
  • MySQL or MariaDB (also works for production)
  • +
  • H2 (default for local demos - AVOID in production)
  • +
+ +

Metabase will read the connection configuration information when the application starts up. You can’t change the application database while the application is running.

+ +

PostgreSQL

+ +

We recommend that you use PostgreSQL for your Metabase application database. Metabase supports the oldest supported version of PostgreSQL through the latest stable version. See PostgreSQL versions.

+ +

You can use environment variables to set a Postgres database as Metabase’s application database. For example, the following commands tell Metabase to use a Postgres database as its application database:

+ +
export MB_DB_TYPE=postgres
+export MB_DB_DBNAME=metabase
+export MB_DB_PORT=5432
+export MB_DB_USER=<username>
+export MB_DB_PASS=<password>
+export MB_DB_HOST=localhost
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

Metabase will not create a Postgres database for you. Example command to create the database:

+ +
createdb --encoding=UTF8 -e metabase
+
+ +

If you have additional parameters, Metabase also supports providing a full JDBC connection string:

+ +
export MB_DB_CONNECTION_URI="jdbc:postgresql://localhost:5432/metabase?user=<username>&password=<password>"
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

If you want to pass the connection URI, user, and password credentials separately from the JDBC connection string (useful if the password contains special characters), you can use the MB_DB_CONNECTION_URI environment variable in combination with MB_DB_USER and MB_DB_PASS variables:

+ +
export MB_DB_CONNECTION_URI="jdbc:postgresql://localhost:5432/metabase"
+export MB_DB_USER=<username>
+export MB_DB_PASS=<password>
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

MySQL or MariaDB

+ +

We recommend PostgreSQL, but you can also use MySQL or MariaDB.

+ +

The minimum recommended version is MySQL 8.0.17 or MariaDB 10.2.2. The utf8mb4 character set is required.

+ +

We don’t support ApsaraDB MySQL. You can instead use ApsaraDB PostgreSQL.

+ +

You can change the application database to use MySQL using environment variables like so:

+ +
export MB_DB_TYPE=mysql
+export MB_DB_DBNAME=metabase
+export MB_DB_PORT=3306
+export MB_DB_USER=<username>
+export MB_DB_PASS=<password>
+export MB_DB_HOST=localhost
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

Metabase won’t create this database for you. Example SQL statement to create the database:

+ +
CREATE DATABASE metabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+
+ +

The following command will tell Metabase to look for its application database using the supplied MySQL connection information. Metabase also supports providing a full JDBC connection string if you have additional parameters:

+ +
export MB_DB_CONNECTION_URI="jdbc:mysql://localhost:3306/metabase?user=<username>&password=<password>"
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

As with Postgres, MB_DB_CONNECTION_URI can also be used in combination with MB_DB_USER and/or MB_DB_PASS if you +want to pass one or both separately from the rest of the JDBC connection string:

+ +
export MB_DB_CONNECTION_URI="jdbc:mysql://localhost:5432/metabase"
+export MB_DB_USER=<username>
+export MB_DB_PASS=<password>
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

H2 application database

+ +
+

For production installations of Metabase we recommend that people replace the default H2 database with PostgreSQL. Postgres offers a greater degree of performance and reliability.

+
+ +

By default, Metabase ships with an H2 database to make it easy to demo Metabase on your local machine. Avoid using this default database in production.

+ +

If when launching Metabase you don’t provide environment variables that specify connection details for a production database, Metabase will attempt to create a new H2 database in the same directory as the Metabase JAR.

+ +

H2 is a file-based database, and you can see these H2 database files from the terminal:

+ +
ls metabase.*
+
+ +

You should see the following files:

+ +
metabase.db.h2.db  # Or metabase.db.mv.db depending on when you first started using Metabase.
+metabase.db.trace.db
+
+ +

If you want to use an H2 database file in a particular directory, use the MB_DB_TYPE and MB_DB_FILE environment variables:

+ +
export MB_DB_TYPE=h2
+export MB_DB_FILE=/the/path/to/my/h2.db
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

Note that H2 automatically appends .mv.db or .h2.db to the path you specify; exclude those extensions in your path! In other words, MB_DB_FILE should be something like /path/to/metabase.db, rather than something like /path/to/metabase.db.mv.db (even though the latter is the file that Metabase will create).

+ +

Migrating from H2

+ +

If you’ve started out using the default, H2 database, but you want to preserve the content you’ve created and move to a production application database, Metabase provides limited support for migrating from H2 to PostgreSQL.

+ +

Upgrading from a Metabase version pre-0.38

+ +

If you’re upgrading from a previous version of Metabase, note that for Metabase 0.38 we’ve removed the use of the PostgreSQL NonValidatingFactory for SSL validation. It’s possible that you could experience a failure either at startup (if you’re using a PostgreSQL application database) or when querying a PostgreSQL data warehouse.

+ +

You can resolve this failure in one of two ways:

+ +
    +
  1. Configuring the PostgreSQL connection to use SSL certificate validation,
  2. +
  3. Or manually enabling the NonValidatingFactory. WARNING: this method is insecure. We’re including it here only to assist in troubleshooting, or for situations in which security is not a priority.
  4. +
+ +

How you configure your connection depends on whether you’re using Postgres as Metabase’s application database or as a data warehouse connected to Metabase:

+ +

SSL certificate validation for Postgres application databases

+ +

To use SSL certificate validation, you’ll need to use the MB_DB_CONNECTION_URI environment variable to configure your database connection. Here’s an example:

+ +
export MB_DB_CONNECTION_URI="postgres://localhost:5432/metabase?user=<username>&password=<password>&sslmode=verify-ca&sslrootcert=<path to CA root or intermediate root certificate>"
+
+ +

If you can’t enable certificate validation, you can enable the NonValidatingFactory for your application database:

+ +
export MB_DB_CONNECTION_URI="postgres://localhost:5432/metabase?user=<username>&password=<password>&ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory"
+
+ +

SSL certificate validation for Postgres data warehouse databases

+ +

Add the following to the end of your JDBC connection string for your database:

+ +
&sslmode=verify-ca&sslrootcert=<path to CA root or intermediate root certificate>
+
+ +

If that fails, you can enable NonValidatingFactory by adding the following to the end of your connection URI for your database:

+ +
&ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory
+
+ +

For more options to further tune the SSL connection parameters, see the PostgreSQL SSL client documentation.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/creating-RDS-database-on-AWS.html b/_site/docs/doc-update-detection/installation-and-operation/creating-RDS-database-on-AWS.html new file mode 100644 index 000000000..32b97099c --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/creating-RDS-database-on-AWS.html @@ -0,0 +1,3114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Creating an RDS database on AWS | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Creating an RDS database on AWS

+ +

If you want to move from using Metabase just for testing to something that is ready for the big time, you should use PostgreSQL for your application database. Here’s a high-level view of Metabase deployed with a dedicated application database.

+ +

high level architecture diagram

+ +

Create a database

+ +

In AWS, enter RDS in the search box or select RDS from the dropdown button on the top left of the page. Once inside RDS, click on the Create database button.

+ +

Select PostgreSQL as the engine type. We’ll choose the latest version available in AWS at the time of writing (12.4-R1).

+ +

Templates: you can leave “Production” selected, or choose any other option that better suits your needs.

+ +

Settings: type a unique DB instance identifier for your database. You’ll need the username and master password to configure the environment variables in Metabase.

+ +

RDS Templates Section

+ +

Instance size: the sizing of the RDS instance depends on the number of Metabase instances that will be connected to this database, the number of simultaneous users who are using Metabase, and the number of questions, dashboards, and configurations that are saved. To start, a t3.small is a good choice.

+ +

RDS Instance size

+ +

Availability & Durability: on production deployments, you should be using a Multi-AZ (Availability Zone) cluster, as this will ensure that the database does not goes down in case there is an issue on a single availability zone.

+ +

RDS MultiAZ

+ +

Connectivity:

+ +
    +
  • Ensure that you are deploying the database in the same VPC as the one you deployed the Metabase instance/s, otherwise they won’t be able to see each other.
  • +
  • Create a VPC security group, as you will need to grant access from the Metabase instance/s to the database on the port that listens for connections. +RDS VPC Security Groups
  • +
+ +

Additional configuration:

+ +
    +
  • Enter metabase as the Initial database name. Metabase will use this database for all of its configurations.
  • +
  • You can also configure the backup window in case you need to restore the backups at some point in time.
  • +
+ +

RDS Initial Database

+ +

When you’ve completed all these configurations, click on the Create database button on the lower right part of the page and wait for the database to be created (which can take several minutes).

+ +

Set up security

+ +

Once the database status is Available, you need to click on the DB identifier:

+ +

RDS DB Identifier

+ +

On the page that appears after you click on the database identifer, you will see on the center of the page the Connectivity & Security section. This section will provide you with the Endpoint that Metabase needs to connect to the application database we just created.

+ +

RDS Connection Data

+ +

In the Security group rules section, you’ll see the Security Group that was created, but the group will have a rule that allows only one IP address to access the database.

+ +

RDS Security Group Rules

+ +

To configure the rule for the database, select the CIDR/IP - Inbound rule, then click on the Inbound rules tab on the lower part of the page.

+ +

RDS Security Group Rules

+ +

When you click on Inbound Rules, you need to click on Edit Inbound Rules button that appears on the right side of the section.

+ +

RDS Edit Inbound Rule

+ +

On the edit page, you need to delete the IP address that appears as default, then add the security group for the server you’re running Metabase on (the Security group name will have the keyword AWSEBSecurityGroup in its name). Once you add this security group, click the Save rules button.

+ +

RDS Edit Inbound Rule

+ +

Add the RDS instance as the application database with environment variables

+ +

After having finished all the previous steps, go to the your Metabase deployment and add the RDS instance as the Application Database with Environment variables.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/AZDatabase.png b/_site/docs/doc-update-detection/installation-and-operation/images/AZDatabase.png new file mode 100644 index 000000000..b2383ac3f Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/AZDatabase.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/AZMarketPlaceVnet.png b/_site/docs/doc-update-detection/installation-and-operation/images/AZMarketPlaceVnet.png new file mode 100644 index 000000000..9fe107d43 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/AZMarketPlaceVnet.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/AZMarketplaceWebApp.png b/_site/docs/doc-update-detection/installation-and-operation/images/AZMarketplaceWebApp.png new file mode 100644 index 000000000..ead574eec Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/AZMarketplaceWebApp.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/AZNetworks.png b/_site/docs/doc-update-detection/installation-and-operation/images/AZNetworks.png new file mode 100644 index 000000000..00b9cc802 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/AZNetworks.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/AZPostgreSQLMain.png b/_site/docs/doc-update-detection/installation-and-operation/images/AZPostgreSQLMain.png new file mode 100644 index 000000000..fecc71c27 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/AZPostgreSQLMain.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/AZPrivateLink.png b/_site/docs/doc-update-detection/installation-and-operation/images/AZPrivateLink.png new file mode 100644 index 000000000..0bc61a67f Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/AZPrivateLink.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/AZResource_group_Add.png b/_site/docs/doc-update-detection/installation-and-operation/images/AZResource_group_Add.png new file mode 100644 index 000000000..eaff1c643 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/AZResource_group_Add.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/AZVNETPublicSubnet.png b/_site/docs/doc-update-detection/installation-and-operation/images/AZVNETPublicSubnet.png new file mode 100644 index 000000000..44894a4dd Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/AZVNETPublicSubnet.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/AZVNETintegration.png b/_site/docs/doc-update-detection/installation-and-operation/images/AZVNETintegration.png new file mode 100644 index 000000000..6479865c8 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/AZVNETintegration.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/AZVnet.png b/_site/docs/doc-update-detection/installation-and-operation/images/AZVnet.png new file mode 100644 index 000000000..6aebb71ca Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/AZVnet.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/AddRemoteHost.png b/_site/docs/doc-update-detection/installation-and-operation/images/AddRemoteHost.png new file mode 100644 index 000000000..3d03da05e Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/AddRemoteHost.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/ClickAddJMXHost.png b/_site/docs/doc-update-detection/installation-and-operation/images/ClickAddJMXHost.png new file mode 100644 index 000000000..7c2786386 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/ClickAddJMXHost.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/EBDatabaseEndpoint.png b/_site/docs/doc-update-detection/installation-and-operation/images/EBDatabaseEndpoint.png new file mode 100644 index 000000000..231a2313d Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/EBDatabaseEndpoint.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/EBTerminateEnvironment.png b/_site/docs/doc-update-detection/installation-and-operation/images/EBTerminateEnvironment.png new file mode 100644 index 000000000..5d6655afe Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/EBTerminateEnvironment.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/EnterJMXPort.png b/_site/docs/doc-update-detection/installation-and-operation/images/EnterJMXPort.png new file mode 100644 index 000000000..7fbf02add Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/EnterJMXPort.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/HeapDump.png b/_site/docs/doc-update-detection/installation-and-operation/images/HeapDump.png new file mode 100644 index 000000000..0fa623ed6 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/HeapDump.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/LocalProcessVisualVM.png b/_site/docs/doc-update-detection/installation-and-operation/images/LocalProcessVisualVM.png new file mode 100644 index 000000000..f2bee0d07 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/LocalProcessVisualVM.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/Metabase-AWS-SI.png b/_site/docs/doc-update-detection/installation-and-operation/images/Metabase-AWS-SI.png new file mode 100644 index 000000000..94faf3ba6 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/Metabase-AWS-SI.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/OpenRemoteInstance.png b/_site/docs/doc-update-detection/installation-and-operation/images/OpenRemoteInstance.png new file mode 100644 index 000000000..a35bccaa8 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/OpenRemoteInstance.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSConnectionData.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSConnectionData.png new file mode 100644 index 000000000..9c94871b3 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSConnectionData.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSDBIdentifier.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSDBIdentifier.png new file mode 100644 index 000000000..bf9886e6f Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSDBIdentifier.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRule.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRule.png new file mode 100644 index 000000000..e53f86468 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRule.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRuleSG.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRuleSG.png new file mode 100644 index 000000000..a4956deaa Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSEditInboundRuleSG.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSInboundRule.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSInboundRule.png new file mode 100644 index 000000000..3b0516c43 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSInboundRule.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSInitialDatabase.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSInitialDatabase.png new file mode 100644 index 000000000..98384786d Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSInitialDatabase.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSInstanceSize.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSInstanceSize.png new file mode 100644 index 000000000..d924d2355 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSInstanceSize.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSMultiAZ.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSMultiAZ.png new file mode 100644 index 000000000..88f5775a9 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSMultiAZ.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSPostgresSettings.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSPostgresSettings.png new file mode 100644 index 000000000..35b346e1e Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSPostgresSettings.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSSecurityGroupRules.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSSecurityGroupRules.png new file mode 100644 index 000000000..55ecc7f1d Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSSecurityGroupRules.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSSnapshotsMenu.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSSnapshotsMenu.png new file mode 100644 index 000000000..262dc05e2 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSSnapshotsMenu.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSTakeSnapshot.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSTakeSnapshot.png new file mode 100644 index 000000000..03e61b343 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSTakeSnapshot.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/RDSVPCSecurityGroup.png b/_site/docs/doc-update-detection/installation-and-operation/images/RDSVPCSecurityGroup.png new file mode 100644 index 000000000..3326f4f57 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/RDSVPCSecurityGroup.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/SetRemoteHostName.png b/_site/docs/doc-update-detection/installation-and-operation/images/SetRemoteHostName.png new file mode 100644 index 000000000..82b43dacb Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/SetRemoteHostName.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/ThreadDump.png b/_site/docs/doc-update-detection/installation-and-operation/images/ThreadDump.png new file mode 100644 index 000000000..f88a97ac6 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/ThreadDump.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/images/prometheus.png b/_site/docs/doc-update-detection/installation-and-operation/images/prometheus.png new file mode 100644 index 000000000..6c511afd2 Binary files /dev/null and b/_site/docs/doc-update-detection/installation-and-operation/images/prometheus.png differ diff --git a/_site/docs/doc-update-detection/installation-and-operation/information-collection.html b/_site/docs/doc-update-detection/installation-and-operation/information-collection.html new file mode 100644 index 000000000..d7cdf8021 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/information-collection.html @@ -0,0 +1,3086 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +About the anonymous usage data we collect | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

About the anonymous usage data we collect

+ +

If you’re self-hosting Metabase and you’ve opted in to provide us with anonymous usage data (thank you!), Metabase will phone home some data collected via Snowplow.

+ +

We only collect anonymous Metabase data; we don’t collect any of your data. We don’t collect any usernames, emails, server IPs, database details of any kind, or any personally identifiable information (PII).

+ +

This anonymous data helps us understand how people are actually using Metabase, which in turn helps us prioritize what to work on next.

+ +

Examples of the anonymous data we collect and how we use it

+ +

In a nutshell: we track some basic events to find opportunities for improving the product and evaluating project outcomes. We don’t use the data for sales or advertising (and the data’s anonymous, so we couldn’t use it for that anyway).

+ +

We collect things like:

+ +
    +
  • Events in the product (for example, when people create models)
  • +
  • Some performance data
  • +
  • The number and types of DBs you’ve connected to your Metabase
  • +
  • The number of questions and dashboards and other items you’ve created
  • +
+ +

This anonymous data helps us figure out things like:

+ +
    +
  • Which features you’re using
  • +
  • Where people get stuck
  • +
  • How performance for key workflows (like querying or loading) changes over time
  • +
+ +

Opting out of anonymous usage data collection for self-hosted Metabases

+ +

If you’re self-hosting Metabase, you can opt out of providing us with your anonymous usage data:

+ +
    +
  1. Click on the gear icon.
  2. +
  3. Select Admin settings.
  4. +
  5. Go to the Settings tab.
  6. +
  7. Click General
  8. +
  9. Toggle the Anonymous tracking option.
  10. +
+ +

If you’re in the process of setting up your Metabase, you can also toggle off tracking during the Usage Data Preferences onboarding step. We collect a few anonymous events before that point, but won’t do so anymore if you choose to opt out.

+ +

Further reading

+ +

Check out our page on data privacy and security.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/installing-metabase.html b/_site/docs/doc-update-detection/installation-and-operation/installing-metabase.html new file mode 100644 index 000000000..8f40c040d --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/installing-metabase.html @@ -0,0 +1,3096 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Installing Metabase | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Installing Metabase

+ +

Metabase is built and packaged as a Java JAR file and can be run anywhere that Java is available.

+ + + +

Metabase Cloud is the easiest way to run Metabase. All you need to do is sign up for a free trial, and you’re off to the races.

+ +

Self-hosting Metabase

+ +

For an overview on how to self-host Metabase, check out how to run Metabase in production.

+ + + +

Run Metabase in a Docker container.

+ +

Running the Jar file

+ +

If you’re self-hosting but don’t use Docker, the JAR is the easiest way to get started, but it might make it more challenging to move to production. See running the Metabase Jar.

+ +

Air-gapped Metabase

+ +

If you’re self-hosting because you need an air-gapped environment, check out the air-gapped edition of Metabase.

+ +

Professional services from the Metabase team

+ +

If you want help with:

+ +
    +
  • Set up
  • +
  • Training
  • +
  • Data stack
  • +
  • Embedding
  • +
  • Data modeling
  • +
+ +

Check out our professional services.

+ +

Upgrading Metabase

+ +

See Upgrading Metabase.

+ +

Other installation options

+ + + +

We currently do not distribute Metabase on AWS Marketplace or Azure Marketplace.

+ +

Connect with a Metabase Expert

+ +

If you’d like more technical resources to set up your data stack with Metabase, connect with a Metabase Expert.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/migrating-from-h2.html b/_site/docs/doc-update-detection/installation-and-operation/migrating-from-h2.html new file mode 100644 index 000000000..0be0354cf --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/migrating-from-h2.html @@ -0,0 +1,3243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Migrating to a production application database | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Migrating to a production application database

+ +

This page covers how to convert a Metabase that’s been using the built-in application database, H2, to a production-ready instance PostgreSQL. For more on why you should use Postgres as your app DB, check out How to run Metabase in production.

+ +

If you’d rather move to Metabase Cloud, check out Migrate to Metabase Cloud.

+ +

Metabase’s application database

+ +

The main difference between a local installation and a production installation of Metabase is the application database. This application database keeps track of all of your Metabase data: your questions, dashboards, collections, and so on.

+ +

Metabase ships with an embedded H2 application database that you should avoid using in production. The reason Metabase ships with the H2 database is because we want people to spin up Metabase on their local machine and start playing around with asking questions.

+ +

If you want to run Metabase in production, you’ll need to use a production-ready application database to store your application data. You can switch from using the default H2 application database at any time, but if you’re planning on running Metabase in production, the sooner you migrate to a production application database, the better. If you keeping running Metabase with the default H2 application database, and you don’t regularly back it up, the application database could get corrupted, and you could end up losing all of your questions, dashboards, collections, and other Metabase data.

+ +

The migration process is a one-off process. You can execute the migration script from any computer that has the H2 application database file.

+ +

Avoid migrating and upgrading at the same time

+ +

One important thing here is that the version of Metabase you use during the migration process must be the same. Meaning, the Metabase you use to run the migration command must be the same one that was last used to create or update H2 file, which must be the same version you’ll be using in production. Only after completing the migration should you consider upgrading.

+ +

You could also choose to run Metabase on a Metabase Cloud plan, which takes care of all of this stuff for you. If you have an existing Metabase, here’s how you can migrate to Metabase Cloud.

+ +

Supported databases for storing your Metabase application data

+ +

We recommend using PostgreSQL for your application database.

+ +
    +
  • PostgreSQL. Minimum version: 12. Postgres is our preferred choice for Metabase’s application database.
  • +
  • MySQL. Minimum version: 8.0.17. Required settings (which are the default): utf8mb4_unicode_ci collation, utf8mb4 character set, and innodb_large_prefix=ON.
  • +
  • MariaDB. Minimum version: 10.4.0. Required settings (which are the default): utf8mb4_unicode_ci collation, utf8mb4 character set, and innodb_large_prefix=ON.
  • +
+ +

JAR: How to migrate from H2 to your production application database

+ +
+

You must use the same version of Metabase throughout the migration process.

+
+ +

Metabase provides a custom migration command for migrating to a new application database. Here’s what you’ll do:

+ + + +

1. Confirm that you can connect to your target application database

+ +

You must be able to connect to the target application database in whatever environment you’re running this migration command in. So, if you’re attempting to move the data to a cloud database, make sure you can connect to that database.

+ +

2. Shut down your Metabase instance

+ +

You don’t want people creating new stuff in your Metabase while you’re migrating. Ideally, if you’re running the Metabase JAR in production, you’re running Metabase as a service.

+ +

3. Back up your H2 application database

+ +

Safety first! See Backing up Metabase Application Data.

+ +

4. Run the Metabase data migration command

+ +

Run the migration command, load-from-h2, using the appropriate environment variables for the target database you want to migrate to.

+ +

You can find details about specifying databases at Configuring the application database.

+ +

Here’s an example command for migrating to a Postgres database:

+ +
export MB_DB_TYPE=postgres
+export MB_DB_CONNECTION_URI="jdbc:postgresql://<host>:5432/metabase?user=<username>&password=<password>"
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar load-from-h2 /path/to/metabase.db # do not include .mv.db
+
+ +

Here’s an example command for migrating to a MySQL database using Java parameter instead of environment variables:

+ +
java -DMB_DB_TYPE=mysql -DMB_DB_CONNECTION_URI="jdbc:mysql://<host>:3306/metabase?user=<username>&password=<password>" -jar metabase.jar load-from-h2 metabase.db
+
+ +

Note that the file name of the database file itself might be /path/to/metabase.db.mv.db, but when running the load-from-h2 command, you need to truncate the path to /path/to/metabase.db.

+ +

Metabase expects that you’ll run the command against a brand-new (empty) database; it’ll create the database schema and migrate the data for you.

+ +

5. Start your Metabase

+ +

Start your Metabase (with the db connection info, but without the load-from-h2 and H2 file migration command), and you should be good to go. For example, if you’re using Postgres, your command to start Metabase would look something like:

+ +
export MB_DB_TYPE=postgres
+export MB_DB_CONNECTION_URI="jdbc:postgresql://<host>:5432/metabase?user=<username>&password=<password>"
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

You should, however, keep your old H2 file just for safe-keeping, or as a heirloom, or talisman, or whatever.

+ +

Docker: how to migrate from H2 to your production application database

+ +
+

You must use the same version of Metabase throughout the migration process.

+
+ +

Metabase provides a custom migration command for migrating to a new application database. Here’s what you’ll do:

+ + + +

1. Confirm that you can connect to your target application database

+ +

You must be able to connect to the target application database in whatever environment you’re running this migration command in. So, if you’re attempting to move the data to a cloud database, make sure you can connect to that database.

+ +

2. Back up your H2 application database

+ +

Safety first! See Backing up Metabase Application Data.

+ +

If you don’t back up your H2 database, and you replace or delete your container, you’ll lose all of your questions, dashboards, and other Metabase data, so be sure to back up before you migrate.

+ +

3. Stop the existing Metabase container

+ +

You don’t want people creating new stuff in your Metabase while you’re migrating.

+ +

3. Download the JAR

+ +

In the directory where you saved your H2 file (that is, outside the container), download the JAR for your current version.

+ +

Make sure you use the same version of Metabase you’ve been using. If you want to upgrade, perform the upgrade after you’ve confirmed the migration is successful.

+ +

4. Run the migration command

+ +

Create another copy of your H2 file that you extracted from the container when you backed up your app db (step 2).

+ +

From the directory with your H2 file and your Metabase JAR, run the migration command, load-from-h2. Use the appropriate connection string or environment variables for the target database you want to migrate to. The command would look something like:

+ +
export MB_DB_TYPE=postgres
+export MB_DB_CONNECTION_URI="jdbc:postgresql://<host>:5432/metabase?user=<username>&password=<password>"
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar load-from-h2 /path/to/metabase.db # do not include .mv.db
+
+ +

Metabase will start up, perform the migration (meaning, it’ll take the data from the H2 file and put it into your new app db, in this a Postgres db), and then exit.

+ +

See Configuring the application database.

+ +

5. Start a new Docker container that uses the new app db

+ +

With your new application database populated with your Metabase data, you can start a new container and tell the Metabase in the container to connect to the appdb. The command will looks something like this:

+ +
docker run -d -p 3000:3000 \
+  -e "MB_DB_TYPE=postgres" \
+  -e "MB_DB_DBNAME=<your-postgres-db-name>" \
+  -e "MB_DB_PORT=5432" \
+  -e "MB_DB_USER=<db-username>" \
+  -e "MB_DB_PASS=<db-password>" \
+  -e "MB_DB_HOST=<your-database-host>" \
+  --name metabase metabase/metabase
+
+ +

7. Remove the old container that was using the H2 database

+ +

If you have your H2 file backed up somewhere safe, go ahead and remove the old container. See Docker docs for removing containers.

+ +

Running Metabase application database migrations manually

+ +

When Metabase is starting up, it will typically attempt to determine if any changes are required to the application database, and, if so, will execute those changes automatically. If for some reason you wanted to see what these changes are and run them manually on your database then we let you do that.

+ +

Simply set the following environment variable before launching Metabase:

+ +
export MB_DB_AUTOMIGRATE=false
+
+ +

When the application launches, if there are necessary database changes, you’ll receive a message like the following which will indicate that the application cannot continue starting up until the specified upgrades are made:

+ +
2015-12-01 12:45:45,805 [INFO ] metabase.db :: Database Upgrade Required
+
+NOTICE: Your database requires updates to work with this version of Metabase.  Please execute the following sql commands on your database before proceeding.
+
+-- *********************************************************************
+-- Update Database Script
+-- *********************************************************************
+-- Change Log: migrations/liquibase.yaml
+-- Ran at: 12/1/15 12:45 PM
+-- Against: @jdbc:h2:file:/Users/agilliland/workspace/metabase/metabase/metabase.db
+-- Liquibase version: 3.4.1
+-- *********************************************************************
+
+-- Create Database Lock Table
+CREATE TABLE PUBLIC.DATABASECHANGELOGLOCK (ID INT NOT NULL, LOCKED BOOLEAN NOT NULL, LOCKGRANTED TIMESTAMP, LOCKEDBY VARCHAR(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID));
+
+...
+
+Once your database is updated try running the application again.
+
+2015-12-01 12:46:39,489 [INFO ] metabase.core :: Metabase Shutting Down ...
+
+ +

You can then take the supplied SQL script and apply it to your database manually. Once that’s done just restart Metabase and everything should work normally.

+ +

Troubleshooting migration issues

+ +

Check out this troubleshooting guide.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/monitoring-metabase.html b/_site/docs/doc-update-detection/installation-and-operation/monitoring-metabase.html new file mode 100644 index 000000000..26cc92d2c --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/monitoring-metabase.html @@ -0,0 +1,3124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Monitoring your Metabase | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Monitoring Your Metabase

+ +

Diagnosing performance-related issues can be a challenge. Luckily, the JVM ships with tools that can help diagnose many common issues. Enabling JMX and using a tool like VisualVM can help diagnose issues related to running out of memory, a stalled Metabase, or slow response times.

+ +

This guide assumes that you have the VisualVM tool installed locally. VisualVM is included with OpenJDK and the Oracle JDK. You can find VisualJVM in the bin directory of the JDK installation. Some Linux distributions separate VisualVM from the JDK, in which case it’s a separate visualvm package.

+ +

Connecting to a local Metabase

+ +

If you have VisualVM installed on your Metabase server and are able to run VisualVM there, this is the easiest path as there is no need to setup remote communication with your metabase instance. In this scenario, start Metabase like you would normally and separately start VisualVM.

+ +

localprocess

+ +

Connecting to a remote Metabase

+ +

Monitoring a remote Metabase instance (or a local instance running in a docker container) is probably more common, but requires a more setup. First we need to specify some system properties that lets the JVM know that we want to allow remote monitoring. Assuming we are running Metabase using java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar, we’d need change the invocation to the below command, which includes the properties:

+ +
java --add-to-start=jmx,jmx-remote \
+     -Dcom.sun.management.jmxremote \
+     -Dcom.sun.management.jmxremote.port=1099 \
+     -Dcom.sun.management.jmxremote.rmi.port=1099 \
+     -Dcom.sun.management.jmxremote.authenticate=false \
+     -Dcom.sun.management.jmxremote.ssl=false \
+     -Dcom.sun.management.jmxremote.local.only=false \
+     -Djava.rmi.server.hostname=<Metabase Hostname> \
+     -jar metabase.jar
+
+ +

Port 1099 is a typical RMI/JMX port, but it can be any accessible port.

+ +

The above command opens up your application to monitoring by anyone and should only be used when on a trusted network for a short period of time. Securing this connection is possible, see the Oracle +docs.

+ +

If you’re running Metabase in a docker container, you’ll need to specify the system properties detailed above and will also need to ensure the port is open. Docker allows specifying environment variables via a separate file that can be passed into the docker run invocation. You can create a file called metabase-vars.env with JAVA_OPTS specified:

+ +
JAVA_OPTS=-Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.rmi.port=1099 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false -Djava.rmi.server.hostname=<Metabase Hostname>
+
+ +

This file expects to have each environment variable on its own line with no line breaks:

+ +
docker run --env-file=metabase-vars.env -d -p 3000:3000 -p 1099:1099 -h <Metabase Hostname> --name metabase metabase/metabase
+
+ +

The addition -p 1099:1099 opens the JMX port for monitoring and the --env-file=metabase-vars.env passes in the extra JMX related environment variables. With the instance started, VisualVM needs to know how to connect to the running instance. First add a new remote instance:

+ +

addremotehost

+ +

Then use the hostname you specified above:

+ +

sethostname

+ +

Your local machine must to be able to refer to the hostname you specified (which might require a hosts entry):

+ +

addjmxhost

+ +

If you’re using Docker, the port specified for the JMX host needs to match the system property and the exposed port:

+ +

jmxport

+ +

Next open the new remote JMX process:

+ +

jmxinstance

+ +

Runtime information

+ +

Connecting to a running Metabase with VisualVM makes a lot of runtime information available. Here are some highlights:

+ +

Heap dump

+ +

When running into memory-related issues, typically the first question to ask is: what is consuming extra memory? A heap dump will take a snapshot of everything in memory at that specific point of time. That memory snapshot can be analyzed later by tools like the Eclipse Memory Analyzer Tool. Create a heap dump from the “Monitor” tab:

+ +

heapdump

+ +

Thread dump

+ +

Another useful picture of a running Metabase system is a Thread Dump. In cases when Metabase appears stalled or extremely slow, a thread dump will indicate what each thread is executing (or blocked on) for that specific point in time Collect a thread dump via the “Threads” tab:

+ +

threaddump

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/observability-with-prometheus.html b/_site/docs/doc-update-detection/installation-and-operation/observability-with-prometheus.html new file mode 100644 index 000000000..35ab741d5 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/observability-with-prometheus.html @@ -0,0 +1,3206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Observability with Prometheus | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Observability with Prometheus

+ +

You can export metrics in Prometheus format from your Metabase.

+ +

Running Metabase and Prometheus locally

+ +

To give you an idea of how Metabase and Prometheus would work in your production environment, we’ll walk through how to set up Metabase and Prometheus locally.

+ +

Start up Metabase with MB_PROMETHEUS_SERVER_PORT

+ +

Download the latest Metabase JAR, and run Metabase using an environment variable to specify the Prometheus server port:

+ +
MB_PROMETHEUS_SERVER_PORT=9191 java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

The MB_PROMETHEUS_SERVER_PORT=9191 specifies which port (9191) Metabase will use to send data to Prometheus. To clarify the ports that will be involved here:

+ +
    +
  • Port 3000 is the port Metabase uses to serve the Metabase app. You can set another port with MB_JETTY_PORT (e.g., MB_JETTY_PORT=3001).
  • +
  • Port 9191 (or whichever port you specified with the MB_PROMETHEUS_SERVER_PORT environment variable) is the port Prometheus uses to scrape metrics from Metabase.
  • +
  • Port 9090 is the port Prometheus uses to serve the Prometheus application.
  • +
+ +

When you start Metabase, the Metabase logs will tell you that Metabase is starting the prometheus metrics collector and prometheus metrics web-server.

+ +
(truncated logs)
+2022-09-01 17:47:38,808 INFO metabase.util :: Database setup took 3.4 s
+2022-09-01 17:47:38,826 INFO metabase.core :: Setting up prometheus metrics
+2022-09-01 17:47:38,827 INFO metabase.prometheus :: Starting prometheus metrics collector
+2022-09-01 17:47:38,839 INFO metabase.prometheus :: Starting prometheus metrics web-server on port 9,191
+(truncated logs)
+
+ +

You can view your locally running Metabase at http://localhost:3000.

+ +

Download and configure Prometheus

+ +

Download Prometheus, and extract the files.

+ +

Change into the Prometheus directory, add the following YAML file to configure your Prometheus:

+ +

Prometheus configuration file example

+ +
global:
+  scrape_interval: 15s # By default, scrape targets every 15 seconds.
+
+  # Attach these labels to any time series or alerts when communicating with
+  # external systems (federation, remote storage, Alertmanager).
+  external_labels:
+    monitor: "codelab-monitor"
+
+# A scrape configuration containing exactly one endpoint to scrape:
+# Here it's Prometheus itself.
+scrape_configs:
+  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
+  - job_name: "prometheus"
+
+    # Override the global default and scrape targets from this job every 5 seconds.
+    scrape_interval: 5s
+    # use whatever port here that you set for MB_PROMETHEUS_SERVER_PORT
+    static_configs:
+      - targets: ["localhost:9191"]
+
+ +

You need to change the “target” to where Metabase is, for this particular example, Metabase resides in the same host where Prometheus is running (“localhost”).

+ +

Running Prometheus Locally

+ +

In a new terminal process in the Prometheus directory, run:

+ +
./prometheus --config.file=prometheus.yml
+
+ +

Then check http://localhost:9090. You should see the Prometheus app, and be able to search for various metrics emitted by Metabase.

+ +

Prometheus page showing `jvm_thread_state` graph

+ +

Sample metrics output

+ +

Here is some sample output from Metabase:

+ +
'# HELP jvm_threads_current Current thread count of a JVM
+'# TYPE jvm_threads_current gauge
+jvm_threads_current 81.0
+'# HELP jvm_threads_daemon Daemon thread count of a JVM
+'# TYPE jvm_threads_daemon gauge
+jvm_threads_daemon 36.0
+'# HELP jvm_threads_peak Peak thread count of a JVM
+'# TYPE jvm_threads_peak gauge
+jvm_threads_peak 81.0
+'# HELP jvm_threads_started_total Started thread count of a JVM
+'# TYPE jvm_threads_started_total counter
+jvm_threads_started_total 104.0
+'# HELP jvm_threads_deadlocked Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers
+'# TYPE jvm_threads_deadlocked gauge
+jvm_threads_deadlocked 0.0
+
+ +

Exported metrics

+ +

Metrics exported by Metabase include:

+ +
    +
  • c3p0_max_pool_size
  • +
  • c3p0_min_pool_size
  • +
  • c3p0_num_busy_connections
  • +
  • c3p0_num_connections
  • +
  • c3p0_num_idle_connections
  • +
  • c3p0_num_threads_awaiting_checkout_default_user
  • +
  • jetty_async_dispatches_total
  • +
  • jetty_async_requests_total
  • +
  • jetty_async_requests_waiting
  • +
  • jetty_async_requests_waiting_max
  • +
  • jetty_dispatched_active
  • +
  • jetty_dispatched_active_max
  • +
  • jetty_dispatched_time_max
  • +
  • jetty_dispatched_time_seconds_total
  • +
  • jetty_dispatched_total
  • +
  • jetty_expires_total
  • +
  • jetty_request_time_max_seconds
  • +
  • jetty_request_time_seconds_total
  • +
  • jetty_requests_active
  • +
  • jetty_requests_active_max
  • +
  • jetty_requests_total
  • +
  • jetty_responses_bytes_total
  • +
  • jetty_responses_total
  • +
  • jetty_stats_seconds
  • +
  • jvm_gc_collection_seconds_count
  • +
  • jvm_gc_collection_seconds_sum
  • +
  • jvm_memory_bytes_committed
  • +
  • jvm_memory_bytes_init
  • +
  • jvm_memory_bytes_max
  • +
  • jvm_memory_bytes_used
  • +
  • jvm_memory_objects_pending_finalization
  • +
  • jvm_memory_pool_bytes_committed
  • +
  • jvm_memory_pool_bytes_init
  • +
  • jvm_memory_pool_bytes_max
  • +
  • jvm_memory_pool_bytes_used
  • +
  • jvm_memory_pool_collection_committed_bytes
  • +
  • jvm_memory_pool_collection_init_bytes
  • +
  • jvm_memory_pool_collection_max_bytes
  • +
  • jvm_memory_pool_collection_used_bytes
  • +
  • jvm_threads_current
  • +
  • jvm_threads_daemon
  • +
  • jvm_threads_deadlocked
  • +
  • jvm_threads_deadlocked_monitor
  • +
  • jvm_threads_peak
  • +
  • jvm_threads_started_total
  • +
  • jvm_threads_state
  • +
  • process_cpu_seconds_total
  • +
  • process_max_fds
  • +
  • process_open_fds
  • +
  • process_start_time_seconds
  • +
  • process_virtual_memory_bytes
  • +
  • metabase_email_messages_total
  • +
  • metabase_email_messages_created
  • +
  • metabase_email_message_errors_total
  • +
  • metabase_email_message_errors_created
  • +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/privacy.html b/_site/docs/doc-update-detection/installation-and-operation/privacy.html new file mode 100644 index 000000000..3c4e553d8 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/privacy.html @@ -0,0 +1,3052 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Privacy | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Privacy

+ +

Do you need a Data Processing Agreement with Metabase to comply with GDPR?

+ +

Self-hosted

+ +

If you self-host your Metabase instance, we have no access to any of your data, UNLESS you opted in to give us anonymized usage stats. Even in that case, Metabase doesn’t gather any personally-identifiable data. As such, if you’re self-hosting, we are not a data processor for the purposes of GDPR.

+ +

Metabase Cloud

+ +

If you’re a Metabase Cloud customer, your Terms of Service include a Data Processing Agreement (DPA).

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-azure.html b/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-azure.html new file mode 100644 index 000000000..f7abbe184 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-azure.html @@ -0,0 +1,3247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Running Metabase on Microsoft Azure | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Running Metabase on Microsoft Azure

+ +

This guide covers the basics for running your Metabase instance in Microsoft Azure using Docker.

+ +

Step 1: Create the resource group (resource grouping)

+ +

On the Azure management console, click on the Resource Groups icon at the top of the page (or just search for Resource Groups). If you already have a resource group, you can go straight to Step 2.

+ +

On the resource group page, click on the + Add button in the top bar to create a new resource group. On the Create a resource group page, select your valid Azure Subscription, enter the name of your resource group, and select a region.

+ +

Create a Resource Group

+ +

Click Next until you see the Create button, then click it.

+ +

When selecting the region for your Metabase, you should consider the location of your users and your data warehouse, as well as the infrastructure costs and privacy laws that might restrict cross-border data transfers.

+ +

Step 2: Create the VNET (virtual network)

+ +

At the center of the page, click on the Create resources button. Search for VNET:

+ +

VNET Marketplace

+ +

Select the VNET product from Microsoft, and click Create:

+ +

VNET Product

+ +

Enter a name for the virtual network and select the same region you used for the resource group. Click on Next: IP Addresses button at the bottom.

+ +

Here we’ll create a secure network composed of a public subnet (a network that is exposed to the internet), and a private network that will contain your application database.

+ +

In the IPv4 address, you should have a default value of 10.0.0.0/16 (otherwise add that network space to the box). Next, add two subnets:

+ +
    +
  • one subnet named public, with the subnet address range of 10.0.1.0/24, and
  • +
  • one subnet named private with the subnet range of 10.0.2.0/24.
  • +
+ +

Azure network configuration

+ +

Click Next until you get to the Review and create page, then click on the Create button at the bottom to create your network.

+ +

Step 3: Create the Application Database (PostgreSQL)

+ +

From the Azure Management console homepage, create a new resource. This time search for Azure Database for PostgreSQL. You can also find this database in the Marketplace menu under Databases.

+ +

Azure PostgreSQL

+ +

In the next page you will have to select the way you will use the service. Choose Single server for now, which is a good starting point, but take into account that this will create just one instance of PostgreSQL that will be your single point of failure.

+ +

On the next screen, select or enter the following:

+ +
    +
  • Resource group: the one you are including all your components.
  • +
  • Server name: a unique name for your database.
  • +
  • Data Source: can be left as None.
  • +
  • Location: the same one you used for your Resource Group and VNET.
  • +
  • Version: use the latest one you can.
  • +
  • Compute + Storage: you can re-dimension your database, but you must select the General Purpose tier, as it’s the only tier that provides a Private Link.
  • +
+ +

Then choose an admin username and password of your choice.

+ +

Click Next until you get to the final page, then click Create. It’ll take some time for Azure to create the database. Once the creation is complete, click on the Go to resource button.

+ +

Step 4: Create the private endpoint connection

+ +

On the properties page for the Azure for PostgreSQL database, you can manage parameters for your database. You’ll create the Private Endpoint to the database, so all traffic from the web application is routed internally through Azure’s network.

+ +

On the left menu, click on Private endpoint connection which is situated under Security

+ +

Azure Database for PostgreSQL

+ +

Now click on the button of the top bar with a plus sign that says Private endpoint. In the page that opens:

+ +
    +
  1. Provide a name for this link (any name that describes what you are trying to do is fine, like metabase_link). Select the region where the database lives, click Next.
  2. +
  3. On the Resource section of the configuration, ensure that Resource type is set to Microsoft.DBforPostgreSQL/servers which will enable you to select in the dropdown below the server created in the previous step, and leave Target sub-resource with the default value
  4. +
  5. On the Configuration section, the only value that needs to be changed is the Subnet one, where you need to select the private subnet that you created on the first step of this guide, and leave everything else as it is.
  6. +
+ +

Azure PrivateLink config

+ +

Now go to the last step and click Create. Once the endpoint is created, you will need do two things before proceeding:

+ +
    +
  1. In the page of database server you just created go to the database Connection Security item and deny all public network access.
  2. +
  3. In the page of the VNET you created in the previous step, go to Connected devices setting and you should see a device connected to the network. Take note of the IP address, as you’ll need it in Step 5 (this is the IP address that the network has given to the database server).
  4. +
+ +

Step 5: Create web application (deploy Metabase)

+ +

At last, the step where all the magic comes together: go to your resource group and add a new resource, or search for Web App in the Marketplace (blue globe icon). +Azure web app

+ +

Now set up the following values on the page (resource group should be the same as in the first step):

+ +
    +
  • Name: The name must be unique, as the subdomain is shared across all Azure deployments.
  • +
  • Publish: Docker Container.
  • +
  • Operating System: Linux.
  • +
  • Region: Use the same region as the previous steps.
  • +
  • App Service Plan: If you don’t have one a service plan, Azure will create a new one automatically.
  • +
  • SKU and Size: Set a Production level plan with AT LEAST 200 total ACU and 3.5GB of memory, and click Apply.
  • +
+ +

Now go to the next step where you will select:

+ +
    +
  • Options: Single container.
  • +
  • Image source: DockerHub.
  • +
  • Access Type: Public.
  • +
  • Image and tag: metabase/metabase:latest (or choose any other docker image tag of your preference, like our Enterprise Edition). To find the latest version, check our Community Edition Dockerhub repository and also our Enterprise Edition Dockerhub Repository.
  • +
  • Startup command: Leave this field empty.
  • +
+ +

Click Next until you get to the last section, then click Create, and wait while your application initializes.

+ +

Now go to the application configuration page and click on Settings -> Networking on the left side of the page. On the next page, click on Click here to configure under VNET integration.

+ +

Azure VNET integration

+ +

Now click on the huge plus sign next to Add VNET and select the VNET that you created, and the public subnet. Click OK.

+ +

Azure VNET public subnet

+ +

Return to the application configuration page and click on Settings -> Configuration on the left side of the page. You should see a few Application Settings already configured.

+ +

You’ll need to add the environment Variables for connecting Metabase to its PostgreSQL Application Database. Make sure that you use the full MB_DB_CONNECTION_URI.

+ +

Also, take into account that the username in Azure PostgreSQL is user@name_of_your_database_engine so in this case the entire connection uri would be as follows:

+ +
postgresql://databasePrivateIPAddress:port/postgres?user=user@name_of_your_database_engine&password=configuredpassword&ssl=true&sslmode=required
+
+ +

For example, if your values are:

+ +
    +
  1. database private IP address: 10.0.2.4
  2. +
  3. database port: 5432 (in the case of Postgres, MySQL/MariaDB default port is 3306)
  4. +
  5. name of the database server: metabase-app-database
  6. +
  7. username of the database: metabase
  8. +
  9. password: Password1!
  10. +
+ +

then your connection string would be:

+ +
postgresql://10.0.2.4:5432/postgres?user=metabase%40metabase-app-database&password=Password1!&ssl=true&sslmode=require
+
+ +

Note: the “@” character has been replaced for “%40”, as the “@” will no longer work in versions > 43

+ +

Click Save and the instance will restart.

+ +

Once it finishes, you should be able to visit your Metabase at the URL shown in the “Overview” tab in the web app (under the URL section).

+ +

Additional configurations

+ +

How to enable Health checks

+ +

Enabling health checking in Metabase is a good practice. Go to your web app -> Monitoring -> Health Check -> Enable health check, and include in the path /api/health.

+ +

How to upgrade

+ +

Go to the Metabase web app you created and click on Deployment -> Deployment Center.

+ +

Change the version of the container to the new version in the Full Image Name and Tag text field under Registry settings, and click on Save. Available versions of the Metabase Docker image can be found on Docker Hub.

+ +

Important: always ensure you have backed up the Metabase application database before upgrading, especially when doing so between major versions. Metabase also doesn’t officially support downgrading versions.

+ +

How to see the logs

+ +

Visit your web app in Azure, and navigate to Monitoring -> Log stream.

+ +

You should be able to see the logs as well inside Metabase by going to Settings -> Admin -> Troubleshooting -> Logs.

+ +

Performance tuning

+ +
    +
  • Disable FTP State
  • +
  • Change HTTP version to 2.0
  • +
  • Enable WebSockets
  • +
  • ARR Affinity enabled
  • +
+ +

Custom domains

+ +

In your Azure web app, visit Settings -> Custom domains to use a custom domain with your own certificates.

+ +

Scale-up vs Scale-out

+ +

Azure provides an easy way to increase the server’s capacity by doing a Scale-up. Simply choose a pricing tier with more RAM and CPU count and restart the instance. This approach is easier than scaling out and you should choose this option first before scaling out.

+ +

For a highly-available Metabase deployment, you can tell your web app to scale-out (more servers serving the application in parallel). Simply go to Scale-out and use the slider to ask for more instances, or use a custom autoscaling policy (like using more servers during your work hours and fewer during off hours).

+ +

CORS

+ +

In case you’re embedding Metabase, you might need to enable CORS in Settings -> CORS in the web application. You’ll need to fill the origin domains for the app with the embedded Metabase, so Azure knows to enable cross requests from those domains.

+ +

Database name

+ +

Azure does not let users create a database upon service creation, that’s the reason why we used postgres as the database to install Metabase. Although this shouldn’t be a problem, a good practice would be to install the database in a separate database named metabase. If you are not in a hurry to try the product, you should create a database named metabase as soon as you create the database and then use the appropriate connection string when deploying the docker container. +In the example above the connection string would be

+ +
postgresql://10.0.2.4:5432/metabase?user=metabase@metabase-app-database&password=Password1!&ssl=true&sslmode=require
+
+ +

If you have trouble connecting, refer to the postgres configuration instructions as you may run into a problem with an @ symbol in the username portion of the connection string. Using a combination of MB_DB_CONNECTION_URI with separate MB_DB_USER and MB_DB_PASSWORD fields also works.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-debian.html b/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-debian.html new file mode 100644 index 000000000..cc0024688 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-debian.html @@ -0,0 +1,3197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Running Metabase on Debian as a service with nginx | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Running Metabase on Debian as a service with nginx

+ +

For those people who don’t (or can’t) use Docker in their infrastructure, there’s still a need to easily setup and deploy Metabase in production. On Debian-based systems, this means registering Metabase as a service that can be started/stopped/uninstalled.

+ +

Note: This is just a bare-bones recipe to get you started. Anyone can take it from here to do what they need to do on their systems, and should follow best practices for setting up and securing the rest of their server.

+ +

Assumptions

+ +

The core assumption in this guide:

+ +
    +
  • You will run Metabase using the metabase.jar file
  • +
  • You already have nginx and postgres (or another supported database) running on your server
  • +
  • You will use environment variables to configure your Metabase instance
  • +
  • You have sudo access on your server
  • +
+ +

Create an unprivileged user to run Metabase and give the user access to app and logs

+ +

For security reasons we want to have Metabase run as an unprivileged user. We will call the user simply metabase. Further we will create the files we will need later for logging and configuration of Metabase, and apply the correct security settings for our unprivileged user.

+ +
sudo groupadd -r metabase
+sudo useradd -r -s /bin/false -g metabase metabase
+sudo chown -R metabase:metabase </your/path/to/metabase/directory>
+sudo touch /var/log/metabase.log
+sudo chown syslog:adm /var/log/metabase.log
+sudo touch /etc/default/metabase
+sudo chmod 640 /etc/default/metabase
+
+ +

Create a Metabase Service

+ +

Every service needs a script that tells systemd how to manage it, and what capabilities it supports. Services are typically registered at /etc/systemd/system/<servicename>. So, a Metabase service should live at /etc/systemd/system/metabase.service.

+ +

The Metabase service file

+ +

Create the /etc/systemd/system/metabase.service service file and open it in your editor:

+ +
sudo touch /etc/systemd/system/metabase.service
+sudo <your-editor> /etc/systemd/system/metabase.service
+
+ +

In /etc/systemd/system/metabase.service, replace configurable items (they look like <some-var-name>) with values sensible for your system. The Metabase script below has extra comments to help you know what everything is for.

+ +
[Unit]
+Description=Metabase server
+After=syslog.target
+After=network.target
+
+[Service]
+WorkingDirectory=</your/path/to/metabase/directory/>
+ExecStart=/usr/bin/java --add-opens java.base/java.nio=ALL-UNNAMED -jar </your/path/to/metabase/directory/>metabase.jar
+EnvironmentFile=/etc/default/metabase
+User=metabase
+Type=simple
+StandardOutput=syslog
+StandardError=syslog
+SyslogIdentifier=metabase
+SuccessExitStatus=143
+TimeoutStopSec=120
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+
+ +

Create syslog conf

+ +

Next we need to create a syslog conf to make sure systemd can handle the logs properly.

+ +
sudo touch /etc/rsyslog.d/metabase.conf
+sudo <your-editor> /etc/rsyslog.d/metabase.conf
+
+if $programname == 'metabase' then /var/log/metabase.log
+& stop
+
+ +

Restart the syslog service to load the new config.

+ +
sudo systemctl restart rsyslog.service
+
+ +

Environment variables for Metabase

+ +

Environment variables provide a good way to customize and configure your Metabase instance on your server. On Debian systems, services typically expect to have accompanying configs inside etc/default/<service-name>.

+ +

The Metabase config file

+ +

Open your /etc/default/metabase environment config file in your editor:

+ +
sudo <your-editor> /etc/default/metabase
+
+ +

In /etc/default/metabase, replace configurable items (they look like <some-var-name>) with values sensible for your system. Some Metabase configs have available options, some of which are shown below, separated by | symbols:

+ +
MB_PASSWORD_COMPLEXITY=<weak|normal|strong>
+MB_PASSWORD_LENGTH=<10>
+MB_JETTY_HOST=<0.0.0.0>
+MB_JETTY_PORT=<12345>
+MB_DB_TYPE=<postgres|mysql|h2>
+MB_DB_DBNAME=<your_metabase_db_name>
+MB_DB_PORT=<5432>
+MB_DB_USER=<your_metabase_db_user>
+MB_DB_PASS=<ssshhhh>
+MB_DB_HOST=<localhost>
+MB_EMOJI_IN_LOGS=<true|false>
+# any other env vars you want available to Metabase
+
+ +

Final steps

+ +

The best part of setting up Metabase as a service on a Debian-based system is to be confident it will start up at every system boot. We only have a few more quick steps to finish registering our service and having Metabase up and running.

+ +

Ensure your database is ready

+ +

If you’re running postgres or some other database, you need to ensure you’ve already followed the instructions for your database system to create a database for Metabase, as well as a user that can access that database. These values should match what you’ve set in your Metabase config for the MB_DB_TYPE, MB_DB_DBNAME, MB_DB_USER, and MB_DB_PASS environment variables. If you don’t have your database properly configured, Metabase won’t be able to start.

+ +

Ensure nginx is setup to proxy requests to Metabase

+ +

Getting into too much detail about configuring nginx is well outside the scope of this guide, but here’s a quick nginx.conf file that will get you up and running.

+ +

Note: The nginx.conf below assumes you are accepting incoming traffic on port 80 and want to proxy requests to Metabase, and that your Metabase instance is configured to run on localhost at port 3000. There are several proxy directives you may care about, so you should check those out further in the Official nginx docs.

+ +
# sample nginx.conf
+# proxy requests to Metabase instance
+server {
+  listen 80;
+  listen [::]:80;
+  server_name your.domain.com;
+  location / {
+    proxy_pass http://127.0.0.1:3000;
+  }
+}
+
+ +

Register your Metabase service

+ +

Now, it’s time to register our Metabase service with systemd so it will start up at system boot. We’ll also ensure our log file is created and owned by the unprivileged user our service runs the metabase.jar as.

+ +
sudo systemctl daemon-reload
+sudo systemctl start metabase.service
+sudo systemctl status metabase.service
+
+ +

Once we are ok here, enable the service to startup during boot.

+ +
sudo systemctl enable metabase.service
+
+ +

Start, stop, or restart Metabase

+ +

Now, whenever you need to start, stop, or restart Metabase, all you need to do is:

+ +
sudo systemctl start metabase.service
+sudo systemctl stop metabase.service
+sudo systemctl restart metabase.service
+
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-docker.html b/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-docker.html new file mode 100644 index 000000000..60d60758a --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-docker.html @@ -0,0 +1,3382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Running Metabase on Docker | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Running Metabase on Docker

+ +
+

To get fast, reliable, and secure deployment with none of the work or hidden costs that come with self-hosting, check out Metabase Cloud.

+
+ +

Metabase provides an official Docker image via Dockerhub that can be used for deployments on any system that is running Docker.

+ +

If you’re trying to upgrade your Metabase version on Docker, check out these upgrading instructions.

+ +

Open Source quick start

+ +

Use this quick start to run the Open Source version of Metabase locally. See below for instructions on running Metabase in production.

+ +

Assuming you have Docker installed and running, get the latest Docker image:

+ +
docker pull metabase/metabase:latest
+
+ +

Then start the Metabase container:

+ +
docker run -d -p 3000:3000 --name metabase metabase/metabase
+
+ +

This will launch an Metabase server on port 3000 by default.

+ +

Optional: to view the logs as your Open Source Metabase initializes, run:

+ +
docker logs -f metabase
+
+ +

Once startup completes, you can access your Open Source Metabase at http://localhost:3000.

+ +

To run your Open Source Metabase on a different port, say port 12345:

+ +
docker run -d -p 12345:3000 --name metabase metabase/metabase
+
+ +

Pro or Enterprise quick start

+ +

Use this quick start if you have a license token for a Pro or Enterprise version of Metabase, and you want to run Metabase locally. See below for instructions on running Metabase in production.

+ +

Assuming you have Docker installed and running, get the latest Docker image:

+ +
docker pull metabase/metabase-enterprise:latest
+
+ +

Then start the Metabase container:

+ +
docker run -d -p 3000:3000 --name metabase metabase/metabase-enterprise
+
+ +

This will launch a Metabase server on port 3000 by default.

+ +

Optional: to view the logs as Metabase initializes, run:

+ +
docker logs -f metabase
+
+ +

Once startup completes, you can access your Pro or Enterprise Metabase at http://localhost:3000.

+ +

To run your Pro or Enterprise Metabase on a different port, say port 12345:

+ +
docker run -d -p 12345:3000 --name metabase metabase/metabase-enterprise
+
+ +

Production installation

+ +

Metabase ships with an embedded H2 database that uses the file system to store its own application data. Meaning, if you remove the container, you’ll lose your Metabase application data (your questions, dashboards, collections, and so on).

+ +

If you want to run Metabase in production, you’ll need store your application data in a production-ready database.

+ +

Once you’ve provisioned a database, like Postgres, for Metabase to use to store its application data, all you need to do is provide Metabase with the connection information and credentials so Metabase can connect to it.

+ +

Running Docker in production

+ +

Let’s say you set up a Postgres database by running:

+ +
createdb metabaseappdb
+
+ +

No need to add any tables; Metabase will create those on startup. And let’s assume that database is accessible via my-database-host:5432 with username name and password password.

+ +

Here’s an example Docker command that tells Metabase to use that database:

+ +
docker run -d -p 3000:3000 \
+  -e "MB_DB_TYPE=postgres" \
+  -e "MB_DB_DBNAME=metabaseappdb" \
+  -e "MB_DB_PORT=5432" \
+  -e "MB_DB_USER=name" \
+  -e "MB_DB_PASS=password" \
+  -e "MB_DB_HOST=my-database-host" \
+   --name metabase metabase/metabase
+
+ +

Keep in mind that Metabase will be connecting from within your Docker container, so make sure that either: a) you’re using a fully qualified hostname, or b) that you’ve set a proper entry in your container’s /etc/hosts file.

+ +

Migrating to a production installation

+ +

If you’ve already been running Metabase with the default application database (H2), and want to use a production-ready application database without losing your app data (your questions, dashboards, etc), see Migrating from H2 to a production database.

+ +

Example Docker compose YAML file

+ +

Here’s an example docker-compose.yml file for running Metabase with a PostgreSQL database metabaseappdb:

+ +
+

This is an example file and and is not meant to be used when running Metabase in a production environment. Please refer to our guide about How to run Metabase in production

+
+ +
services:
+  metabase:
+    image: metabase/metabase:latest
+    container_name: metabase
+    hostname: metabase
+    volumes:
+      - /dev/urandom:/dev/random:ro
+    ports:
+      - 3000:3000
+    environment:
+      MB_DB_TYPE: postgres
+      MB_DB_DBNAME: metabaseappdb
+      MB_DB_PORT: 5432
+      MB_DB_USER: metabase
+      MB_DB_PASS: mysecretpassword
+      MB_DB_HOST: postgres
+    networks:
+      - metanet1
+    healthcheck:
+      test: curl --fail -I http://localhost:3000/api/health || exit 1
+      interval: 15s
+      timeout: 5s
+      retries: 5
+  postgres:
+    image: postgres:latest
+    container_name: postgres
+    hostname: postgres
+    environment:
+      POSTGRES_USER: metabase
+      POSTGRES_DB: metabaseappdb
+      POSTGRES_PASSWORD: mysecretpassword
+    networks:
+      - metanet1
+networks:
+  metanet1:
+    driver: bridge
+
+ +

Additional Docker maintenance and configuration

+ + + +

Customizing the Metabase Jetty server

+ +

You can use any of the custom settings from Customizing the Metabase Jetty Webserver by setting environment variables in your Docker run command.

+ +

Docker-specific environment variables

+ +

In addition to the standard custom settings there are two docker specific environment variables MUID and MGID which are used to set the user and group IDs used by metabase when running in a docker container. These settings make it possible to match file permissions when files, such as the application database, are shared between the host and the container.

+ +

Here’s how to use a database file, owned by your account and stored in your home directory:

+ +
docker run -d -v ~/my-metabase-db:/metabase.db --name metabase -e MB_DB_FILE=/metabase.db -e MUID=$UID -e MGID=$GID -p 3000:3000 metabase/metabase
+
+ +

Setting the Java Timezone

+ +

It’s best to set your Java timezone to match the timezone you’d like all your reports to come in. You can do this by simply specifying the JAVA_TIMEZONE environment variable which is picked up by the Metabase launch script. For example:

+ +
docker run -d -p 3000:3000 \
+  -e "JAVA_TIMEZONE=US/Pacific" \
+  --name metabase metabase/metabase
+
+ +

Copying the application database

+ +

The default location for the application database in the container is /metabase.db/metabase.db.mv.db. You can copy this directory out of the container using the following command (replacing CONTAINER_ID with the actual container ID or name, metabase if you named the container):

+ +
docker cp CONTAINER_ID:/metabase.db ./
+
+ +

The DB contents will be left in a directory named metabase.db.

+ +

Mounting a mapped file storage volume

+ +

To persist your data outside of the container and make it available for use between container launches, we can mount a local file path inside our container.

+ +
docker run -d -p 3000:3000 \
+  -v ~/metabase-data:/metabase-data \
+  -e "MB_DB_FILE=/metabase-data/metabase.db" \
+  --name metabase metabase/metabase
+
+ +

When you launch your container, Metabase will use the database file (MB_DB_FILE) at ~/metabase-data/metabase.db instead of its default location. and we are mounting that folder from our local filesystem into the container.

+ +

Getting your config back if you stopped your container

+ +

If you’ve previously run and configured your Metabase using the local Database and then stopped the container, your data will still be there unless you deleted the container with the docker rm command. To recover your previous configuration:

+ +

1. Find the stopped container using the docker ps -a command. It will look something like this:

+ +
docker ps -a | grep metabase
+    ca072cd44a49        metabase/metabase        "/app/run_metabase.sh"   About an hour ago   Up About an hour          0.0.0.0:3000->3000/tcp   metabase
+    02e4dff057d2        262aa3d0f714             "/app/run_metabase.sh"   23 hours ago        Exited (0) 23 hours ago                            pedantic_hypatia
+    0d2170d4aa4a        262aa3d0f714             "/app/run_metabase.sh"   23 hours ago        Exited (0) 23 hours ago                            stoic_lumiere
+
+ +

Once you have identified the stopped container with your configuration in it, save the container ID from the left most column for the next step.

+ +

2. Use docker commit to create a new custom docker image from the stopped container containing your configuration.

+ +
docker commit ca072cd44a49 mycompany/metabase-custom
+sha256:9ff56186de4dd0b9bb2a37c977c3a4c9358647cde60a16f11f4c05bded1fe77a
+
+ +

3. Run your new image using docker run to get up and running again.

+ +
docker run -d -p 3000:3000 --name metabase mycompany/metabase-custom
+430bb02a37bb2471176e54ca323d0940c4e0ee210c3ab04262cb6576fe4ded6d
+
+ +

You should have your previously configured Metabase Installation back. If it’s not the one you expected, try a different stopped container and repeat these steps.

+ +

Adding external dependencies or plugins

+ +

To add external dependency JAR files, such as the Oracle or Vertica JDBC drivers or 3rd-party Metabase drivers), you’ll need to:

+ +
    +
  • create a plugins directory in your host system, and
  • +
  • bind that directory so it’s available to Metabase as the path /plugins (using either --mount or -v/--volume).
  • +
+ +

For example, if you have a directory named /path/to/plugins on your host system, you can make its contents available to Metabase using the --mount option as follows:

+ +
docker run -d -p 3000:3000 \
+  --mount type=bind,source=/path/to/plugins,destination=/plugins \
+  --name metabase metabase/metabase
+
+ +

Note that Metabase will use this directory to extract plugins bundled with the default Metabase distribution (such as drivers for various databases such as SQLite), thus it must be readable and writable by Docker.

+ +

Use Docker Secrets to hide sensitive parameters

+ +

In order to keep your connection parameters hidden from plain sight, you can use Docker Secrets to put all parameters in files so Docker can read and load them in memory before it starts the container.

+ +

Here is an example docker-compose.yml file to start a Metabase Docker container with secrets to connect to a PostgreSQL database.

+ +

In addition to this example yml file, you’ll need to create two files:

+ +
    +
  • db_user.txt
  • +
  • db_password.txt
  • +
+ +

These files should be in the same directory as the docker-compose.yml. Put the db_user in the db_user.txt file, and db_password in the db_password.txt file.

+ +

Notice the “_FILE” on the environment variables that have a secret:

+ +
services:
+  metabase:
+    image: metabase/metabase:latest
+    container_name: metabase
+    hostname: metabase
+    volumes:
+      - /dev/urandom:/dev/random:ro
+    ports:
+      - 3000:3000
+    environment:
+      MB_DB_TYPE: postgres
+      MB_DB_DBNAME: metabase
+      MB_DB_PORT: 5432
+      MB_DB_USER_FILE: /run/secrets/db_user
+      MB_DB_PASS_FILE: /run/secrets/db_password
+      MB_DB_HOST: postgres
+    networks:
+      - metanet1
+    secrets:
+      - db_password
+      - db_user
+    healthcheck:
+      test: curl --fail -I http://localhost:3000/api/health || exit 1
+      interval: 15s
+      timeout: 5s
+      retries: 5
+  postgres:
+    image: postgres:latest
+    container_name: postgres
+    hostname: postgres
+    environment:
+      POSTGRES_USER_FILE: /run/secrets/db_user
+      POSTGRES_DB: metabase
+      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
+    networks:
+      - metanet1
+    secrets:
+      - db_password
+      - db_user
+networks:
+  metanet1:
+    driver: bridge
+secrets:
+  db_password:
+    file: db_password.txt
+  db_user:
+    file: db_user.txt
+
+ +

We currently support the following environment variables to be used as secrets:

+ +
    +
  • MB_DB_USER
  • +
  • MB_DB_PASS
  • +
  • MB_DB_CONNECTION_URI
  • +
  • MB_EMAIL_SMTP_PASSWORD
  • +
  • MB_EMAIL_SMTP_USERNAME
  • +
  • MB_LDAP_PASSWORD
  • +
  • MB_LDAP_BIND_DN
  • +
+ +

In order for the Metabase container to read the files and use the contents as a secret, the environment variable name needs to be appended with a “_FILE” as explained above.

+ +
+

This is an example file and and is not meant to be used when running Metabase in a production environment. Please refer to our guide about How to run Metabase in production.

+
+ +

Troubleshooting

+ +

See Running Metabase in the Troubleshooting guide.

+ +

Continue to setup

+ +

Now that you’ve installed Metabase, it’s time to set it up and connect it to your database.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-elastic-beanstalk.html b/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-elastic-beanstalk.html new file mode 100644 index 000000000..073efb79b --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-elastic-beanstalk.html @@ -0,0 +1,3123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Running Metabase on AWS Elastic Beanstalk | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Running Metabase on AWS Elastic Beanstalk

+ +
+

Due to problems with the platform, we no longer recommend using Elastic Beanstalk to run Metabase in production.

+
+ +

If you’re running Metabase on Elastic Beanstalk, we recommend you switch to a different setup.

+ +

Alternatives to Elastic Beanstalk

+ +

Metabase Cloud

+ +

We recommend Metabase Cloud (obviously).

+ +

Self-hosted setups

+ +

You can set up Metabase with either PostgreSQL or MySQL as its application database, and run Metabase on a server you can monitor, either on your hardware or with a cloud provider.

+ +

At a minimum, make sure you back up your application database regularly (and always before upgrading). Follow your organization’s requirements for security, monitoring, and availability.

+ +

Professional services

+ +

If you’d like help with setting up Metabase (or building out your data stack in general), check out the professional services we offer.

+ +

Decouple your RDS database from the Elastic Beanstalk deployment

+ +

If you’re using AWS’s Relational Database Service to store your Metabase application data, you can continue to do so (though you should still move your Metabase installation away from Elastic Beanstalk). You can use environment variables to connect to your RDS host from wherever you move your Metabase installation to.

+ +

Notify people that your Metabase will be down for a bit

+ +

This procedure will generate downtime, so make sure to communicate to your users that Metabase will be down while you recreate the environment with the new database.

+ +

Get a snapshot of your application database

+ +
+

You’ll need the master username and password for the database you used when you created the Elastic Beanstalk instance.

+
+ +

Identify the RDS endpoint that your Elastic Beanstalk is using by going to the configuration of the Environment and finding the endpoint value on the Database section.

+ +

RDS endpooint

+ +
    +
  • If Retention is “Create snapshot”, you’re good to go. You can delete the whole Elastic Beanstalk environment, because AWS will take a snapshot (backup) of the database before deleting the environment.
  • +
  • +

    If Retention has a different value, visit your RDS instance and take a snapshot of the database used by the Elastic Beanstalk application.

    + +

    RDS snapshot

    +
  • +
+ +

Terminate your Elastic Beanstalk environment with snapshot

+ +

Go to the Elastic Beanstalk Metabase application, select the running environment, and terminate it. Confirm that the database will be terminated with snapshot.

+ +

Terminate environment

+ +

Terminating the environment can take around 20 minutes. If the deletion fails, you’ll have to identify through CloudFormation which resources failed to be deleted and delete them yourself.

+ +

Restore your snapshot

+ +

Return to RDS and select the Snapshots option on the left of the page. You should see a Manual Snapshot listed.

+ +

RDS Snapshots

+ +

Select that snapshot and click on Actions > Restore Snapshot.

+ +

From this step on, you can follow the same steps as the Configuring RDS for Metabase.

+ +

Upgrade your Elastic Beanstalk deployment

+ +

If you want to stay in Elastic Beanstalk, you can keep upgrading it by following these steps:

+ +
    +
  1. Download the last published Beanstalk artifact file.
  2. +
  3. Unzip the file.
  4. +
  5. Edit the Dockerrun.aws.json file and change the image tag to the latest available version. Always Avoid using :latest, instead, use the latest version number.
  6. +
  7. Compress the file.
  8. +
  9. Upload the file to AWS as a new Beanstalk version.
  10. +
  11. Upgrade your environment.
  12. +
+ +

Remember that if you’re using a Pro or Enterprise version of Metabase, you need to use the metabase/metabase-enterprise repository instead of the metabase/metabase one.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-podman.html b/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-podman.html new file mode 100644 index 000000000..a14e440c2 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/running-metabase-on-podman.html @@ -0,0 +1,3182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Running Metabase on Podman | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Running Metabase on Podman

+ +

Our official Metabase Docker image is compatible on any system that is running Podman.

+ +

Open Source quick start

+ +

Assuming you have Podman installed and running, get the latest container image:

+ +
podman pull docker.io/metabase/metabase:latest
+
+ +

Then start the Metabase container:

+ +
podman run -d -p 3000:3000 --name=metabase docker.io/metabase/metabase:latest
+
+ +

This will launch an Metabase server on port 3000 by default.

+ +

Optional: to view the logs as your Open Source Metabase initializes, run:

+ +
podman logs -f metabase
+
+ +

Once startup completes, you can access your Open Source Metabase at http://localhost:3000.

+ +

To run your Open Source Metabase on a different port, say port 12345:

+ +
podman run -d -p 12345:3000 --name=metabase docker.io/metabase/metabase:latest
+
+ +

Pro or Enterprise quick start

+ +

Use this quick start if you have a license token for a Pro or Enterprise version of Metabase, and you want to run Metabase locally.

+ +

Assuming you have Podman installed and running, get the latest container image:

+ +
podman pull docker.io/metabase/metabase-enterprise:latest
+
+ +

Then start the Metabase container:

+ +
podman run -d -p 3000:3000 --name=metabase docker.io/metabase/metabase-enterprise:latest
+
+ +

This will launch a Metabase server on port 3000 by default.

+ +

Optional: to view the logs as Metabase initializes, run:

+ +
podman logs -f metabase
+
+ +

Once startup completes, you can access your Pro or Enterprise Metabase at http://localhost:3000.

+ +

To run your Pro or Enterprise Metabase on a different port, say port 12345:

+ +
podman run -d -p 12345:3000 --name=metabase docker.io/metabase/metabase-enterprise:latest
+
+ +

Production installation

+ +

Metabase ships with an embedded H2 database that uses the file system to store its own application data. Meaning, if you remove the container, you’ll lose your Metabase application data (your questions, dashboards, collections, and so on).

+ +

If you want to run Metabase in production, you’ll need store your application data in a production-ready database.

+ +

Once you’ve provisioned a database, like Postgres, for Metabase to use to store its application data, all you need to do is provide Metabase with the connection information and credentials so Metabase can connect to it.

+ +

Running Podman in production

+ +

Let’s say you set up a Postgres database by running:

+ +
createdb metabaseappdb
+
+ +

No need to add any tables; Metabase will create those on startup. And let’s assume that database is accessible via my-database-host:5432 with username name and password password.

+ +

Here’s an example Podman command that tells Metabase to use that database:

+ +
podman run -d -p 3000:3000 \
+  -e "MB_DB_TYPE=postgres" \
+  -e "MB_DB_DBNAME=metabaseappdb" \
+  -e "MB_DB_PORT=5432" \
+  -e "MB_DB_USER=name" \
+  -e "MB_DB_PASS=password" \
+  -e "MB_DB_HOST=my-database-host" \
+   --name metabase metabase/metabase
+
+ +

Keep in mind that Metabase will be connecting from within your Podman container, so make sure that either: a) you’re using a fully qualified hostname, or b) that you’ve set a proper entry in your container’s /etc/hosts file.

+ +

Migrating to a production installation

+ +

If you’ve already been running Metabase with the default application database (H2), and want to use a production-ready application database without losing your app data (your questions, dashboards, etc), see Migrating from H2 to a production database.

+ +

Additional Podman maintenance and configuration

+ + + +

Running Metabase as a service

+ +

We can use the systemd initialization service to register a Metabase service that can be started and stopped automatically. Prior to executing this process, ensure that the Metabase container is operational. Then, utilize Podman’s built-in feature to generate the service file as follows:

+ +
sudo podman generate systemd --new --name metabase > metabase.service
+
+ +

Before executing the service, inspect the contents of the metabase.service file to verify that all the accurate configurations are present. Once confirmed, locate the service file to the appropriate location by running the command:

+ +
sudo mv metabase.service /etc/systemd/system
+
+ +

To enable the automatic initiation of the Metabase service during system boot, execute:

+ +
sudo systemctl enable metabase
+
+ +

To verify that the system functions correctly, reboot the system. Upon completion of the system initialization process, the Metabase container should be operational as intended.

+ +

Customizing the Metabase Jetty server

+ +

You can use any of the custom settings from Customizing the Metabase Jetty Webserver by setting environment variables in your Podman run command.

+ +

Setting the Java Timezone

+ +

It’s best to set your Java timezone to match the timezone you’d like all your reports to come in. You can do this by simply specifying the JAVA_TIMEZONE environment variable which is picked up by the Metabase launch script. For example:

+ +
podman run -d -p 3000:3000 \
+  -e "JAVA_TIMEZONE=US/Pacific" \
+  --name metabase metabase/metabase
+
+ +

Troubleshooting

+ +

See Running Metabase in the Troubleshooting guide.

+ +

Continue to setup

+ +

Now that you’ve installed Metabase, it’s time to set it up and connect it to your database.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/running-the-metabase-jar-file.html b/_site/docs/doc-update-detection/installation-and-operation/running-the-metabase-jar-file.html new file mode 100644 index 000000000..09f20b224 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/running-the-metabase-jar-file.html @@ -0,0 +1,3204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Running the Metabase JAR file | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Running the Metabase OSS JAR file

+ +
+

We recommend running Metabase on Metabase Cloud. If you need to self-host, you can run Metabase as a standalone JAR, but we recommend running Metabase in a Docker container.

+
+ +

To run the free, Open Source version of Metabase via a JAR file, you will need to have a Java Runtime Environment (JRE) installed on your system.

+ +

If you have a token for the Pro or Enterprise editions of Metabase, see Activating your Metabase commercial license.

+ +

Quick start

+ +
+

The quick start is intended for running Metabase locally. See below for instructions on running Metabase in production.

+
+ +

If you have Java installed:

+ +
    +
  1. Download the JAR file for Metabase OSS. If you’re on a Pro or Enterprise plan, download the JAR for the Enterprise Edition.
  2. +
  3. Create a new directory and move the Metabase JAR into it.
  4. +
  5. Change into your new Metabase directory and run the JAR.
  6. +
+ +
java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

Metabase will log its progress in the terminal as it starts up. Wait until you see “Metabase Initialization Complete” and visit http://localhost:3000/setup.

+ +

If you are using a Pro or Enterprise version, be sure to activate your license.

+ +

Local installation

+ +

If you just want to try Metabase out, play around with Metabase, or just use Metabase on your local machine, Metabase ships with a default application database that you can use. This setup is not meant for production. If you intend to run Metabase for real at your organization, see Production installation.

+ +

The below instructions are the same as the quick start above, just with a little more context around each step.

+ +

1. Install Java JRE

+ +

You may already have Java installed. To check the version, open a terminal and run:

+ +
java -version
+
+ +

If Java isn’t installed, you’ll need to install Java before you can run Metabase. We recommend version 21 of JRE from Eclipse Temurin with HotSpot JVM. You can run Metabase wherever Java 21 runs. Earlier Java versions aren’t supported. The particular processor architecture shouldn’t matter (although we only test Metabase for x86 and ARM).

+ +

2. Download Metabase

+ +

Download the JAR file:

+ + + +

If you want to install the Pro or Enterprise editions of Metabase, see Activating your Metabase commercial license.

+ +

3. Create a new directory and move the Metabase JAR into it

+ +

When you run Metabase, Metabase will create some new files, so it’s important to put the Metabase Jar file in a new directory before running it (so move it out of your downloads folder and put it a new directory).

+ +

On posix systems, the commands would look something like this:

+ +

Assuming you downloaded to /Users/person/Downloads:

+ +
mkdir ~/metabase
+
+ +

then

+ +
mv /Users/person/Downloads/metabase.jar ~/metabase
+
+ +

4. Change into your new Metabase directory and run the jar

+ +

Change into the directory you created in step 2:

+ +
cd ~/metabase
+
+ +

Now that you have Java working you can run the JAR from a terminal with:

+ +
java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

Metabase will start using the default settings. You should see some log entries starting to run in your terminal window showing you the application progress as it starts up. Once Metabase is fully started you’ll see a confirmation such as:

+ +
...
+06-19 10:29:34 INFO metabase.task :: Initializing task CheckForNewVersions
+06-19 10:29:34 INFO metabase.task :: Initializing task SendAnonymousUsageStats
+06-19 10:29:34 INFO metabase.task :: Initializing task SendAbandomentEmails
+06-19 10:29:34 INFO metabase.task :: Initializing task SendPulses
+06-19 10:29:34 INFO metabase.task :: Initializing task SendFollowUpEmails
+06-19 10:29:34 INFO metabase.task :: Initializing task TaskHistoryCleanup
+06-19 10:29:34 INFO metabase.core :: Metabase Initialization COMPLETE
+
+ +

At this point you’re ready to go! You can access your new Metabase server on port 3000, most likely at http://localhost:3000.

+ +

You can use another port than 3000 by setting the MB_JETTY_PORT environment variable before running the jar.

+ +

If you are using a Pro or Enterprise version of Metabase, be sure to activate your license.

+ +

Production installation

+ +

The steps are similar to those steps above with two important differences: if you want to run Metabase in production, you’ll want to:

+ + + +

If you’d prefer to use Docker, check out running Metabase on Docker.

+ +

Production application database

+ +

Here are some databases we support.

+ +

For example, say you want to use PostgreSQL. You would get a PostgreSQL service up and running and create an empty database:

+ +
createdb metabaseappdb
+
+ +

You can call your app db whatever you want. And there’s no need to create any tables in that database; Metabase will do that for you. You’ll just need to set environment variables for Metabase to use on startup so Metabase knows how to connect to this database.

+ +

You’ll create a directory for your Metabase like in the steps listed above for the Local installation, but when it’s time to run the java --add-opens java.base/java.nio=ALL-UNNAMED -jar command to start up the JAR, you’ll prefix the command with some environment variables to tell Metabase how to connect to the metabaseappdb you created:

+ +
export MB_DB_TYPE=postgres
+export MB_DB_DBNAME=metabaseappdb
+export MB_DB_PORT=5432
+export MB_DB_USER=username
+export MB_DB_PASS=password
+export MB_DB_HOST=localhost
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

The above command would connect Metabase to your Postgres database, metabaseappdb via localhost:5432 with the user account username and password password. If you’re running Metabase as a service, you’ll put these environment variables in a separate configuration file.

+ +

Running the Metabase JAR as a service

+ +

If you need to run the JAR in production, you should run Metabase as a service. Running Metabase as a service will:

+ +
    +
  • Make sure Metabase runs automatically (and stay running).
  • +
  • Allow you to run Metabase with an unprivileged user (which is good for security).
  • +
+ +

The exact instructions for how to run Metabase as a service will differ depending on your operating system. For an example of how to set up Metabase as a service, check out Running Metabase on Debian.

+ +

Migrating to a production installation

+ +

If you’ve been running Metabase with the default H2 application database and your team has already created questions, dashboards, collections and so on, you’ll want to migrate that data to a production application database. And the sooner you do, the better. See Migrating from the H2 database.

+ +

Troubleshooting

+ +

If you run into any problems during installation, check out our troubleshooting page.

+ +

Upgrading Metabase

+ +

See Upgrading Metabase.

+ +

Setting up Metabase

+ +

Now that you’ve installed Metabase, it’s time to set it up and connect it to your database.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/serialization.html b/_site/docs/doc-update-detection/installation-and-operation/serialization.html new file mode 100644 index 000000000..1046e5b99 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/serialization.html @@ -0,0 +1,3886 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Serialization | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Serialization

+ +
+
+ + + + + + + +

Serialization is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Once you really get rolling with Metabase, it’s often the case that you’ll have more than one Metabase instance spun up. You might have a couple of testing or development instances and a few production ones, or maybe you have a separate Metabase per office or region.

+ +

To help you out in situations like this, Metabase has a serialization feature which lets you create an export of the contents of a Metabase that can then be imported into one or more Metabases.

+ +

Export will serialize the contents of your source Metabase as YAML files.

+ +

Import will read those exported YAML files and create or update items in the target Metabase based on the contents serialized in those YAML files.

+ +

There are two ways to run these export and import commands:

+ + + +
+

We’re interested in how we can improve serialization to suit your workflow. Upvote an existing issue to let us know it’s important to you. If a relevant issue doesn’t yet exist, please create one and tell us what you need.

+
+ +

Serialization use cases

+ +
    +
  • Staging environments. Enable a staging-to-production workflow for important dashboards by exporting from a staging instance of Metabase and then importing them into your production instance(s).
  • +
  • Version control. Check the exported files into version control and audit changes to them, as the YAML files contained within the export are pretty readable.
  • +
  • Duplicating assets to other Metabase instances. Export the “template” data from a source Metabase and import them to one or more target instances.
  • +
+ +

Check out our guides for:

+ + + +
+

Serialization isn’t intended for use cases like duplicating assets or swapping data sources within the same Metabase instance. If you’re using serialization for duplicating assets within the same instance, check out How export works, How import works, and the directions for your use case in Other uses of serialization

+
+ +

How export works

+ + + +

What gets exported

+ +

Metabase will only export the following entities:

+ +
    +
  • Collections (but personal collections don’t get exported unless explicitly specified them through export options)
  • +
  • Dashboards
  • +
  • Saved questions
  • +
  • Actions
  • +
  • Models
  • +
  • Metrics
  • +
  • Snippets
  • +
  • Data model and table metadata
  • +
  • Segments
  • +
  • Public sharing settings for questions and dashboards
  • +
  • General Metabase settings
  • +
  • Events and timelines
  • +
  • Database connection strings (only if specified through export options).
  • +
+ +

All other entities—including users, groups, permissions, alerts, subscriptions—won’t get exported.

+ +

Metabase will export its artifacts to a directory of YAML files. The export includes:

+ +
    +
  • +

    Directories that contain YAML files for various Metabase entities. +An example export could include the following directories, depending on what you exported and the contents of your Metabase:

    + +
      +
    • actions
    • +
    • collections +
        +
      • cards
      • +
      • dashboards
      • +
      • timelines
      • +
      +
    • +
    • databases
    • +
    + +

    When serializing through the API, the export directory will be a compressed into a .tar.gz file.

    +
  • +
  • +

    A settings.yaml file that includes some Metabase-wide settings

    +
  • +
+ +

Database connection details are not included by default, so you but you can configure your export to include them.

+ +

General Metabase settings that are exported

+ +

Here’s the list of the general settings Metabase exports in the settings.yaml file. For more on Metabase settings, see Configuring Metabase.

+ +
humanization-strategy
+native-query-autocomplete-match-style
+site-locale
+report-timezone-short
+report-timezone-long
+application-name
+enable-xrays
+show-homepage-pin-message
+source-address-header
+enable-nested-queries
+custom-geojson-enabled
+start-of-week
+custom-geojson
+available-timezones
+unaggregated-query-row-limit
+aggregated-query-row-limit
+hide-embed-branding?
+search-typeahead-enabled
+enable-sandboxes?
+application-font
+available-locales
+landing-page
+enable-embedding
+application-colors
+application-logo-url
+application-favicon-url
+show-homepage-xrays
+show-metabot
+enable-whitelabeling?
+show-homepage-data
+site-name
+application-font-files
+loading-message
+report-timezone
+persisted-models-enabled
+enable-content-management?
+subscription-allowed-domains
+breakout-bins-num
+available-fonts
+custom-formatting
+
+ +

Customize what gets exported

+ +

You can customize what gets exported. You can tell Metabase:

+ +
    +
  • Export specific collections
  • +
  • Do not export collections
  • +
  • Do not export Metabase settings
  • +
  • Do not export table metadata
  • +
  • Include sample field values (excluded by default)
  • +
  • Include database connection details (excluded by default)
  • +
+ +

See export parameters in CLI commands or export parameters in API calls.

+ +

Example of a serialized question

+ +

Questions can be found in the cards directory of a collection directory. Here’s an example card YAML file for a question written with SQL that uses a field filter and has an area chart visualization.

+ +
+

To preserve a native query’s multi-line format, remove trailing whitespace from native queries. If your native query has trailing whitespace, YAML will convert your query to a single string literal (which only affects presentation, not functionality).

+
+ +
name: Products by week
+description: Area chart of products created by week
+entity_id: r6vC_vLmo9zG6_r9sAuYG
+created_at: "2024-05-08T19:10:24.348808Z"
+creator_id: admin@metabase.local
+display: area
+archived: false
+collection_id: onou5H28Wvy3kWnjxxdKQ
+collection_preview: true
+collection_position: null
+query_type: native
+dataset: false
+cache_ttl: null
+database_id: Sample Database
+table_id: null
+enable_embedding: false
+embedding_params: null
+made_public_by_id: null
+public_uuid: null
+parameters:
+  - default:
+      - Gizmo
+    id: c37d2f38-05fa-48c4-a208-19d9dba803c6
+    name: Pick a category
+    slug: category_filter
+    target:
+      - dimension
+      - - template-tag
+        - category_filter
+    type: string/=
+parameter_mappings: []
+dataset_query:
+  database: Sample Database
+  native:
+    query: |-
+      SELECT
+        category,
+        date_trunc ('week', created_at) AS "Week",
+        count(*) AS "Count"
+      FROM
+        products
+      WHERE
+        
+      GROUP BY
+        category,
+        "Week"
+    template-tags:
+      category_filter:
+        default:
+          - Gizmo
+        dimension:
+          - field
+          - - Sample Database
+            - PUBLIC
+            - PRODUCTS
+            - CATEGORY
+          - base-type: type/Text
+        display-name: Pick a category
+        id: c37d2f38-05fa-48c4-a208-19d9dba803c6
+        name: category_filter
+        type: dimension
+        widget-type: string/=
+  type: native
+result_metadata:
+  - base_type: type/Text
+    display_name: CATEGORY
+    effective_type: type/Text
+    field_ref:
+      - field
+      - CATEGORY
+      - base-type: type/Text
+    name: CATEGORY
+    semantic_type: null
+  - base_type: type/DateTime
+    display_name: Week
+    effective_type: type/DateTime
+    field_ref:
+      - field
+      - Week
+      - base-type: type/DateTime
+    name: Week
+    semantic_type: null
+  - base_type: type/BigInteger
+    display_name: Count
+    effective_type: type/BigInteger
+    field_ref:
+      - field
+      - Count
+      - base-type: type/BigInteger
+    name: Count
+    semantic_type: type/Quantity
+visualization_settings:
+  column_settings: null
+  graph.dimensions:
+    - Week
+    - CATEGORY
+  graph.metrics:
+    - Count
+serdes/meta:
+  - id: r6vC_vLmo9zG6_r9sAuYG
+    label: products_created_by_week
+    model: Card
+initially_published_at: null
+metabase_version: v1.49.7 (f0ff786)
+type: question
+
+ +

Metabase uses Entity IDs to identify and reference Metabase items

+ +

Metabase assigns a unique Entity ID to every Metabase item (a dashboard, question, model, collection, etc.). These Entity IDs are in addition to the sequential IDs Metabase generates. Entity IDs use the NanoID format, and are stable across Metabases. By “stable” we mean that you can, for example, export a dashboard with an entity ID from one Metabase, and import that dashboard into another Metabase and have that dashboard use the same Entity ID, even though it’s in a different Metabase.

+ +

To get an item’s Entity ID in Metabase:

+ +
    +
  1. Visit the item in Metabase.
  2. +
  3. Click on the info button.
  4. +
  5. In the overview tab, copy the Entity ID.
  6. +
+ +

You can also see the Entity IDs of items in the exported YAML files in the entity_id field. For example, in the Example of a serialized question, you’ll see the Entity ID of that question:

+ +
entity_id: r6vC_vLmo9zG6_r9sAuYG
+
+ +

This ID also appears in the serdes/meta → id field (these IDs must match):

+ +
serdes/meta:
+  - id: r6vC_vLmo9zG6_r9sAuYG
+
+ +

To disambiguate entities that share the same name, Metabase includes Entity IDs in the file and directory names for exported entities.

+ +
r6vC_vLmo9zG6_r9sAuYG_products_by_week.yaml
+IA96oUzmUbYfNFl0GzhRj_accounts_model.yaml
+KUEGiWvoBFEc5oGQCEnPg_converted_customers.yaml
+
+ +

For example, in the Example of a serialized question above, you can see the field collection_id:

+ +
collection_id: onou5H28Wvy3kWnjxxdKQ
+
+ +

This ID refers to the collection where the question was saved. In a real export, you’d be able to find a YAML file for this collection whose name starts with its ID: onou5H28Wvy3kWnjxxdKQ.

+ +

Entity IDs work with embedding

+ +

Metabase supports working with Entity IDs for questions, dashboards, and collections in Static Embedding, Interactive embedding, and the Embedded Analytics SDK.

+ +

A high-level workflow for using Entity IDs when embedding Metabase in your app would look something like:

+ +
    +
  1. Create a dashboard in a Metabase running locally on your machine.
  2. +
  3. Embed the dashboard in your app locally using the Entity ID in your application code.
  4. +
  5. Export your Metabase changes to YAML files via serialization.
  6. +
  7. Import your Metabase changes (the exported YAML files) to your production Metabase.
  8. +
  9. Since the Entity ID remains the same in the production Metabase, you can just push the code in your app to production, and the code will refer to the right dashboard.
  10. +
+ +

Databases, schemas, tables, and fields are identified by name

+ +

By default, Metabase exports some database and data model settings. Exports exclude database connection strings by default. You can explicitly include database connection strings. You can also choose to exclude the data model entirely.

+ +

Metabase serializes databases and tables in the databases directory. It will include YAML files for every database, table, field, segment, and metric.

+ +

Databases, tables, and fields are referred to by their names (unlike Metabase-specific items, which are referred to by Entity IDs).

+ +

For example, in the Example of a serialized question, there are several YAML keys that reference Sample Database:

+ +
database_id: Sample Database
+---
+dataset_query:
+  database: Sample Database
+
+ +

In the description of the field filter (category_filter:) in that example, you can see the reference to the field that’s used to populate the filter options:

+ +
dimension:
+  - field
+  - - Sample Database
+    - PUBLIC
+    - PRODUCTS
+    - CATEGORY
+
+ +

It refers to the CATEGORY field in the PRODUCTS table in the PUBLIC schema in Sample Database. The serialized Sample Database in the databases directory will also include YAML files for this field and table.

+ +

How import works

+ +

During import, Metabase will read the provided YAML files and create items according to the YAML specs. Example of a serialized question how Metabase records information it needs to reconstruct an item.

+ +

Metabase will not delete items from target instance during import, but it will overwrite items that already exist.

+ +

Metabase relies on Entity IDs to figure out which items to create or overwrite, and what are the relationships between items. When importing into an instance that already has some content in it, keep in mind:

+ +
    +
  • +

    If you import an item with an entity_id that doesn’t exist in your target Metabase, Metabase will create a new item.

    +
  • +
  • +

    If you import an item with an entity_id that already exists in your target Metabase, the existing item will be overwritten.

    + +

    In particular, this means that if you export a question, then make a change in an exported YAML file — like rename a question by directly editing the name field — and then import the edited file back, Metabase will try to apply the changes you made to the YAML.

    +
  • +
  • +

    If you import an item with a blank entity_id, Metabase will create a new item. Any serdes/meta → id will be ignored in this case.

    +
  • +
  • +

    All items and data sources referenced in YAML must either exist in the target Metabase already, or be included in the import.

    + +

    For example, if an exported YAML has the field collection_id: onou5H28Wvy3kWnjxxdKQ, then the collection onou5H28Wvy3kWnjxxdKQ must already exist in target instance, or there must be a YAML file with the export of a collection that has this ID.

    +
  • +
+ +

Serialization best practices

+ +

Use the same Metabase version for source and target instance

+ +

Currently, serialization only works if source and target Metabase have the same major version. +If you are using the CLI serialization commands, the version of the .jar file that you are using to run the serialization commands should match both the source and target Metabase versions as well.

+ +

If you’re using H2 as your application database, you’ll need to stop Metabase before importing or exporting

+ +

If you’re using Postgres or MySQL as your application database, you can import and export while your Metabase is still running.

+ +

Avoid using serialization for backups

+ +

Just a note: serialization is not meant to back up your Metabase.

+ +

See Backing up Metabase.

+ +

If you’re instead looking to do a one-time migration from the default H2 database included with Metabase to a MySQL/Postgres, then use the migration guide instead.

+ +

You’ll need to manually add license tokens

+ +

Metabase excludes your license token from exports, so if you’re running multiple environments of Metabase Enterprise Edition, you’ll need to manually add your license token to the target Metabase(s), either via the Metabase user interface, or via an environment variable.

+ +

Metabase adds logs to exports and imports

+ +

Exports: Metabase adds logs to the compressed directory as export.log.

+ +

Imports: You can add the -o - flag to export logs directly into the terminal, or -o import.log to save to a file.

+ +

Serialization with CLI commands

+ +
+

To serialize data on Metabase Cloud, use the import and export API endpoints

+
+ +

Metabase provides export and import CLI commands.

+ +

See How export works, How import works, and Serialization best practices for general information about serialization.

+ +

Exporting with CLI

+ +

To export the contents of a Metabase instance, change into the directory where you’re running the Metabase JAR and run:

+ +
java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar export dir_name
+
+ +

Where dir_name can be whatever you want to call the directory.

+ +

export options

+ +

To view a list of export options, use the help command:

+ +
java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar help export
+
+ +

Which will run and then print something like:

+ +
export path & options
+	 Serialize Metabase instance into directory at `path`.
+	 Options:
+	   -c, --collection ID             Export only specified ID; may occur multiple times.
+	   -C, --no-collections            Do not export any content in collections.
+	   -S, --no-settings               Do not export settings.yaml
+	   -D, --no-data-model             Do not export any data model entities; useful for subsequent exports.
+	   -f, --include-field-values      Include field values along with field metadata.
+	   -s, --include-database-secrets  Include database connection details (in plain text; use caution).
+
+ +

--collection

+ +

By default, Metabase will include all collections (except for personal collections) in the export. To include personal collections, you must explicitly add them with the --collection flag.

+ +

The --collection flag (alias -c) lets you specify by ID one or more collections to include in the export. You can find the collection ID in the collection’s URL, e.g., for a collection at: your-metabase.com/collection/42-terraforming-progress, the ID would be 42.

+ +

If you want to specify multiple collections, separate the IDs with commas. E.g.,

+ +
java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar export export_name --collection 1,2,3
+
+ +

--no-collections

+ +

The --no-collections flag (alias -C) tells Metabase to exclude all collections from the export.

+ +

--no-settings

+ +

The --no-settings flag (alias -S) tells Metabase to exclude the settings.yaml file that includes site-wide settings, which is exported by default.

+ +

--no-data-model

+ +

The --no-data-model flag (alias -D) tells Metabase to exclude the Table Metadata settings from the export. Admins define the metadata settings in the Table Metadata tab of the Admin settings.

+ +

--include-field-values

+ +

The --include-field-values flag (alias -f) tells Metabase to include the sample values for field values, which Metabase uses to present dropdown menus. By default, Metabase excludes these sample field values.

+ +

--include-database-secrets

+ +

The --include-database-secrets flag (alias -s) tells Metabase to include connection details, including the database user name and password. By default, Metabase excludes these database connection secrets. If you don’t use this flag, you’ll need to manually input the credentials in the target Metabase.

+ +

Importing with CLI

+ +

To import exported artifacts into a Metabase instance, go to the directory where you’re running your target Metabase (the Metabase you want to import into) and use the following command, where path_to_export is the path to the export that you want to import:

+ +
java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar import path_to_export
+
+ +

Currently, you can only import exported artifacts into a Metabase instance that was created from the same version of Metabase.

+ +

import options

+ +

Most options are defined when exporting data from a Metabase. To view a list of import flags, run:

+ +
java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar help import
+
+ +

Which prints out:

+ +
import path & options
+         Load serialized Metabase instance as created by the [[export]] command from directory `path`.
+
+ +

Serialization via the API

+ +
+

Just like the CLI serialization commands, these endpoints are only available for Pro and Enterprise plans.

+
+ +

You can import and export serialized Metabase data via Metabase’s API, which makes serialization possible for Metabase Cloud deployments.

+ +

There are two endpoints:

+ +
    +
  • POST /api/ee/serialization/export
  • +
  • POST /api/ee/serialization/import
  • +
+ +
+

We use POST, not GET, for the /export endpoint. The export operation does not modify your Metabase, but it’s long and intensive, so we use POST to prevent accidental exports.

+
+ +

For now, these endpoints are synchronous. If the serialization process takes too long, the request can time out. In this case, we suggest using the CLI commands.

+ +

See How export works, How import works, and Serialization best practices for general information about serialization.

+ +

API export parameters

+ +

You can append optional parameters to tell Metabase what to include or exclude from the export. You can also combine parameters (excluding, of course, all_collections and selective collections).

+ +

So, assuming you’re testing on localhost, and you want to exclude all collections from the export, you’d format the URL like so:

+ +
http://localhost:3000/api/ee/serialization/export?all_collections=false
+
+ +

You can include multiple parameters, separated by &. For example, to exclude both the settings and the data model from the export:

+ +
http://localhost:3000/api/ee/serialization/export?data_model=false&settings=false
+
+ +

collection

+ +

Type: Array of integers.

+ +

Default value: Metabase will export all collections, unless all_collections is set to false.

+ +

To select which collections to export, include the collection IDs. For example, to include collections 1 and 2:

+ +
collection=1&collection=2
+
+ +

all_collections

+ +

Type: Boolean

+ +

Default: true (unless you specify a subset of collections with collection).

+ +

To exclude all collections:

+ +
all_collections=false
+
+ +

settings

+ +

Type: Boolean.

+ +

Default: true.

+ +

To exclude the settings.yaml file that contains site-wide settings:

+ +
settings=false
+
+ +

data_model

+ +

Type: Boolean.

+ +

Default: true.

+ +

To exclude the Table Metadata:

+ +
data_model=false
+
+ +

field_values

+ +

Type: Boolean.

+ +

Default: false.

+ +

To include the sample values for field values, which Metabase uses to present dropdown menus:

+ +
field_values=true
+
+ +

database_secrets

+ +

Type: Boolean.

+ +

Default: false.

+ +

To include database connection details, like the database username and password:

+ +
database_secrets=true
+
+ +

dirname

+ +

Type: String.

+ +

Default: <instance-name>-<YYYY-MM-dd_HH_mm>

+ +

To specify a different directory:

+ +
dirname=name_of_your_directory
+
+ +

You must compress your files when serializing via API calls

+ +

To keep file sizes over the network under control, both the export and import endpoints expect GZIP-compressed Tar files (.tgz).

+ +

Compress a directory

+ +

To compress a directory (e.g., a directory named metabase_data).

+ +
tar -czf  metabase_data.tgz metabase_data
+
+ +

Extract a directory

+ +

To extract/unzip a directory:

+ +
tar -xvf  metabase_data.tgz
+
+ +

Serialization API example

+ +

Step 1: Set up an API key

+ +
    +
  1. Create an API key.
  2. +
  3. Assign the key to the Admin group
  4. +
+ +

Step 2: Export

+ +
    +
  1. Send a curl request to export data:
  2. +
+ +
curl \
+  -H 'x-api-key: YOUR_API_KEY' \
+  -X POST 'http://your-metabase-url/api/ee/serialization/export' \
+  -o metabase_data.tgz
+
+ +

substituting YOUR_API_KEY with your API key and your-metabase-url with the URL of your Metabase instance.

+ +
+

We use POST, not GET, for the /export endpoint.

+
+ +

This command will download the files as a GZIP-compressed Tar file named metabase_data.tgz.

+ +
    +
  1. Unzip the compressed file:
  2. +
+ +
tar -xvf metabase_data.tgz
+
+ +

The extracted directory will be called something like metabase-yyyy-MM-dd_HH-mm, with the date and time of the export.

+ +

Step 3: Import

+ +
    +
  1. Compress the directory containing serialized Metabase application data
  2. +
+ +

Let’s say you have your YAML files with Metabase application data in a directory called metabase_data. Before importing those files to your target Metabase, you’ll need to compress those files.

+ +
tar -czf metabase_data.tgz metabase_data
+
+ +
    +
  1. POST to /api/ee/serialization/import.
  2. +
+ +

From the directory where you’ve stored your GZIP-compressed file, run:

+ +
curl -X POST \
+  -H 'x-api-key: YOUR_API_KEY' \
+  -F file=@metabase_data.tgz \
+  'http://your-metabase-url/api/ee/serialization/import' \
+  -o -
+
+ +

substituting YOUR_API_KEY with your API key and your-metabase-url with your Metabase instance URL. +The -o - option will output logs in the terminal.

+ +
+

If you import Metabase data into the same Metabase as you exported it from, you will overwrite your existing questions, dashboards, etc. See How import works.

+
+ +

Other uses of serialization

+ +

Serialization is intended for version control, staging-to-production workflows, and duplicating assets to other Metabase instances. While it’s possible to use serialization for other use cases (like duplicating assets within a single instance), we don’t officially support these use cases.

+ +

We’re providing some directions on how to approach these unsupported use cases, but you should use them at your own risk. We strongly recommend that you test any process involving serialization on a non-production instance first, and reach out to help@metabase.com if you have any questions.

+ +

Using serialization for duplicating content within the same Metabase

+ +

Using serialization to duplicate content is not trivial, because you’ll need to wrangle Entity IDs for all the items you want to duplicate — and the IDs for all the items that are related to those items — to avoid overwriting existing data.

+ +

Before starting this perilous journey, review how export works and how import works, and contact help@metabase.com if you have any questions.

+ +

You’ll need to keep in mind:

+ +
    +
  • Importing an item with an Entity ID that already exists will overwrite the existing item. To use an existing YAML file to create a new item, you’ll need to either a) create a new Entity ID or b) clear the Entity ID.
  • +
  • Two items cannot have the same Entity IDs.
  • +
  • entity_id and serdes/meta → id fields in the YAML file should match.
  • +
  • If the entity_id and serdes/meta → id fields in a YAML file for an item are blank, Metabase will create a new item with a new Entity ID.
  • +
  • +

    All items and data sources referenced by an item should either already exist in target Metabase or be included in the import.

    + +

    For example, a collection can contain a dashboard that contains a question that is built on a model that references a data source. All of those dependencies must be either included in the import or already exist in the target instance.

    + +

    This means that you might need a multi-stage export/import: create some of the items you need (like collections) in Metabase first, export them to get their Entity IDs, then export the stuff that you want to duplicate and use those IDs in items that reference them.

    +
  • +
+ +

For example, to duplicate a collection that contains only questions that are built directly on raw data (not on models or other saved questions), without changing the data source for the questions, you can use a process like this:

+ +
    +
  1. In Metabase, create a “template” collection and add the items you’d like to duplicate.
  2. +
  3. In Metabase, create a new collection which will serve as the target for duplicated items.
  4. +
  5. Export the template collection and the target collection (you can use export parameters to export only a few collections). +The YAML files for template questions in the export will have their own Entity IDs and reference the Entity ID of the template collection.
  6. +
  7. Get the Entity ID of the target collection from its export.
  8. +
  9. +

    In the YAML files for questions in the template collection export:

    + +
      +
    • Clear the values for the fields entity_id and serdes/meta → id for questions. This will ensure that the template questions don’t get overwritten, and instead Metabase will create new questions.
    • +
    • Replace collection_id references to the template collection with the ID of the new collection
    • +
    +
  10. +
  11. Import the edited files.
  12. +
+ +

This process assumes that your duplicated questions will all use the same data source. You can combine this with switching the data source to use a different data source for every duplicated collection.

+ +

If you want to create multiple copies of a collection at once, then instead of repeating this process for every copy, you could create your own target Entity IDs (they can be any string that uses the NanoID format), duplicate all the template YAML files, and replace template Entity IDs and any references to them with your created Entity IDs.

+ +

If your collections contains dashboards, models, and other items that can add dependencies, this process can become even more complicated – you need to handle every dependency. We strongly recommend that you first test your serialization on a non-production Metabase, and reach out to help@metabase.com if you need any help.

+ +

Using serialization to swap the data source for questions within one instance

+ +

If you want to change the data source for some of the questions in your Metabase — for example, just for questions in a single collection - you can serialize the questions manually, then edit the exported YAML files.

+ +
+

If you want to switch every question built on database A to use database B instead, and database B has exactly the same schema as database A, you don’t need to use serialization: you can just swap the connection string in Admin > Databases

+
+ +

Your databases must have the same engine, and ideally they should have the same schema.

+ +

You’ll need to keep in mind:

+ +
    +
  • Databases, tables and fields are referred to in Metabase by name
  • +
  • Database connection details are not exported by default. To export database connection details, you’ll need to specify this in export parameters.
  • +
  • Databases, tables and fields referenced by an item should either already exist in the target Metabase, or be included in the import.
  • +
+ +

For example, if you want to switch all questions in the Movie reviews collection to use the Romance database instead of the Horror database, and both databases have the same schema, you could follow a process like this:

+ +
    +
  1. In Metabase, add a new database connection in Admin > Databases and name it Romance.
  2. +
  3. +

    Export the collection Movie reviews.

    + +

    You can tell Metabase to export a single collection, or you can export all the collections and just work with files in the folder for the Movie reviews collection

    +
  4. +
  5. In the YAML files for items from this collection, replace all references to Horror database with references to Romance
  6. +
  7. Import the edited files.
  8. +
+ +

Importing will overwrite the original questions. If you’re looking to create new questions that use a different data source, you can combine this process with Using serialization for duplicating assets.

+ +

This process assumes that your new data source has exactly the same schema. If the schema is different, then you will also need to replace all references to all tables and fields. This process can be complicated and error-prone, so we strongly recommend that you test your serialization on a non-production instance first, and reach out to help@metabase.com if you need any help.

+ +

Migrating from the old serialization commands

+ +

If you’re upgrading from Metabase version 46.X or older, here’s what you need to know:

+ +
    +
  • The export command replaces the dump command.
  • +
  • The import command replace the load command.
  • +
+ +

A few other changes to call out:

+ +
    +
  • The exported YAML files have a slightly different structure: +
      +
    • Metabase will prefix each file with a 24-character Entity ID (like IA96oUzmUbYfNFl0GzhRj_accounts_model.yaml). +You can run a Metabase command to drop Entity IDs before exporting.
    • +
    • The file tree is slightly different.
    • +
    +
  • +
  • To serialize personal collections, you just need to include the personal collection IDs in the list of comma-separated IDs following the -c option (short for --collection).
  • +
+ +

If you’ve written scripts to automate serialization, you’ll need to:

+ +
    +
  • Reserialize your Metabase using the upgraded Metabase (which uses the new export and import commands). Note that serialization will only work if you export and import your Metabase using the same Metabase version.
  • +
  • Update those scripts with the new commands. See the new export options.
  • +
  • If your scripts do any post-processing of the exported YAML files, you may need to update your scripts to accommodate the slightly different directory and YAML file structures.
  • +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/start.html b/_site/docs/doc-update-detection/installation-and-operation/start.html new file mode 100644 index 000000000..1badc7614 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/start.html @@ -0,0 +1,3095 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Installation and operation overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Installation and operation overview

+ +

The birth, care, and feeding of your Metabase.

+ +

Installing Metabase

+ +

Options for installing Metabase.

+ +

Migrating to a production database

+ +

If you started using Metabase with the default, H2 application database, here’s how to migrate your data to a production-ready database.

+ +

Configuring the Metabase application database

+ +

Use environment variables to set up your application database.

+ +

Backing up Metabase application data

+ +

How to back up your Metabase data: questions, dashboards, and other application data.

+ +

Upgrading Metabase

+ +

How to safely upgrade your Metabase.

+ +

Serialization

+ +

Export your questions, dashboards, and more as YAML files that you can check into version control.

+ +

Monitoring your Metabase

+ +

Monitor your Metabase with JMX.

+ +

Observability with Prometheus

+ +

Export Metabase metrics for viewing with Prometheus.

+ +

Supported browsers

+ +

Rest in peace, Internet Explorer.

+ +

About the anonymous usage data we collect.

+ +

We collect anonymous Metabase usage data to improve the product. We don’t collect your data.

+ +

Accessibility

+ +

Notes on Metabase’s accessibility.

+ +

Command line commands

+ +

Metabase’s CLI.

+ +
+ +

If you’d like more technical resources to set up your data stack with Metabase, connect with a Metabase Expert.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/supported-browsers.html b/_site/docs/doc-update-detection/installation-and-operation/supported-browsers.html new file mode 100644 index 000000000..eee2979a9 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/supported-browsers.html @@ -0,0 +1,3054 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Supported browsers | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Supported browsers

+ +

We try our best to make sure Metabase works in as many browsers as possible, but as this is the Internet, there may be little quirks from time to time in different settings. We believe Metabase works on these versions of these browsers and will attempt to fix specific bugs if any are found:

+ +
    +
  • Chrome (v70+)
  • +
  • Firefox (v68+)
  • +
  • Microsoft Edge (v17+)
  • +
  • Safari (v11+)
  • +
+ +

Metabase may run perfectly well on older versions of these browsers or on specific browsers not listed above, but your mileage may vary. In particular, we ended support for IE11 in Metabase 0.40: it mostly still works, but you may see some unexpected behavior.

+ +

We recommend you use the most up-to-date browser you can.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/installation-and-operation/upgrading-metabase.html b/_site/docs/doc-update-detection/installation-and-operation/upgrading-metabase.html new file mode 100644 index 000000000..c93626647 --- /dev/null +++ b/_site/docs/doc-update-detection/installation-and-operation/upgrading-metabase.html @@ -0,0 +1,3239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Upgrading Metabase | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Upgrading Metabase

+ +

Instructions for upgrading to a new Metabase release.

+ +

Backing up your application database

+ +

The application database keeps track of all of your people, dashboards, questions, collections, permissions: all the application data in Metabase (that is, everything but the data you’ve connected to Metabase). While it’s unlikely you’ll need to roll back to your current version, a backup will do wonders for your peace of mind.

+ +

See Backing up Metabase application data.

+ +

Swapping in the new Metabase version

+ +

Steps differ depending on whether you’re running the JAR or a Docker image.

+ +

Upgrading a JAR running locally

+ +

If you’re running the JVM Jar file directly:

+ +
    +
  1. +

    Back up your application database.

    +
  2. +
  3. +

    Download the latest version of the JAR file:

    + + +
  4. +
  5. +

    Use a terminal to access your existing Metabase process and kill it (usually CTRL-C).

    +
  6. +
  7. +

    Replace the existing JAR file (metabase.jar) in your Metabase directory with the newer version.

    +
  8. +
  9. +

    Restart the server:

    + +
    java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
    +
    +
  10. +
+ +

On startup, Metabase will perform any tasks it needs to complete the upgrade. Once Metabase has completed those tasks, you’ll be running the new version.

+ +

Upgrading a JAR running in production as a service

+ +

To upgrade, you’ll need to stop the service, replace the JAR with the newer version, and restart the service.

+ +

E.g., if you’re running Metabase on Debian as a service using Nginx.

+ +
    +
  1. +

    Back up your application database.

    +
  2. +
  3. +

    Download the latest version of the JAR file:

    + + +
  4. +
  5. +

    Stop the Metabase service. Aassuming you called your service metabase.service), you’ll run:

    + +
    sudo systemctl stop metabase.service
    +
    +
  6. +
  7. +

    In your Metabase directory on your server, replace the current (older) Metabase JAR file with the newer JAR you downloaded.

    +
  8. +
  9. +

    Restart the service:

    + +
    sudo systemctl restart metabase.service
    +
    +
  10. +
+ +

Upgrading the Docker image

+ +

If you’re running Metabase in a Docker container:

+ +
    +
  1. +

    Back up your application database.

    + +
    +

    WARNING: If you’re not using a production-ready database, your application data (questions, dashboards, and so on) will have been stored in an H2 database inside your container. Upgrading requires swapping out your existing container for a new image with the upgraded Metabase JAR, which will wipe out your application data. We recommend switching to a production-ready database before you upgrade.

    +
    +
  2. +
  3. +

    Stop the current Docker container.

    +
  4. +
  5. +

    Pull the latest Metabase Docker image.

    + +

    Metabase Open Source:

    + +
    docker pull metabase/metabase:latest
    +
    + +

    Metabase Pro or Enterprise:

    + +
    docker pull metabase/metabase-enterprise:latest
    +
    +
  6. +
  7. +

    Start the new Docker container. Depending on the ports and what you want to name the container, the command will look something like:

    + +

    Metabase Open Source:

    + +
    docker run -d -p 3000:3000 -e MB_DB_CONNECTION_URI="jdbc:postgresql://<host>:5432/metabase?user=<username>&password=<password>" --name metabase metabase/metabase:latest
    +
    + +

    Metabase Pro or Enterprise:

    + +
    docker run -d -p 3000:3000 -e MB_DB_CONNECTION_URI="jdbc:postgresql://<host>:5432/metabase?user=<username>&password=<password>" --name metabase metabase/metabase-enterprise:latest
    +
    +
  8. +
+ +

On startup, Metabase will perform the upgrade automatically. Once Metabase has completed the upgrade, you’ll be running the new version.

+ +

Upgrading from older versions of Metabase

+ +

If you’re on a Metabase version older than Metabase 40, you’ll need to upgrade release by release until you’re on the latest version of Metabase 40. From the latest version of Metabase 40, you can then jump to the current version of Metabase.

+ +

For example, if you’re running Metabase 1.38, your upgrade path would look like:

+ +
    +
  • 1.38.X
  • +
  • 1.39.X
  • +
  • 1.40.X
  • +
  • Latest
  • +
+ +

With X being the latest version available for each release.

+ +

Check out a list of Metabase releases.

+ +

Upgrading Metabase Cloud

+ +

If you’re on a Metabase Cloud plan, we’ll upgrade your Metabase automatically with each new release; no action needed on your end. How soon we upgrade you depends on the type of release:

+ +
    +
  • Minor releases (e.g., x.47.4 to x.47.5): Usually about a week.
  • +
  • Major releases (e.g., x.47.4 to x.48.0): Longer, usually weeks (just to make sure everything goes smoothly).
  • +
+ +

Cloud customers can request an early upgrade by emailing support at help@metabase.com. Include the URL of the Metabase you want us to upgrade.

+ +

Upgrading Metabase on other platforms

+ + + +

Rolling back an upgrade

+ +

In general, regular backups (especially backups before upgrading), are the best policy, so we recommend reverting to a backup of your application database to roll back an upgrade.

+ +

But if you’ve made changes to your application database since upgrading that you want to keep, you may be able to use the migrate down command to roll back your Metabase application database to support the previous Metabase version you were running. When Metabase upgrades to a new version, it runs migrations that may change the application database schema. The migrate down command undoes those schema changes. In general, we recommend restoring from a backup (the backup that you definitely remembered to generate before upgrading), and only using the migrate down command if you really need to keep changes made after your upgrade.

+ +

Using the migrate down command

+ +

Stop your Metabase and use the current, upgraded Metabase JAR (not the Metabase JAR you want to roll back to) to complete the rollback with the migrate down command. Make sure that the connection details for your application database are set in the environment variables, for example:

+ +
export MB_DB_TYPE=postgres
+export MB_DB_DBNAME=metabaseappdb
+export MB_DB_PORT=5432
+export MB_DB_USER=username
+export MB_DB_PASS=password
+export MB_DB_HOST=localhost
+java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar migrate down
+
+ +

If you’re running Docker, use the command "migrate down" (with the quotes around "migrate down"), and include the connection details for your application database, for example:

+ +
docker run
+  -e "MB_DB_TYPE=postgres" \
+  -e "MB_DB_DBNAME=metabaseappdb" \
+  -e "MB_DB_PORT=5432" \
+  -e "MB_DB_USER=name" \
+  -e "MB_DB_PASS=password" \
+  -e "MB_DB_HOST=my-database-host" \
+--rm metabase/metabase "migrate down"
+
+ +

If you’re running Docker Compose with the right environments variables, the command would be:

+ +
docker compose run metabase "migrate down"
+
+ +

Note the quotes around "migrate down" for the Docker and Docker compose command.

+ +

Once the migration process completes, start up Metabase using the JAR or Docker image for the version you want to run.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/operations-guide.html b/_site/docs/doc-update-detection/operations-guide.html new file mode 100644 index 000000000..9664adb8b --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/advanced-topics-for-running-Metabase-in-AWS-ElasticBeanstalk.html b/_site/docs/doc-update-detection/operations-guide/advanced-topics-for-running-Metabase-in-AWS-ElasticBeanstalk.html new file mode 100644 index 000000000..add30644a --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/advanced-topics-for-running-Metabase-in-AWS-ElasticBeanstalk.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/backing-up-metabase-application-data.html b/_site/docs/doc-update-detection/operations-guide/backing-up-metabase-application-data.html new file mode 100644 index 000000000..5a12411ce --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/backing-up-metabase-application-data.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/changing-password-complexity.html b/_site/docs/doc-update-detection/operations-guide/changing-password-complexity.html new file mode 100644 index 000000000..f2067f753 --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/changing-password-complexity.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/changing-session-expiration.html b/_site/docs/doc-update-detection/operations-guide/changing-session-expiration.html new file mode 100644 index 000000000..6bfffe37e --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/changing-session-expiration.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/configuring-application-database.html b/_site/docs/doc-update-detection/operations-guide/configuring-application-database.html new file mode 100644 index 000000000..500d7ff2a --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/configuring-application-database.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/creating-RDS-database-on-AWS.html b/_site/docs/doc-update-detection/operations-guide/creating-RDS-database-on-AWS.html new file mode 100644 index 000000000..7078e2c10 --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/creating-RDS-database-on-AWS.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/customizing-jetty-webserver.html b/_site/docs/doc-update-detection/operations-guide/customizing-jetty-webserver.html new file mode 100644 index 000000000..5f62c8e3c --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/customizing-jetty-webserver.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/enable-jmx.html b/_site/docs/doc-update-detection/operations-guide/enable-jmx.html new file mode 100644 index 000000000..52ba3c19a --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/enable-jmx.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/encrypting-database-details-at-rest.html b/_site/docs/doc-update-detection/operations-guide/encrypting-database-details-at-rest.html new file mode 100644 index 000000000..d25b452fc --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/encrypting-database-details-at-rest.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/environment-variables.html b/_site/docs/doc-update-detection/operations-guide/environment-variables.html new file mode 100644 index 000000000..fe1371434 --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/environment-variables.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/handling-timezones.html b/_site/docs/doc-update-detection/operations-guide/handling-timezones.html new file mode 100644 index 000000000..ebbd591be --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/handling-timezones.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/installing-metabase.html b/_site/docs/doc-update-detection/operations-guide/installing-metabase.html new file mode 100644 index 000000000..ff28bf608 --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/installing-metabase.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/jmx-monitoring.html b/_site/docs/doc-update-detection/operations-guide/jmx-monitoring.html new file mode 100644 index 000000000..52ba3c19a --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/jmx-monitoring.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/log-configuration.html b/_site/docs/doc-update-detection/operations-guide/log-configuration.html new file mode 100644 index 000000000..95b524890 --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/log-configuration.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/migrating-from-h2.html b/_site/docs/doc-update-detection/operations-guide/migrating-from-h2.html new file mode 100644 index 000000000..e2d67e03a --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/migrating-from-h2.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/running-metabase-on-azure.html b/_site/docs/doc-update-detection/operations-guide/running-metabase-on-azure.html new file mode 100644 index 000000000..a527a230e --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/running-metabase-on-azure.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/running-metabase-on-debian.html b/_site/docs/doc-update-detection/operations-guide/running-metabase-on-debian.html new file mode 100644 index 000000000..d04b64274 --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/running-metabase-on-debian.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/running-metabase-on-docker.html b/_site/docs/doc-update-detection/operations-guide/running-metabase-on-docker.html new file mode 100644 index 000000000..f0e383865 --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/running-metabase-on-docker.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/running-metabase-on-elastic-beanstalk.html b/_site/docs/doc-update-detection/operations-guide/running-metabase-on-elastic-beanstalk.html new file mode 100644 index 000000000..add30644a --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/running-metabase-on-elastic-beanstalk.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/running-metabase-on-podman.html b/_site/docs/doc-update-detection/operations-guide/running-metabase-on-podman.html new file mode 100644 index 000000000..e529b8d76 --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/running-metabase-on-podman.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/running-migrations-manually.html b/_site/docs/doc-update-detection/operations-guide/running-migrations-manually.html new file mode 100644 index 000000000..e2d67e03a --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/running-migrations-manually.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/running-the-metabase-jar-file.html b/_site/docs/doc-update-detection/operations-guide/running-the-metabase-jar-file.html new file mode 100644 index 000000000..2c19233fd --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/running-the-metabase-jar-file.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/operations-guide/upgrading-metabase.html b/_site/docs/doc-update-detection/operations-guide/upgrading-metabase.html new file mode 100644 index 000000000..8549ba1de --- /dev/null +++ b/_site/docs/doc-update-detection/operations-guide/upgrading-metabase.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/paid-features/activating-the-enterprise-edition.html b/_site/docs/doc-update-detection/paid-features/activating-the-enterprise-edition.html new file mode 100644 index 000000000..114cd93ce --- /dev/null +++ b/_site/docs/doc-update-detection/paid-features/activating-the-enterprise-edition.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/people-and-groups/accessibility.html b/_site/docs/doc-update-detection/people-and-groups/accessibility.html new file mode 100644 index 000000000..8bd147d9d --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/accessibility.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/people-and-groups/account-settings.html b/_site/docs/doc-update-detection/people-and-groups/account-settings.html new file mode 100644 index 000000000..38c14f481 --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/account-settings.html @@ -0,0 +1,3070 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Account settings | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Account settings

+ +

You can view your account settings by going to the top right of the screen and clicking on the gear icon > Account settings.

+ +

Account profile

+ +

You can set your first and last names, change your email address, and set your language. See our list of supported languages.

+ +

Account password

+ +

You can change your password here. Note that if your Metabase uses Single Sign-On (SSO), your administrator will have disabled this password section, as your identity provider will manage logins.

+ +

If you’re having trouble logging in, see our People can’t log into Metabase.

+ +

Account login history

+ +

The login history lists each login, along with some location information (if available), and some client information (like Browser (Firefox/Windows)). +If you see any suspicious login attempts, change your password and notify your administrator.

+ +

A note about new login emails

+ +

Whenever you log in from a new device, Metabase will send you an email just to let you know someone (presumably you) has logged in from an unrecognized device. If you see this email, but don’t remember logging in, or don’t recognize the device, change your password and let your administrator know.

+ +

Disable animations in Metabase

+ +

This isn’t an in-Metabase setting, but just so you know: you can disable UI animations in Metabase (like sidebars sliding around, or rotating spinners) by changing the settings for your operating system so it respects the prefers-reduced-motion CSS media feature. This change will also affect other applications, not just Metabase. Check out the instructions for how to set the user preferences for your operating system in the MDN Web Docs.

+ +

Notifications

+ +

If you subscribe or are added to dashboard subscriptions or alerts, you’ll be able to manage those notifications here (as well as on the relevant question or dashboard themselves).

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/api-keys.html b/_site/docs/doc-update-detection/people-and-groups/api-keys.html new file mode 100644 index 000000000..ed5f3234b --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/api-keys.html @@ -0,0 +1,3162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +API keys | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

API keys

+ +

Metabase can create API keys to authenticate programmatic requests to the API. To set the permissions for an API key, you can assign the key to a group.

+ +

Fair warning about Metabase’s API

+ +

We don’t version the Metabase API. We rarely change API endpoints, and almost never remove them, but if you write code that relies on the API, there’s a chance you might have to update your code in the future.

+ +

That said, there are times when it’s nice to work with the API, like when managing permissions with a large number of people and groups, or bulk archiving, or content creation. So we added the ability to create API keys to authenticate your programmatic requests.

+ +

Create an API key

+ +

To create an API key:

+ +
    +
  1. Click on the gear icon in the upper right.
  2. +
  3. Select Admin settings.
  4. +
  5. Go to the Settings tab.
  6. +
  7. Click on the Authentication tab on the left menu.
  8. +
  9. Scroll to API Keys and click Manage.
  10. +
  11. Click the Create API Key button.
  12. +
  13. Enter a Key name. You can have multiple API keys, so give it a name that will help you remember what you’re using the key for.
  14. +
  15. Select a Group. The key will have the same permissions granted to that group.
  16. +
  17. Click Create.
  18. +
  19. Copy the generated API key and save it somewhere safe. Metabase won’t be able to show you the key again. If you lose the key, you’ll need to regenerate a new key.
  20. +
+ +

Creating API keys from the config file

+ +

If you’re on a Pro or Enterprise self-hosted plan, you can create API keys via the configuration file.

+ +

Managing API Keys

+ +

To view and manage existing API keys:

+ +
    +
  1. Click on the gear icon in the upper right.
  2. +
  3. Select Admin settings.
  4. +
  5. Go to the Settings tab.
  6. +
  7. Click on the Authentication tab on the left menu.
  8. +
  9. Scroll to API Keys and click Manage.
  10. +
+ +

Editing API keys

+ +

To edit an API key, scroll to the key you want to edit and click on the pencil icon. Metabase will pop up an Edit API Key modal where you can edit:

+ +
    +
  • The key’s name
  • +
  • Which group the key belongs to.
  • +
  • Change (regenerate) the key. Metabase will replace the existing API key with a new key. You won’t be able to recover the old key.
  • +
+ +

Deleting API keys

+ +

You won’t be able to recover a deleted API key. You’ll have to create a new key.

+ +

To delete an API Key:

+ +
    +
  1. Click on the gear icon in the upper right.
  2. +
  3. Select Admin settings.
  4. +
  5. Go to the Settings tab.
  6. +
  7. Click on the Authentication tab on the left menu.
  8. +
  9. Scroll to API Keys and click Manage.
  10. +
  11. Select the key you want to delete and click the trash icon.
  12. +
  13. Metabase will pop up a Delete API Key modal. Click the Delete API Key button.
  14. +
+ +

Metabase will transfer API keys associated with a group that gets deleted to the All users group

+ +

If you have API keys assigned to a group, but then someone deletes that group, the API keys will still work, but Metabase will reassign those keys to the All users group. If you want to change their group, you’ll need to edit the keys manually.

+ +

Example GET requests

+ +

Here are some example GET requests that return the groups in your Metabase. These examples assume you’re running Metabase locally on the default port: 3000.

+ +

curl example

+ +

Replace YOUR_API_KEY with the API key you generated above.

+ +
curl \
+-H 'x-api-key: YOUR_API_KEY' \
+-X GET 'http://localhost:3000/api/permissions/group'
+
+ +

JavaScript example

+ +

Assuming you’ve set your key as an environment variable like so:

+ +
export METABASE_API_KEY="YOUR_API_KEY"
+
+ +

Here’s a basic GET request using fetch to get the list of groups. You can copy the code, save it as file (e.g., as api-test.js), and run the code with node api-test.js.

+ +
// Assuming you've set the key in process with
+// `export METABASE_API_KEY="YOUR_KEY_HERE"`
+const API_KEY = process.env.METABASE_API_KEY;
+
+const init = {
+  headers: {
+    "Content-Type": "application/json",
+    "X-API-KEY": API_KEY,
+  },
+};
+
+const host = "http://127.0.0.1:3000";
+
+async function getGroups() {
+  const response = await fetch(`${host}/api/permissions/group`, init);
+  return response.json();
+}
+
+getGroups().then(groups => console.log("Groups in your Metabase:", groups));
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/authenticating-with-jwt.html b/_site/docs/doc-update-detection/people-and-groups/authenticating-with-jwt.html new file mode 100644 index 000000000..68b16236a --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/authenticating-with-jwt.html @@ -0,0 +1,3158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +JWT-based authentication | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

JWT-based authentication

+ +
+
+ + + + + + + +

JWT-based authentication is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

You can connect Metabase to your identity provider using JSON Web Tokens (JWT) to authenticate people.

+ +

Typical flow for a JWT-based SSO interaction with Metabase

+ +

Assuming your site is localhost serving on port 3000:

+ +
    +
  1. Person attempts to view a question, e.g., http://localhost:3000/question/1-superb-question.
  2. +
  3. If the person isn’t logged in, Metabase redirects them to http://localhost:3000/auth/sso.
  4. +
  5. Retaining the original /question/1-superb-question URI, Metabase redirects the person to the SSO provider (the authentication app).
  6. +
  7. Person logs in using the basic form.
  8. +
  9. In the event of a successful sign-in, your authentication app should issue a GET request to your Metabase endpoint with the token and the “return to” URI: http://localhost:3000/auth/sso?jwt=TOKEN_GOES_HERE&return_to=/question/1-superb-question.
  10. +
  11. Metabase verifies the JSON Web Token, logs the person in, then redirects the person to their original destination, /question/1-superb-question.
  12. +
+ +

Enabling JWT authentication

+ +

Navigate to the Admin>Settings section of the Admin area, then click on the Authentication tab. Click the Configure button in the JWT section of this page, and you’ll see this form:

+ +

JWT form

+ +

Here’s a breakdown of each of the settings:

+ +

JWT Identity Provider URI: This is where Metabase will redirect login requests. That is, it’s where your users go to log in through your identity provider.

+ +

String Used by the JWT Signing Key: The string used to seed the private key used to validate JWT messages. Both Metabase and the authentication app should have the same JWT signing key.

+ +

User attribute configuration (optional)

+ +

These are additional settings you can fill in to pass user attributes to Metabase.

+ +
    +
  • Email attribute: the key to retrieve each JWT user’s email address.
  • +
  • First Name attribute: the key to retrieve each JWT user’s first name.
  • +
  • Last Name attribute: if you guessed that this is the key to retrieve each JWT user’s last name, well then you have been paying attention.
  • +
+ +

You can send additional user attributes to Metabase by adding the attributes as key/value pairs to your JWT. These attributes will be synced on every login.

+ +

Configure group mappings

+ +

You can use your JWT to assign Metabase users to custom groups.

+ +
    +
  1. Add groups to your JWT: groups: ["group_name"].
  2. +
  3. In Metabase, go to the Admin panel and switch to Setting > Authentication tab.
  4. +
  5. Click the Configure button under JWT.
  6. +
  7. Under Group Schema, turn on the toggle Synchronize Group Memberships
  8. +
  9. Click New mapping and add the name of a JWT group.
  10. +
  11. In the row that appears, click the dropdown to pick the Metabase group(s) that this should map to. +Metabase JWT group mappings
  12. +
  13. Repeat this for each of the groups you want to map.
  14. +
+ +

Alternatively, you can define the mappings between JWT and Metabase groups using the environment variable MB_JWT_GROUP_MAPPINGS. It accepts a JSON object where the keys are JWT groups and the values are lists of Metabase groups IDs. For example:

+ +
MB_JWT_GROUP_MAPPINGS='{"extHR":[7], "extSales":[3,4]}'
+
+ +

where extHR, extSales are names of JWT groups and 3,4,7 are IDs of Metabase groups.

+ +

You can find Metabase Group ID in the URL for the group page, like http://your-metabase-url/admin/people/groups/<ID>. “All Users” group has ID 1 and “Administrators” group has ID 2.

+ +

You can also use the environment variable MB_JWT_GROUP_SYNC to turn group sync on or off.

+ +
MB_JWT_GROUP_SYNC=true
+
+ +

Creating Metabase accounts with SSO

+ +
+

Paid plans charge for each additional account.

+
+ +

A new SSO login will automatically create a new Metabase account.

+ +

Metabase accounts created with an external identity provider login don’t have passwords. People who sign up for Metabase using an IdP must continue to use the IdP to log into Metabase.

+ +

Disabling password logins

+ +
+

Avoid locking yourself out of your Metabase! This setting will apply to all Metabase accounts, including your Metabase admin account. We recommend that you keep password authentication enabled. This will safeguard you from getting locked out of Metabase in case of any problems with SSO.

+
+ +

To require people to log in with SSO, disable password authentication from Admin settings > Authentication.

+ +

Password disable

+ +

Note about Azure

+ +

If you’re using Azure, you may need to use Azure AD B2C. Check out their tokens overview.

+ +

Example code using JWT-based authentication

+ +

You can find example code that uses JWT authentication in the SSO examples repository.

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/authenticating-with-saml.html b/_site/docs/doc-update-detection/people-and-groups/authenticating-with-saml.html new file mode 100644 index 000000000..315dd7574 --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/authenticating-with-saml.html @@ -0,0 +1,3345 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SAML-based authentication | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SAML-based authentication

+ +
+
+ + + + + + + +

SAML authentication is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Integrating your SSO with Metabase allows you to:

+ +
    +
  • Provision a Metabase account when someone logs in to Metabase.
  • +
  • Automatically pass user attributes from your SSO to Metabase in order to power data sandboxes.
  • +
  • Let people access Metabase without re-authenticating.
  • +
+ +

Confirm the password for your Metabase admin account

+ +

Before setting up SAML, make sure you know the password for your Metabase admin account. If you encounter any issues during the setup process, you can login via the “Admin backup login” option on the sign-in screen.

+ +

Setting up SAML with your IdP in Metabase

+ +

Once you’ve confirmed the password to your Metabase admin account, head over to the Settings section of the Admin Panel, then click on the Authentication tab. Click the Set up button in the SAML section of the Authentication page, and you’ll see this form:

+ +

SAML form

+ +

The form includes three sections:

+ +
    +
  1. Metabase info that you’ll have to input into your identity provider (IdP).
  2. +
  3. IdP info that you’ll need to tell Metabase about.
  4. +
  5. Signing SSO requests (optional).
  6. +
+ +

SAML guides

+ +

First you’ll need to make sure things are configured correctly with your IdP. Each IdP handles SAML setup differently.

+ +

We’ve written up some guides for the most common providers:

+ + + +

If you don’t see your IdP listed here:

+ +
    +
  • Refer to your IdP’s reference docs on configuring SAML. You’ll be looking for something like this OneLogin SAML guide.
  • +
  • Using the information found on the Metabase SAML form, fill out your IdP’s SAML form.
  • +
  • For more information, see the next section on Generic SAML configuration.
  • +
+ +

User provisioning

+ +

By default, Metabase will create accounts for people who don’t yet have a Metabase account but who are able to log in via SAML SSO.

+ +

If you’ve set up User provisioning with SCIM, you’ll want to turn this setting off so that Metabase doesn’t automatically create a new account for anyone who authenticates successfully, as you may want to use SCIM to determine who can and can’t create an account in Metabase.

+ +

Generic SAML configuration

+ +

The top portion of the SAML form in Metabase has the information you’ll need to fill out your IdP’s SAML form, with buttons to make copying the information easy.

+ +

The names of the fields in the Metabase SAML form won’t always match the names used by your IdP. We’ve provided a description of each field below to help you map information from one place to another.

+ +

URL the IdP should redirect back to

+ +

The redirect URL is the web address that people will be sent to after signing in with your IdP. To redirect people to your Metabase, your redirect URL should be your Metabase Site URL, with /auth/sso at the end.

+ +

For example, if your Metabase Site URL is https://metabase.yourcompany.com, you’ll use

+ +
https://metabase.yourcompany.com/auth/sso
+
+ +

as the redirect URL in your IdP’s SAML form.

+ +

Different IdPs use different names for the redirect URL. Here are some common examples:

+ + + + + + + + + + + + + + + + + + + + + + +
ProviderName
Auth0Application Callback URL
OktaSingle Sign On URL
OneLoginACS (Consumer) URL
+ +

User attributes

+ +

Metabase will automatically log in people who’ve been authenticated by your SAML identity provider. In order to do so, the first assertion returned in the identity provider’s SAML response must contain attributes for each person’s first name, last name, and email.

+ +

Most IdPs already include these assertions by default, but some (such as Okta) must be configured to include them.

+ +

Generally you’ll need to paste these user attributes (first name, last name, and email) into fields labelled “Name”, “Attributes” or “Parameters”.

+ +
+

If you allow people to edit their email addresses: make sure to update the corresponding account emails in Metabase. Keeping email addresses in sync will protect people from losing access to their accounts.

+
+ +

Settings for signing SSO requests (optional)

+ +

These are additional settings you can fill in to sign SSO requests to ensure they don’t get tampered with.

+ +

Enabling SAML authentication in Metabase

+ +

Metabase will now need to know some things about your IdP. Here’s a breakdown of each of the settings:

+ +

SAML identity provider URL

+ +

Metabase will redirect login requests to the Identity Provider URL, where people will go to log in with SSO.

+ +

Different IdPs use different names for the Identity Provider URL. Here are some common examples:

+ + + + + + + + + + + + + + + + + + + + + + +
ProviderName
Auth0Identity Provider Login URL
OktaIdentity Provider Single-Sign On URL
OneLoginSAML 2.0 Endpoint (HTTP)
+ +

SAML identity provider issuer

+ +

The SAML identity provider issuer is a unique identifier for the IdP. You might also see “Issuer” referred to as “Entity ID”. Assertions from the IdP will contain this information, and Metabase will verify that the issuer matches the value you set.

+ +

We recommend that you set this value to make your SAML configuration more secure.

+ + + + + + + + + + + + + + + + + + + + + + +
ProviderName
Auth0Identity Provider Login URL
OktaIdentity Provider Issuer
OneLoginIssuer URL
+ +

SAML identity provider certificate

+ +

The SAML identity provider certificate is an encoded certificate that Metabase will use when connecting to the IdP URI. The certificate will look like a big blob of text that you’ll want to copy and paste carefully — the spacing is important!

+ +

Your IdP might have you download this certificate as a file (usually .cer or .pem), which you’ll then need to open up in a text editor in order to copy the contents to then paste into the box in Metabase.

+ +

Note that your certificate text may include header and footer comments that look like -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----. These comments should be included when pasting your certificate text into Metabase.

+ + + + + + + + + + + + + + + + + + + + + + +
ProviderName
Auth0Signing Certificate
OktaX.509 Certificate
OneLoginX.509 Certificate
+ +

Settings for signing SSO requests (optional)

+ +

To sign request so that they can’t be tampered with, you’ll need to provide additional settings.

+ +

If your IdP encrypts SAML responses, you’ll need to ensure this section is filled out.

+ +
+

If you change any of these settings, either during initial setup or after editing an existing value, you will need to restart Metabase due to the way the keystore file is read.

+
+ +
    +
  • SAML keystore path: the absolute path to the keystore file to use for signing SAML requests.
  • +
  • SAML keystore password: the magic spell that will open the keystore.
  • +
  • SAML keystore alias: the alias for the key that Metabase should use for signing SAML requests.
  • +
+ +

SAML Single logout (SLO)

+ +

Metabase supports single logout (SLO) for SAML.

+ +

The endpoint for SLO: /auth/sso/handle_slo

+ +

So if your Metabase is served at metabase.example.com the logout service POST binding URL would be:

+ +
https://metabase.example.com/auth/sso/handle_slo
+
+ +

Synchronizing group membership with your IdP

+ +

This setting allows you to assign users to Metabase groups based on an attribute of your users in your IdP. This setting may not correlate to group functionality provided by your IdP; you may need to create a separate user attribute to set people’s Metabase groups, like metabaseGroups.

+ +

First, you will need to create a SAML user attribute that you will use to indicate which Metabase groups the person should be a part of. This created user attribute can be a XML string or a list of XML strings. Different IdPs have different ways of handling this, but you will likely need to edit your user profiles or find a way to map a user’s groups to a list of Metabase group names.

+ +

Configuring the group schema in Metabase

+ +

Once you’ve gotten everything set up in your SAML provider, you’ll need to configure the group schema in Metabase.

+ +
    +
  1. Turn on the Synchronize group memberships setting.
  2. +
  3. Click Edit mappings.
  4. +
  5. Click Create a mapping.
  6. +
  7. Enter in the name of one of the groups you entered as your metabaseGroups attribute values, then click the Add button.
  8. +
  9. Click the dropdown that appears under the Groups heading to select the Metabase group(s) that users with this particular metabaseGroups value should be added to.
  10. +
  11. Click Save.
  12. +
  13. After that, type in the name of the user attribute you added in your SAML provider. In this case, we told Okta that the metabaseGroups attribute should be named MetabaseGroupName, so that’s what we’ll enter in the Group Attribute Name field in Metabase.
  14. +
+ +

Group schema

+ +

Creating Metabase accounts with SSO

+ +
+

Paid plans charge for each additional account.

+
+ +

A new SSO login will automatically create a new Metabase account.

+ +

Metabase accounts created with an external identity provider login don’t have passwords. People who sign up for Metabase using an IdP must continue to use the IdP to log into Metabase.

+ +

Disabling password logins

+ +
+

Avoid locking yourself out of your Metabase! Turning off password logins applies to all Metabase accounts, including your Metabase admin account. Before turning off password logins, make sure you can log in to your admin account using SSO.

+
+ +

To require people to log in with SSO, disable password authentication from Admin settings > Authentication. Turn off the Enable Password Authentication toggle.

+ +

Password disable

+ +

New account notification emails

+ +

When people log in to Metabase for the first time via SSO, Metabase will automatically create an account for them, which will trigger an email notification to Metabase administrators. If you don’t want these notifications to be sent, you can toggle them off at the bottom of the Authentication page.

+ +

Example code using SAML

+ +

You can find example code that uses SAML authentication in the SSO examples repository.

+ +

Troubleshooting SAML issues

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/changing-password-complexity.html b/_site/docs/doc-update-detection/people-and-groups/changing-password-complexity.html new file mode 100644 index 000000000..1e7f4c031 --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/changing-password-complexity.html @@ -0,0 +1,3082 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Passwords | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Passwords

+ +

Metabase can allow authentication via email and password.

+ +

Password complexity

+ +

Metabase offers a couple controls for administrators who prefer to increase the password requirements on their user accounts.

+ +
export MB_PASSWORD_COMPLEXITY=strong
+export MB_PASSWORD_LENGTH=10
+
+ +

The settings above can be used independently, so it’s fine to use only one or the other. By default Metabase use complexity = normal and a password length of 6. The following options are available for complexity choice:

+ +
    +
  • weak = no character constraints
  • +
  • normal = at least 1 digit
  • +
  • strong = minimum 8 characters w/ 2 lowercase, 2 uppercase, 1 digit, and 1 special character
  • +
+ +

By default, Metabase also prevents users from setting passwords that are in a list of common passwords (like qwerty123 and +passw0rd). Changing the complexity requirement to weak disables this behavior.

+ +

Disabling password logins

+ +
+
+ + + + + + + +

Disabling password logins is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

On Pro and Enterprise plans, you can require people to log in with SSO by disabling password authentication from Admin settings > Authentication.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/changing-session-expiration.html b/_site/docs/doc-update-detection/people-and-groups/changing-session-expiration.html new file mode 100644 index 000000000..e186d35c3 --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/changing-session-expiration.html @@ -0,0 +1,3097 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Session expiration | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Session expiration

+ +

By default, Metabase sessions are valid for two weeks after a user last authenticated (e.g. by entering their email address/password or via an SSO provider). For example, even if you visit your Metabase instance every day, you’ll still have to log in again every two weeks.

+ +

Session age

+ +

The session age is the maximum time that a person stays logged into Metabase (even if the person closes the browser).

+ +

You can set the environment variable MAX_SESSION_AGE:

+ +
# Change session expiration to 24 hours
+MAX_SESSION_AGE=1440 java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

or set the Java system property:

+ +
java -DMAX_SESSION_AGE=1440 -jar metabase.jar
+
+ +

MAX_SESSION_AGE is in minutes.

+ +

Session timeout

+ +
+
+ + + + + + + +

Session timeout is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

The session timeout is the maximum time that a person can be inactive (for example, if someone leaves Metabase open in a long-forgotten browser tab).

+ +

You can toggle this setting from Admin > Authentication, or set the environment variable MB_SESSION_TIMEOUT.

+ +

Session timeout is null by default. You can use a session timeout to log people out earlier than the max session age.

+ +

Session cookies

+ +

Metabase also supports using session cookies, which mean users will only stay authenticated until they close their browser. This can be enabled on a per-user basis by unchecking the “Remember me” box when logging in. Once the user closes their browser, the next time they visit Metabase they’ll have to log in again. Session expiration still applies, so even if you leave your browser open forever, you’ll still be required to re-authenticate after two weeks or whatever session expiration you’ve configured.

+ +

You can tell Metabase to always use session cookies with the environment variable or Java system property MB_SESSION_COOKIES:

+ +
MB_SESSION_COOKIES=true java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar
+
+ +

Setting this environment variable will override the behavior of the “Remember me” checkbox and enforce the use of session cookies for all users.

+ +

Note that browsers may use “session restoring”, which means they automatically restore their previous session when reopened. In this case, the browser effectively acts as if it was never closed; session cookies will act the same as permanent cookies. For browsers that support this feature, this behavior is usually configurable.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/google-and-ldap.html b/_site/docs/doc-update-detection/people-and-groups/google-and-ldap.html new file mode 100644 index 000000000..ee00d0443 --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/google-and-ldap.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/people-and-groups/google-sign-in.html b/_site/docs/doc-update-detection/people-and-groups/google-sign-in.html new file mode 100644 index 000000000..0606c425e --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/google-sign-in.html @@ -0,0 +1,3115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Google Sign-In | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Google Sign-In

+ +

Enabling Google Sign-In for single sign-on (SSO) lets your team log in with a click instead of using email and password. SSO can also be used to let people create Metabase accounts without asking an admin to add each person manually. You can find SSO options under Settings > Admin settings > Authentication.

+ +

If you’d like to have people authenticate with SAML or JWT, Metabase’s Pro and Enterprise let you do just that.

+ +

Enabling Google Sign-In

+ +

Google Sign-In is a good option for SSO if:

+ +
    +
  • Your team is already using Google Workspace, or
  • +
  • You’d like to use Google’s 2-step or multi-factor authentication (2FA or MFA) to secure your Metabase.
  • +
+ +

Get your Client ID from the Google developer console

+ +

To let your team start signing in with Google, you’ll first need to create an application through Google’s developer console.

+ +

Next, you’ll have to create authorization credentials and get a Google API Client ID:

+ +
    +
  • In the Authorized JavaScript origins section, specify the URI of your Metabase instance.
  • +
  • Leave the Authorized Redirect URIs section blank.
  • +
  • Copy your Client ID, which you’ll paste into Metabase when setting up Google Sign-in.
  • +
+ +

Setting up Google Sign-in in Metabase

+ +

Once you have your Google API Client ID (ending in .apps.googleusercontent.com), visit your Metabase and:

+ +
    +
  1. Click on the settings Gear icon in the upper right.
  2. +
  3. Select Admin settings.
  4. +
  5. In the Settings tab, click on Authentication.
  6. +
  7. On the Sign in with Google card, click Set up.
  8. +
  9. In the Client ID field, paste your Google API Client ID.
  10. +
+ +

Creating Metabase accounts with Google Sign-in

+ +
+

On paid plans, you’re charged for each active account.

+
+ +

If people’s Google account email addresses are from a specific domain, and you want to allow them to sign up on their own, you can enter that domain in the Domain field.

+ +

Once set up, existing Metabase users signed in to a Google account that matches the email they used to set up their Metabase account will be able to sign in with just a click.

+ +

Note that Metabase accounts created with Google Sign-In will not have passwords; they must use Google to sign in to Metabase.

+ +

Multiple domains for Google Sign-in

+ +
+
+ + + + + + + +

Multiple domains for Google Sign-in is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

If you’re on a pro or Enterprise plan, you can specify multiple domains from the same Google Workspace in the Domain field, separated by a comma. For example, mycompany.com,example.com.br,otherdomain.co.uk.

+ +

Syncing user attributes with Google

+ +

User attributes can’t be synced with regular Google Sign-In. To synchronize user attributes, you’ll need to set up Google SAML or JWT instead.

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/images/AdminBar.png b/_site/docs/doc-update-detection/people-and-groups/images/AdminBar.png new file mode 100644 index 000000000..a532a8b90 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/AdminBar.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/JWT-auth-form.png b/_site/docs/doc-update-detection/people-and-groups/images/JWT-auth-form.png new file mode 100644 index 000000000..8819e2a7c Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/JWT-auth-form.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/RemoveUser.png b/_site/docs/doc-update-detection/people-and-groups/images/RemoveUser.png new file mode 100644 index 000000000..079a08ab7 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/RemoveUser.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/auth0callbackurl.png b/_site/docs/doc-update-detection/people-and-groups/images/auth0callbackurl.png new file mode 100644 index 000000000..1f6de8d06 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/auth0callbackurl.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/auth0createapp.png b/_site/docs/doc-update-detection/people-and-groups/images/auth0createapp.png new file mode 100644 index 000000000..3afd0845b Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/auth0createapp.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/auth0regularapp.png b/_site/docs/doc-update-detection/people-and-groups/images/auth0regularapp.png new file mode 100644 index 000000000..4ee101d70 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/auth0regularapp.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/auth0saml2addon.png b/_site/docs/doc-update-detection/people-and-groups/images/auth0saml2addon.png new file mode 100644 index 000000000..4540d2506 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/auth0saml2addon.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/auth0samlmappings.png b/_site/docs/doc-update-detection/people-and-groups/images/auth0samlmappings.png new file mode 100644 index 000000000..2d5833245 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/auth0samlmappings.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/auth0samlusage.png b/_site/docs/doc-update-detection/people-and-groups/images/auth0samlusage.png new file mode 100644 index 000000000..251277dea Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/auth0samlusage.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/groups.png b/_site/docs/doc-update-detection/people-and-groups/images/groups.png new file mode 100644 index 000000000..e3411797a Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/groups.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/jwt-groups.png b/_site/docs/doc-update-detection/people-and-groups/images/jwt-groups.png new file mode 100644 index 000000000..db0f5aeb1 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/jwt-groups.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/ldap-attributes.png b/_site/docs/doc-update-detection/people-and-groups/images/ldap-attributes.png new file mode 100644 index 000000000..c6e366c18 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/ldap-attributes.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/ldap-group-mapping.png b/_site/docs/doc-update-detection/people-and-groups/images/ldap-group-mapping.png new file mode 100644 index 000000000..5ff3a7e14 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/ldap-group-mapping.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/okta-adding-groups.png b/_site/docs/doc-update-detection/people-and-groups/images/okta-adding-groups.png new file mode 100644 index 000000000..114f5d09b Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/okta-adding-groups.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/okta-group-attribute.png b/_site/docs/doc-update-detection/people-and-groups/images/okta-group-attribute.png new file mode 100644 index 000000000..0b0cc32cb Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/okta-group-attribute.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/okta-new-attribute-custom.png b/_site/docs/doc-update-detection/people-and-groups/images/okta-new-attribute-custom.png new file mode 100644 index 000000000..1918b5416 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/okta-new-attribute-custom.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/okta-new-attribute.png b/_site/docs/doc-update-detection/people-and-groups/images/okta-new-attribute.png new file mode 100644 index 000000000..559fa50f3 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/okta-new-attribute.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/password-disable.png b/_site/docs/doc-update-detection/people-and-groups/images/password-disable.png new file mode 100644 index 000000000..b9c3a522b Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/password-disable.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-ad-create.png b/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-ad-create.png new file mode 100644 index 000000000..425e371a9 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-ad-create.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-ad-enterprise-app.png b/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-ad-enterprise-app.png new file mode 100644 index 000000000..07f8e0c47 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-ad-enterprise-app.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-app-saml.png b/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-app-saml.png new file mode 100644 index 000000000..64f49beb0 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-app-saml.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-step-1.png b/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-step-1.png new file mode 100644 index 000000000..038d09f91 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/saml-azure-step-1.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/saml-form.png b/_site/docs/doc-update-detection/people-and-groups/images/saml-form.png new file mode 100644 index 000000000..1a4f835d3 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/saml-form.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/saml-okta-groups.png b/_site/docs/doc-update-detection/people-and-groups/images/saml-okta-groups.png new file mode 100644 index 000000000..d54118b47 Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/saml-okta-groups.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/images/user-provisioning.png b/_site/docs/doc-update-detection/people-and-groups/images/user-provisioning.png new file mode 100644 index 000000000..23e5497cb Binary files /dev/null and b/_site/docs/doc-update-detection/people-and-groups/images/user-provisioning.png differ diff --git a/_site/docs/doc-update-detection/people-and-groups/ldap.html b/_site/docs/doc-update-detection/people-and-groups/ldap.html new file mode 100644 index 000000000..da8ca1a89 --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/ldap.html @@ -0,0 +1,3175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +LDAP | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

LDAP

+ +

Metabase supports authentication with Lightweight Directory Access Protocol (LDAP).

+ +

You can find SSO options under Admin settings > Settings > Authentication.

+ +

Required LDAP attributes

+ +

You need to set up your LDAP directory with these attributes:

+ +
    +
  • email (defaulting to the mail attribute)
  • +
  • first name (defaulting to the givenName attribute)
  • +
  • last name (defaulting to the sn attribute).
  • +
+ +

If your LDAP setup uses other attributes for these, you can edit this under the “Attributes” portion of the form.

+ +

Attributes

+ +

Your LDAP directory must have the email field populated for each entry that will become a Metabase user, otherwise Metabase won’t be able to create the account, nor will that person be able to log in. If either name field is missing, Metabase will use a default of “Unknown,” and the person can change their name in their account settings.

+ +

Enabling LDAP authentication

+ +

In the Admin settings > Settings > Authentication tab, go to the LDAP section and click Set up. Click the toggle at the top of the form to enable LDAP, then fill out the form with the relevant details.

+ +

User provisioning

+ +

When a person logs in via LDAP, Metabase can create a Metabase account for them automatically (if they don’t already have a Metabase account).

+ +

Server settings

+ +
    +
  • LDAP Host. Your server name. E.g., ldap.yourdomain.org
  • +
  • LDAP Port. The Server port, usually 389 or 636 if SSL is used.
  • +
  • LDAP Security settings. Options are None, SSL, or StarTLS.
  • +
  • LDAP admin username. The distinguished name to bind as (if any). This user will be used to look up information about other users.
  • +
  • LDAP admin password.
  • +
+ +

Then save your changes. Metabase will automatically pull the required attributes from your LDAP directory.

+ +

User schema

+ +

The User Schema section on this same page is where you can adjust settings related to where and how Metabase connects to your LDAP server to authenticate users.

+ +

User search base

+ +

The User search base field should be completed with the distinguished name (DN) of the entry in your LDAP server that is the starting point when searching for users.

+ +

For example, let’s say you’re configuring LDAP for your company, WidgetCo, where your base DN is dc=widgetco,dc=com. If entries for employees are all stored within an organizational unit in your LDAP server named People, you’ll want to supply the user search base field with the DN ou=People,dc=widgetco,dc=com. This tells Metabase to begin searching for matching entries at that location within the LDAP server.

+ +

User filter

+ +

You’ll see the following grayed-out default value in the User filter field:

+ +
(&(objectClass=inetOrgPerson)(|(uid={login})(mail={login})))
+
+ +

When a person logs into Metabase, this command confirms that the login they supplied matches either a UID or email field in your LDAP server, and that the matching entry has an objectClass of inetOrgPerson.

+ +

This default command will work for most LDAP servers, since inetOrgPerson is a widely-adopted objectClass. But if your company for example uses a different objectClass to categorize employees, this field is where you can set a different command for how Metabase finds and authenticates an LDAP entry upon a person logging in.

+ +

LDAP group mapping

+ +

Manually assigning people to groups in Metabase after they’ve logged in via SSO can get tedious. Instead, you can take advantage of the groups that already exist in your LDAP directory by enabling group mappings.

+ +

Scroll to Group Schema on the same LDAP settings page, and click the toggle to enable group mapping. Selecting Edit Mapping will bring up a modal where you can create and edit mappings, specifying which LDAP group corresponds to which Metabase group.

+ +

As you can see below, if you have an Accounting group in both your LDAP server and Metabase instance, you’ll just need to supply the Distinguished Name from your LDAP server (in the example, it’s cn=Accounting,ou=Groups,dc=widgetco,dc=com) and select its match from the dropdown of your existing Metabase groups.

+ +

Group Mapping

+ +

Some things to keep in mind regarding group mapping:

+ +
    +
  • The Administrator group works like any other group.
  • +
  • Updates to a person’s group membership based on LDAP mappings are not instantaneous; the changes will take effect only after people log back in.
  • +
  • People are only ever added to or removed from mapped groups; the sync has no effect on groups in your Metabase that don’t have an LDAP mapping.
  • +
+ +

LDAP group membership filter

+ +
+
+ + + + + + + +

LDAP advanced features is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Group membership lookup filter. The placeholders {dn} and {uid} will be replaced by the user’s Distinguished Name and UID, respectively.

+ +

Syncing user attributes with LDAP

+ +
+
+ + + + + + + +

LDAP advanced features is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

You can manage user attributes such as names, emails, and roles from your LDAP directory. When you set up data sandboxing, your LDAP directory will be able to pass these attributes to Metabase.

+ +

Troubleshooting login issues

+ + + +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/managing.html b/_site/docs/doc-update-detection/people-and-groups/managing.html new file mode 100644 index 000000000..e069933cf --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/managing.html @@ -0,0 +1,3314 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +People and groups | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

People and groups

+ +

People can have accounts in Metabase, and those accounts can be members of groups. These groups are used to define permissions. People can be in multiple groups.

+ +
+

This page covers accounts people use to log in to your Metabase(s). These accounts are distinct from Metabase store accounts, which are used to manage paid Metabase plans.

+
+ +

Managing people and groups

+ +

To start managing people and groups:

+ +

Hit Cmd/Ctrl + K to bring up the command palette and search for “People”. Click on the People settings result.

+ +

Or

+ +

Click on the gear icon > Admin settings > People. You’ll see a list of all the people in your organization.

+ +

Admin menu

+ +

Creating an account

+ +

Admins can add people to their Metabase. To add a new person manually, click on the gear icon and select Admin settings. Under the People tab, click Invite someone in the upper right corner. You’ll be prompted to enter their email, and optionally their first and last names–only the email is required.

+ +

Click Create to activate an account. An account becomes active once you click Create, even if the person never signs into the account. The account remains active until you deactivate the account. If you’re on a Pro or Enterprise Metabase plan, all active accounts will count toward your user account total. If one person has more than one account, each account will count toward the total (see how billing works).

+ +

If you’ve already configured Metabase to use email, Metabase will send the person an email inviting them to log into Metabase. If you haven’t yet setup email for your Metabase, Metabase will give you a temporary password that you’ll have to manually send to the person.

+ +

To create accounts with SSO, check out authentication options.

+ +

Editing an account

+ +

You can edit someone’s name and email address by clicking the three dots icon and choosing Edit user.

+ +
+

Be careful: changing an account’s email address will change the address the person will use to log in to Metabase.

+
+ +

Adding a user attribute

+ +
+
+ + + + + + + +

User attributes is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

To add a user attribute manually:

+ +
    +
  1. Go to Admin settings > People.
  2. +
  3. Find the person’s account and click the three dot (…) menu.
  4. +
  5. Click Edit user.
  6. +
  7. Click + Add an attribute.
  8. +
  9. Add the name of the user attribute under “Key”. For example, “Department”.
  10. +
  11. Add the value that applies to the specific person. For example, “Engineering”.
  12. +
  13. Optional: if a group for sandboxed people doesn’t exist, create a group to organize people who will get sandboxed table permissions, such as “Sandboxed people”.
  14. +
  15. Add the person to the group.
  16. +
+ +

You can also sync user attributes from your identity provider via SSO.

+ +

User attributes are required for data sandbox permissions.

+ +

You can also employ user attributes to specify what database role Metabase should use when that person queries a database. Check out impersonation access.

+ +

Deactivating an account

+ +

To deactivate someone’s account, click on the three dots icon on the right of a person’s row and select Deactivate from the dropdown. Deactivating an account will mark it as inactive and prevent the user from logging in - but it won’t delete that person’s saved questions or dashboards.

+ +

If you’re using SSO, you should deactivate the account in Metabase as well as your IdP (that is, deactivation doesn’t get applied from Metabase to your IdP, and vice versa).

+ +

Remove a user

+ +

To reactivate a deactivated account, click the Deactivated radio button at the top of the people list to see the list of deactivated accounts. Click on the icon on the far right to reactivate that account, allowing them to log in to Metabase again.

+ +

Deleting an account

+ +

Metabase doesn’t explicitly support account deletion. Instead, Metabase deactivates accounts so people can’t log in to them, while it preserves any questions, models, dashboards, and other items created by those accounts.

+ +

If you want to delete an account because the account information was set up incorrectly, you can deactivate the old account and create a new one instead.

+ +
    +
  1. Change the name and email associated with the old account.
  2. +
  3. Deactivate the old account.
  4. +
  5. Create a new account with the person’s correct information.
  6. +
+ +

Checking someone’s auth method

+ +

Search for a person and look for an icon beside their name.

+ +
    +
  • If they log in using Google credentials, Metabase displays a Google icon.
  • +
  • If they log in using an email address and password stored in Metabase, no icon is shown.
  • +
+ +

Note that the type of user is set when the account is first created: if you create a user in Metabase, but that person then logs in via Google or some other form of SSO, the latter’s icon will not show up next to their name.

+ +

Resetting someone’s password

+ +

If you’ve already configured your email settings, people can reset their passwords using the “forgot password” link on the login screen. If you haven’t yet configured your email settings, they will see a message telling them to ask an admin to reset their password for them.

+ +

To reset a password for someone, just click the three dots icon next to their account and choose Reset Password. If you haven’t configured your email settings yet, you’ll be given a temporary password that you’ll have to share with that person. Otherwise, they’ll receive a password reset email.

+ +

Resetting the admin password

+ +

If you’re using Metabase Cloud, contact support to reset your admin password.

+ +

If you’re a Metabase admin and have access to the server console, you can get Metabase to send you a password reset token:

+ +
    +
  1. Stop the running Metabase application.
  2. +
  3. Restart Metabase with reset-password email@example.com, where “email@example.com” is the email associated with the admin account: +
    java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar reset-password email@example.com
    +
    +
  4. +
  5. +

    Metabase will print out a random token like this:

    + +
    ...
    +Resetting password for email@example.com...
    +
    +OK [[[1_7db2b600-d538-4aeb-b4f7-0cf5b1970d89]]]
    +
    +
  6. +
  7. Start Metabase normally again (without the reset-password option).
  8. +
  9. Navigate to it in your browser using the path /auth/reset_password/:token, where “:token” is the token that was generated from the step above. The full URL should look something like this: +
    https://metabase.example.com/auth/reset_password/1_7db2b600-d538-4aeb-b4f7-0cf5b1970d89
    +
    +
  10. +
  11. You should now see a page where you can input a new password for the admin account.
  12. +
+ +

Unsubscribe from all subscriptions and alerts

+ +

This action will delete any dashboard subscriptions or alerts the person has created, and remove them as a recipient from any other subscriptions or alerts.

+ +

This action doesn’t affect email distribution lists that are managed outside of Metabase.

+ +

Default user accounts

+ +

Metabase includes default user accounts to handle various tasks. We’re documenting these accounts here so you know they’re legitimate accounts and not someone trying to spy on your Metabase. Some things to know about them:

+ +
    +
  • Customers are not charged for these accounts.
  • +
  • No one can log in to these user accounts.
  • +
  • Metabase excludes these user accounts from the Admin settings > People tab.
  • +
+ +

Anonymous user account

+ +
    +
  • ID: 0
  • +
  • First name: External
  • +
  • Last name: User
  • +
  • Email: null
  • +
+ +

Metabase uses this anonymous user account to identify anonymous views, for example views of a public question or dashboard. This account is a virtual user: the account doesn’t exist in the application database. You’ll see this account show up in usage analytics.

+ +

Metabase internal account

+ +
    +
  • ID: 13371338
  • +
  • First name: Internal
  • +
  • Last name: Metabase
  • +
  • Email: internal@metabase.com
  • +
+ +

Metabase uses this account to load content into Metabase (like the Usage analytics collection). You may see this internal@metabase.com account in the logs.

+ +

Groups

+ +

To determine who has access to what, you’ll need to

+ +
    +
  • Create one or more groups.
  • +
  • Choose which level of access that group has to different databases, collections, and so on.
  • +
  • Then add people to those groups.
  • +
  • (Optional) promote people to group managers.
  • +
+ +

To view and manage your groups, go to the Admin Panel > People tab, and then click on Groups from the side menu.

+ +

Groups

+ +

Special default groups

+ +

Every Metabase has two default groups: Administrators and All Users. These are special groups that can’t be removed.

+ +

Administrators

+ +

To make someone an admin of Metabase, you just need to add them to the Administrators group. Metabase admins can log into the Admin Panel and make changes there, and they always have unrestricted access to all data that you have in your Metabase instance. So be careful who you add to the Administrator group!

+ +

All users

+ +

The All Users group is another special one. Every Metabase user is always a member of this group, though they can also be a member of as many other groups as you want. We recommend using the All Users group as a way to set default access levels for new Metabase users. If you have Google single sign-on enabled, new users who join that way will be automatically added to the All Users group.

+ +

It’s important that your All Users group should never have greater access for an item than a group for which you’re trying to restrict access — otherwise the more permissive setting will win out. See Setting permissions.

+ +

Creating a group

+ +

Go to Admin settings > People > Groups, and click the Add a group button.

+ +

We recommend creating groups that correspond to the teams your company or organization has, such as Human Resources, Engineering, Finance, and so on. By default, newly created groups don’t have access to anything.

+ +

To remove a group, click the X icon to the right of a group in the list to remove it (remember, you can’t remove the special default groups).

+ +

Adding people to groups

+ +

To add people to that group, click into a group and then click Add members.

+ +

To remove someone from that group, click on the X to the right of the group member.

+ +

You can also add or remove people from groups from the People list using the dropdown in the Groups column.

+ +

Group managers

+ +
+
+ + + + + + + +

Group managers is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Group managers can manage other people within their group.

+ +

Group managers can:

+ +
    +
  • Add or remove people from their group (that is, people who already have accounts in your Metabase).
  • +
  • View all people in the Admin settings > People tab.
  • +
  • Promote other people to group manager, or demote them from group manager to member.
  • +
  • Rename their group.
  • +
+ +

Group managers are not admins, so their powers are limited. They cannot create new groups or invite new people to your Metabase.

+ +

Promoting/demoting group managers

+ +

To promote someone to become a group manager:

+ +
    +
  1. At the top right of the screen, click the gear icon > Admin settings > People > Groups.
  2. +
  3. Select the group you want the person to manage. If the person isn’t already in the group, you’ll need to add that person to the group.
  4. +
  5. Find the person you want to promote, hover over their member type, and click the up arrow to promote them to group manager. If you want to demote them, click on the down arrow.
  6. +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/saml-auth0.html b/_site/docs/doc-update-detection/people-and-groups/saml-auth0.html new file mode 100644 index 000000000..9bd48b6bb --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/saml-auth0.html @@ -0,0 +1,3152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SAML with Auth0 | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SAML with Auth0

+ +
+
+ + + + + + + +

SAML authentication is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +
    +
  1. Configure SAML in Auth0 (the identity provider).
  2. +
  3. Configure SAML in Metabase (the service provider).
  4. +
+ +

For more information, check out our guide for authenticating with SAML.

+ +

Working in the Auth0 console

+ +

Create an application

+ +

After you log in to your Auth0 account, navigate to Applications and select Create Application.

+ +

Auth0 Applications Page

+ +

Enter “Metabase” as the application name with type “Regular Web Applications”.

+ +

Auth0 Application Selection

+ +

Now go to Settings tab inside Auth0’s Metabase App and fill in the following values:

+ +
    +
  • Application Login URI: the URL of your Metabase instance.
  • +
  • Allowed Callback URLs: the URL that’s below Configure your identity provider (IdP) in SAML settings inside Metabase (it ends with /auth/sso).
  • +
+ +

Auth0 SAML Settings Page

+ +

Scroll to the bottom of the page and click Save Changes.

+ +

Enable SAML in Auth0

+ +

Next, we need to activate the SAML2 Web App Addon. Scroll back to the top of the settings page and select Addons from the navigation menu.

+ +

In the Addons section, select the SAML 2 Web App to load the settings popup.

+ +

Auth0 Application Addons

+ +

Mapping fields from users in Auth0 to Metabase

+ +

On the top of the Settings section on this page, you need to re-enter the value you included in Allowed Callback URLs in the field named Application Callback URL. Copy and paste the following JSON file in the settings box so that Auth0 can send the correct mappings to Metabase when a user logs in:

+ +
{
+    "mappings": {
+        "email":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
+        "given_name":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
+        "family_name":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
+        "groups":"http://schemas.xmlsoap.org/claims/Group"
+    }
+}
+
+ +

If you need to set additional user properties, you can always return to this step to add additional fields to the mappings object.

+ +

Auth0 SAML Mappings

+ +

Configuring Metabase

+ +

Next, in the Auth0 Addon: SAML2 Web App popup, click on the Usage tab and then configure in Metabase (column on the left) the values that this tab provides (column on the right).

+ +

Auth0 SAML usage

+ + + + + + + + + + + + + + + + + + + + + + +
MetabaseAuth0
SAML Identity Provider URLIdentity Provider Login URL
SAML Identity Provider IssuerIssuer
SAML Identity Provider CertificateOpen the Identity Provider Metadata link and copy the string under the X509Certificate tag
+ +

The “SAML Application Name” value can be left as the default (Metabase).

+ +

Save your settings, then enable SAML in Metabase, and you should be good to go!

+ +

Troubleshooting SAML issues

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/saml-azure.html b/_site/docs/doc-update-detection/people-and-groups/saml-azure.html new file mode 100644 index 000000000..3ca672a03 --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/saml-azure.html @@ -0,0 +1,3130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SAML with Microsoft Entra ID | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SAML with Microsoft Entra ID

+ +
+
+ + + + + + + +

SAML authentication is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Enable SAML in Metabase

+ +

First, follow our guide to enable SAML authentication.

+ +

Add an Enterprise Application in Microsoft Entra ID

+ +

Go to Microsoft Entra admin center and click on Enterprise Applications under Applications from the side bar. Once there, click on + New Application in the bar on the top of the page.

+ +

AZEnterpriseApp

+ +

In the new page click on + Create your own application and a bar will open in the right side of the page. Enter “Metabase” as the name of the application, select Integrate any other application you don't find in the gallery (Non-gallery) as the option and click the Create button on the bottom of the bar.

+ +

AZMetabaseApp

+ +

On the application page, under Manage, select Single Sign-on, then click on the “SAML” button.

+ +

AZAppSAML

+ +

When the “Set up Single Sign-On with SAML” page appears, you’ll see an option for “Basic SAML configuration”. Click on the Edit button to enter the required info.

+ +

AZAzureStep1

+ +

Fill out the following fields as follows and click “Save”:

+ +
    +
  • Identifier (Entity ID): Metabase
  • +
  • Reply URL (Assertion Consumer Service URL): go to your Metabase instance in Settings -> Admin-> Authentication -> SAML and insert the value that your Metabase instance reports in the “Configure your identity provider (IdP)” box.
  • +
+ +

Click on “Save” and then note the following 2 items on step 4:

+ +
    +
  • “Login URL”: this is the value you need to enter in “SAML identity provider URL” in Metabase on the next step
  • +
  • “Microsoft Entra Identifier”: this is the value you need to enter in “SAML identity provider issuer” in Metabase on the next step
  • +
+ +

Download the “Federation Metadata XML” file, which will have the certificate you’ll need in the next step.

+ +

To finish the Microsoft Entra side of the configuration, click on the Users and groups button on the Manage tab and add the users or groups that should have access to Metabase.

+ +

Configure the Enterprise Application with Metabase SSO information

+ +

Log in to Metabase as an administrator and go to Admin -> Settings -> Authentication -> SAML.

+ +

Under “Tell Metabase about your identity provider”, enter the following:

+ +
    +
  • SAML Identity Provider URL: the “Login URL” you got on Step 4 on the Microsoft Entra ID SAML SSO configuration
  • +
  • SAML Identity Provider Certificate: open the “Federation Metadata XML” with a text editor, copy and paste the super long string under the <X509Certificate> tag in the “App Federation Metadata Url”. Make sure you copy and paste the whole string; if you miss any character, the integration won’t work
  • +
  • SAML Application Name: “Metabase”
  • +
  • SAML Identity Provider Issuer: the “Microsoft Entra Identifier” URL you got from the Microsoft Entra ID SAML SSO configuration.
  • +
+ +

Click on Save and Enable below, and you should now be able to log in via Microsoft Entra ID.

+ +

Send group membership to Metabase for group mapping

+ +

If you want to send the user group membership to Metabase, then you need to add a group claim on step 2, “Set up Single Sign-On with SAML” on Azure:

+ +
    +
  1. To the right of “Attributes & Claims”, click on “Edit.”
  2. +
  3. Click “Add a group claim.” +3 On the menu that appears for “Which groups associated with the user should be returned in the claim?”, select “All groups.”
  4. +
  5. Click on Save.
  6. +
  7. Then add the group mapping on the Metabase SAML configuration.
  8. +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/saml-google.html b/_site/docs/doc-update-detection/people-and-groups/saml-google.html new file mode 100644 index 000000000..00c091b7f --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/saml-google.html @@ -0,0 +1,3137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SAML with Google | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SAML with Google

+ +
+
+ + + + + + + +

Google SAML authentication is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +
    +
  1. Set up a custom SAML app in your Google admin console.
  2. +
  3. As you follow Google’s instructions, you’ll need to:
  4. +
+ + + +

See authenticating with SAML for general SAML info.

+ +

Saving Google IdP info for Metabase

+ +

On the Google Identity Provider details page:

+ +
    +
  1. Download the IdP metadata.
  2. +
  3. Copy the SSO URL.
  4. +
  5. Download the certificate.
  6. +
+ +

Filling out the Metabase SAML form

+ +
    +
  1. From your Google IdP metadata, locate the issuer. +
      +
    • The issuer looks like this: https://accounts.google.com/o/saml2/.
    • +
    +
  2. +
  3. Go to your Metabase SAML form (Admin settings > Authentication > SAML).
  4. +
  5. Put the issuer in the Metabase SAML Identity Provider Issuer field.
  6. +
  7. Put the SSO URL in the Metabase SAML Identity Provider URL field.
  8. +
  9. Paste the certificate in the Metabase SAML Identity Provider Certificate field.
  10. +
+ +
    +
  • Make sure to include any header and footer comments (like ---BEGIN CERTIFICATE---).
  • +
+ +

Filling out service provider details

+ +

On the Service provider details page:

+ +
    +
  1. Put the Metabase URL the IdP should redirect to in the Google ACS URL field.
  2. +
  3. Put the Metabase SAML Application Name in the Google Entity ID field. +
      +
    • The SAML Application Name can be anything you like (e.g., “yourcompany-metabase”).
    • +
    +
  4. +
  5. Start URL and Signed response are optional fields.
  6. +
+ +

Setting up attribute mappings

+ +

On the Attribute mappings page, you’ll need to add “First name”, “Last name”, and “Email” as attributes, so that Google can pass them to Metabase during authentication.

+ +

For example, to add the attribute “First name”:

+ +
    +
  1. Click Add another mapping.
  2. +
  3. Under Google Directory attributes, choose Basic information > First name as the attribute field name.
  4. +
  5. Go to your Metabase SAML form, and look for SAML attributes > User’s first name attribute. +
      +
    • The attribute looks like this: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname.
    • +
    +
  6. +
  7. Paste the User’s first name attribute under your Google App attributes.
  8. +
  9. Repeat steps 1-3 for the attributes “Last name” and “Email”.
  10. +
+ +

Troubleshooting SAML issues

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/saml-keycloak.html b/_site/docs/doc-update-detection/people-and-groups/saml-keycloak.html new file mode 100644 index 000000000..22c290c24 --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/saml-keycloak.html @@ -0,0 +1,3168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SAML with Keycloak | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SAML with Keycloak

+ +

Keycloak is an open source platform that can be used as a user directory to save user data while acting as the IdP for single sign-on.

+ +
    +
  1. Set up SAML in Keycloak (the identity provider).
  2. +
  3. Set up SAML in Metabase (the service provider).
  4. +
+ +

For more information, check out our guide for authenticating with SAML.

+ +

Working in the Keycloak console

+ +
    +
  1. Go to the Keycloak admin console and sign in as an administrator.
  2. +
  3. Create a user from Manage > Users. You’ll need to populate the fields with an email, first name, and last name.
  4. +
  5. Once you’ve created at least one user, navigation tabs will appear at the top of the Users page. Go to Credentials to set password for your user. +
      +
    • Turn off the Temporary toggle.
    • +
    • Click Set Password to save your changes.
    • +
    +
  6. +
  7. +

    Create a new SSO client from Manage > Clients > Create

    + +
      +
    • Client ID: Enter metabase in lowercase.
    • +
    • Client type: Select SAML from the dropdown.
    • +
    • Click Next.
    • +
    • Valid Redirect URIs: The URL where you are hosting your Metabase instance followed by a slash (/) and an asterisk (*). For example, if you are hosting Metabase locally at http://localhost:3000, the URL would be http://localhost:3000/*.
    • +
    • Home URL: In your Metabase, go to Admin settings > Authentication > SAML. You’ll find your Home URL in the field URL the IdP should redirect back to.
    • +
    • Click Save.
    • +
    +
  8. +
  9. +

    (Optional, but recommended on test environments) Disable key signing for SSO client. See settings for signing SSO requests.

    + +
      +
    • Click Keys tab.
    • +
    • Client signature required: Off.
    • +
    +
  10. +
  11. Map user attributes from Metabase to SSO client. + +
  12. +
  13. Configure the service provider (Metabase) from Configure > Realm Settings. +
      +
    • From Endpoints, select “SAML 2.0 Identity Provider Metadata”.
    • +
    • An XML file will open in a new tab.
    • +
    • Keep this for reference, we will use it in the next section to configure Metabase.
    • +
    +
  14. +
+ +

Mapping fields from Keycloak to Metabase

+ +
    +
  1. Go to your Metabase Admin settings > Authentication > SAML.
  2. +
  3. From the XML file from Step 7 above: +
      +
    • SAML Identity Provider URL: Insert the URL that appears right after the following string: Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location=
    • +
    • SAML Identity Provider Issuer: Insert the URL that appears right after entityID=.
    • +
    • SAML Identity Provider Certificate: Input the long string that appears after the <X509Certificate> tag. Take care when inserting this string: if any letters or special characters are added or off, the setup won’t work.
    • +
    • SAML Application Name: metabase
    • +
    +
  4. +
  5. Click Save Changes.
  6. +
  7. Check that SAML Authentication is toggled ON at the top of the page.
  8. +
+ +

Mapping attributes from users in Keycloak to Metabase

+ +

Keycloak can import four user attributes by default: name, surname, email and role.

+ +

Let’s say we want email, name, and surname to be passed between the client (Metabase) and the authentication server (Keycloak).

+ +
    +
  1. Select “X500 email”, “X500 givenName” and “X500 surname” from the checkboxes that are on the right side of the console.
  2. +
  3. Click Add Selected.
  4. +
  5. Click Edit beside each attribute and make the following changes: +
      +
    • SAML Attribute Name: the name that Metabase expects to receive.
    • +
    • SAML Attribute NameFormat: select “Basic” from the dropdown menu.
    • +
    +
  6. +
+ +

You can edit the attribute values from your Metabase Admin settings > Authentication > SAML > Attributes.

+ +

Configure group mappings between Keycloak and Metabase

+ +

You can configure Metabase to automatically assign people to Metabase groups based on their Keycloak groups.

+ +

Set up group mapping in Keycloak

+ +

In your Keycloak client:

+ +
    +
  1. Click on Client Scopes tab
  2. +
  3. Click on the metabase-dedicated client scope that has been created already.
  4. +
  5. Click on Add Mapper > “By Configuration.
  6. +
  7. Select Group list.
  8. +
  9. Change the name of the attribute to member_of.
  10. +
  11. Deselect the option to use the “Full group path” (so it’s easier to configure in Metabase later).
  12. +
  13. Click on Save.
  14. +
+ +

Set up group mapping in Metabase

+ +
    +
  1. In Admin settings, go to Authentication > SAML.
  2. +
  3. In SAML settings, toggle on Synchronize Group Memberships
  4. +
  5. +

    For each of the Keycloak groups, set up a new mapping to a Metabase group.

    + +

    Currently, Keycloak groups will show up in Metabase with the slash character (“/”) prepended to the group name. So, for example, a group named sales in Keycloak show up in Metabase as /sales.

    +
  6. +
  7. In Group attribute name, enter member_of (the name for the attribute with the group list in your Keycloack configuration). +

    Troubleshooting SAML issues

    +
  8. +
+ +

For common issues, go to Troubleshooting SAML.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/saml-okta.html b/_site/docs/doc-update-detection/people-and-groups/saml-okta.html new file mode 100644 index 000000000..61f418a54 --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/saml-okta.html @@ -0,0 +1,3325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SAML with Okta | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SAML with Okta

+ +
+
+ + + + + + + +

Okta SAML authentication is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +
    +
  1. Turn on SAML-based SSO in Metabase
  2. +
  3. Set up SAML in Okta.
  4. +
  5. Set up SAML up in Metabase.
  6. +
+ +

You can also optionally configure group mappings to automatically assign Okta users to Metabase groups.

+ +

See authenticating with SAML for general SAML info.

+ +

Turn on SAML-based SSO in Metabase

+ +

In the Admin>Settings section of the Admin area, go to the Authentication tab and click on Set up under SAML.

+ +

You’ll see a SAML configuration form like this:

+ +

SAML form

+ +

You’ll need to use the information in this form to set up SAML in Okta.

+ +

Set up SAML in Okta

+ +

Before configuring SAML authentication in Metabase, you’ll need to create a new SAML app integration in Okta.

+ +

Create an app integration in Okta

+ +

From the Okta Admin console, create a new SAML app integration to use with Metabase.

+ +

Configure Okta SAML settings

+ +

To configure Okta app integration with Metabase, you’ll need to use the information found in Metabase in the Admin panel > Authentication > SAML section.

+ +

General settings

+ + + + + + + + + + + + + + + + + + +
Okta SAMLMetabase SAML
Single sign-on URLURL the IdP should redirect to. This is your Metabase Site URL – it should start with https:// and end with /auth/sso.
Audience URI (SP Entity ID)SAML Application Name (“Metabase” by default)
+ +

Attribute statements

+ +

In the Attribute statements (optional) section of the Okta application SAML setting, create the following attribute statements:

+ +
    +
  • email address
  • +
  • first name (given name)
  • +
  • last name (surname)
  • +
+ +

Even though Okta says these are optional, Metabase requires them. Okta will pass these attributes to Metabase during authentication to automatically log people in to Metabase.

+ + + + + + + + + + + + + + + + + + + + + + +
NameValue
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddressuser.email
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givennameuser.firstName
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surnameuser.lastName
+ +

The names of attribute statement in Okta should match the attribute names in Metabase (names are case sensitive). If you want to use non-default attribute names in you Okta app configuration, you will also need to change the names for the attribute fields in Metabase in Admin panel > Authentication > SAML.

+ +
+

Make sure that people cannot edit their email address attribute. To log people in to your Metabase (or to create a Metabase account on first login), your IdP will pass the email address attribute to Metabase. If a person can change the email address attribute, they’ll potentially be able to access Metabase accounts other than their own.

+
+ +

Example of an Okta assertion

+ +

You can click Preview SAML assertion to view the XML file generated by Okta. It should look something like this:

+ +
<saml2:Assertion
+    xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="id4170618837332381492734749" IssueInstant="2019-03-27T17:56:11.067Z" Version="2.0">
+    <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://www.okta.com/Issuer</saml2:Issuer>
+    <saml2:Subject>
+        <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">userName</saml2:NameID>
+        <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+            <saml2:SubjectConfirmationData NotOnOrAfter="2019-03-27T18:01:11.246Z" Recipient="https://metabase.mycompany.com/auth/sso"/>
+        </saml2:SubjectConfirmation>
+    </saml2:Subject>
+    <saml2:Conditions NotBefore="2019-03-27T17:51:11.246Z" NotOnOrAfter="2019-03-27T18:01:11.246Z">
+        <saml2:AudienceRestriction>
+            <saml2:Audience>my-metabase-app</saml2:Audience>
+        </saml2:AudienceRestriction>
+    </saml2:Conditions>
+    <saml2:AuthnStatement AuthnInstant="2019-03-27T17:56:11.067Z">
+        <saml2:AuthnContext>
+            <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
+        </saml2:AuthnContext>
+    </saml2:AuthnStatement>
+    <saml2:AttributeStatement>
+        <saml2:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+            <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">
+              Cam
+            </saml2:AttributeValue>
+        </saml2:Attribute>
+        <saml2:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+            <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">
+              Saul
+            </saml2:AttributeValue>
+        </saml2:Attribute>
+        <saml2:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+            <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">
+              cam@metabase.com
+            </saml2:AttributeValue>
+        </saml2:Attribute>
+    </saml2:AttributeStatement>
+</saml2:Assertion>
+
+ +

Set up SAML in Metabase

+ +

Once you set up your SAML app in Okta, you’ll need to configure SAML in Metabase. You’ll need some information from Okta:

+ +
    +
  1. In Okta, go to the page for your Metabase app integration.
  2. +
  3. Go to the Sign On tab.
  4. +
  5. Click on View SAML setup instructions.
  6. +
+ +

Use the information from Okta SAML instructions to fill the Metabase SAML form in Admin panel > Authentication > SAML:

+ + + + + + + + + + + + + + + + + + + + + + +
Metabase SAMLOkta SAML
SAML Identity Provider URLIdentity Provider Single Sign-On URL
SAML Identity Provider CertificateX.509 Certificate*
SAML Identity Provider IssuerIdentity Provider Issuer
+ +

*Make sure to include any header and footer comments, like ---BEGIN CERTIFICATE--- and ---END CERTIFICATE---.

+ +

Configure group mappings

+ +

You can configure Metabase to automatically assign people to Metabase groups when they log in. You’ll need to create a SAML attribute statement that will pass the groups information to Metabase, and then configure Metabase to read this attribute and map its contents to Metabase groups.

+ +

You can use either:

+ + + +

Use a user profile attribute to assign groups

+ +

You can create a custom user profile attribute and fill it with the Metabase groups for each user.

+ +
    +
  1. In Okta Profile Editor, create a new User Profile attribute called metabaseGroups, which can be a string or a string array. +New User Profile attribute
  2. +
  3. +

    For each user in Okta, fill the metabaseGroups attribute with their Metabase group(s).

    + +

    Metabase groups attribute

    + +

    We recommend that you use the same names for the groups in Okta as you would use in Metabase.

    + +

    Metabase groups don’t have to correspond to Okta User Groups. If you’d like to use Okta User Groups to set up Metabase Groups, see Map Okta User Groups to Metabase groups.

    + +
    +

    Your Okta account has to have SAML_SUPPORT_ARRAY_ATTRIBUTES enabled, as Metabase expects Okta to pass attributes as an array. If your Okta account is old, you might need to reach out to Okta support to enable SAML_SUPPORT_ARRAY_ATTRIBUTES.

    +
    +
  4. +
  5. +

    In the Okta SAML settings for the Metabase app integration, add a new attribute statement MetabaseGroupName with the value user.metabaseGroups (the profile attribute you just created)

    + +

    New attribute statement referencing the attribute

    +
  6. +
  7. In Metabase SAML settings:
  8. +
+ +
    +
  • Turn on Synchronize Group Memberships.
  • +
  • For each of the groups you added to Okta users, set up a new mapping to a Metabase group.
  • +
  • +

    In Group attribute name, enter MetabaseGroupName (the name of the SAML attribute statement).

    + +

    Metabase group mapping

    +
  • +
+ +

Map Okta User Groups to Metabase groups

+ +
    +
  1. Create Okta User groups corresponding to Metabase groups and assign them to Okta users.
  2. +
  3. +

    In Okta’s SAML Settings for the Metabase app integration, add a new attribute statement MetabaseGroupName, set the type to “Basic”, and the value to:

    + +
    Arrays.flatten(getFilteredGroups({"groupID1", "groupID2"}, "group.name", 100))
    +
    + +

    where the Group IDs in {"groupId1", "groupId2"} are the groups that you would like to map to Metabase groups. You can find the Okta Group ID in the URL of the group’s page: https://your-okta-url.okta.com/admin/group/GROUP_ID.

    + +

    This expression will retrieve the names of Okta User Groups that a user is a part of and return them as an array.

    + +

    New attribute statement for groups

    + +
    +

    Your Okta account has to have SAML_SUPPORT_ARRAY_ATTRIBUTES enabled, as Metabase expects Okta to pass attributes as an array. If your Okta account is old, you might need to reach out to Okta support to enable SAML_SUPPORT_ARRAY_ATTRIBUTES.

    +
    + +

    Next, you’ll need to tell Metabase how to map Okta groups to Metabase groups.

    +
  4. +
  5. In Metabase SAML settings:
  6. +
+ +
    +
  • Turn on Synchronize Group Memberships.
  • +
  • For each of the groups you added to Okta users, set up a new mapping to a Metabase group.
  • +
  • +

    In Group attribute name, enter MetabaseGroupName (the name of the SAML attribute statement).

    + +

    Metabase group mapping

    +
  • +
+ +

Troubleshooting SAML issues

+ +

For common issues, go to Troubleshooting SAML.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/start.html b/_site/docs/doc-update-detection/people-and-groups/start.html new file mode 100644 index 000000000..1b81b1b0d --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/start.html @@ -0,0 +1,3106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +People overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

People overview

+ +

User accounts, groups, and authentication. For permissions, see Permissions overview.

+ +

Editing your account settings

+ +

Edit your profile and password, and view your login history.

+ +

Managing people and groups

+ +

Admin controls for setting up user accounts and organizing them into groups.

+ +

Changing password complexity

+ +

Make people use longer and more complex passwords.

+ +

Changing session expiration

+ +

Tell Metabase how long it should wait before asking people to log in again.

+ +

Authentication

+ +

Metabase offers several options for authentication.

+ +
+

If you need to set up 2-step or multi-factor authentication (2FA or MFA) for your Metabase, consider using one of the SSO options below.

+
+ +

SSO for Metabase Open Source and Starter plans

+ + + +

SSO for Metabase Pro and Enterprise plans

+ +

With Pro and Enterprise plans, you have more options to help orchestrate lots of people and groups.

+ + + +

API keys

+ +

Create keys to authenticate API calls.

+ +

User provisioning

+ +

Metabase supports user provisioning via the SCIM protocol.

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/people-and-groups/user-provisioning.html b/_site/docs/doc-update-detection/people-and-groups/user-provisioning.html new file mode 100644 index 000000000..24bdfba0e --- /dev/null +++ b/_site/docs/doc-update-detection/people-and-groups/user-provisioning.html @@ -0,0 +1,3123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +User provisioning with SCIM | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

User provisioning with SCIM

+ +
+
+ + + + + + + +

User provisioning with SCIM is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Metabase supports user provisioning via the System for Cross-domain Identity Management (SCIM) protocol. In addition to Single Sign-on (SSO), you can set up user provisioning in Metabase with SCIM to:

+ +
    +
  • Decouple authentication from provisioning. Even though anyone could authenticate with SSO, you may only want some people to be able to create an account in Metabase.
  • +
  • Support deprovisioning user accounts. If you deactivate someone from your SSO, SCIM can let Metabase know to deactivate their Metabase account as well.
  • +
+ +
+

For now, Metabase officially supports SCIM for Okta and Microsoft Entra ID. Other SCIM providers may work, but we haven’t tested them. If you’re having issues with another identity provider, please reach out to us.

+
+ +

Setting up user provisioning

+ +

Setting up user provisioning with SCIM in Metabase

+ +

To set up user provisioning. Click on the settings Gear icon in the upper right and navigate to Admin settings > Settings> Authentication.

+ +

Click on the User provisioning tab.

+ +

User provisioning via SCIM

+ +

To set up user provisioning with SCIM, hit the toggle to enable it. Metabase will tell you the SCIM endpoint URL and SCIM token to share with your identity provider.

+ +
+

If you’ve previously set up user provisioning with SAML, Metabase will turn that setting off and use the SCIM setup instead.

+
+ +

SCIM endpoint URL

+ +

The SCIM endpoint is /api/ee/scim/v2. So your URL will looks something like:

+ +
https://metabase.example.com/api/ee/scim/v2
+
+ +

Replacing the hostname with your Metabase’s hostname.

+ +

Share this endpoint URL with your identity provider.

+ +

SCIM token

+ +

Copy the token and save the token somewhere safe. For security, Metabase can’t show you the token again. You can, however, regenerate the token, but you’ll need to let your identity provider know about the new token.

+ +

SCIM with Okta

+ +

Once you’ve enabled SCIM in Metabase and gotten your SCIM endpoint URL and SCIM token, follow the docs for Setting up SCIM in Okta.

+ +

With Okta, Metabase supports user and group provisioning; groups are created and populated in Metabase.

+ +

SCIM with Microsoft Entra ID

+ +

Once you’ve enabled SCIM in Metabase and gotten your SCIM endpoint URL and SCIM token, follow the docs for Setting up SCIM in Microsoft Entra ID.

+ +

With Microsoft Entra ID, Metabase only supports user provisioning (groups aren’t created or populated).

+ +

Notify admins of new users provisioned from SSO

+ +

If you’re not using SCIM to provision user accounts, you can optionally have Metabase send an email to admins whenever someone signs in to Metabase via SSO for the first time (which creates a Metabase account). This setting doesn’t require you to set up SCIM.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/permissions/application.html b/_site/docs/doc-update-detection/permissions/application.html new file mode 100644 index 000000000..d987689c4 --- /dev/null +++ b/_site/docs/doc-update-detection/permissions/application.html @@ -0,0 +1,3098 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Application permissions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Application permissions

+ +
+
+ + + + + + + +

Application permissions is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Application settings are useful for granting groups access to some, but not all, of Metabase’s administrative features.

+ +

To set application permissions, got to the top right of the screen and click on the gear icon > Admin settings > Permissions > Application.

+ +

Settings access

+ +

Settings access defines which groups can view and edit the settings under the Admin > Settings tab. These settings include:

+ + + +

Monitoring access

+ +

Monitoring access sets permissions for the following:

+ + + +

Subscriptions and alerts

+ +

This setting determines who can set up:

+ + + +

People will need to be in groups with either view or edit access to the collection that contains the dashboard or question in order to set up alerts. See Collection permissions.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/permissions/collections.html b/_site/docs/doc-update-detection/permissions/collections.html new file mode 100644 index 000000000..eec04da0f --- /dev/null +++ b/_site/docs/doc-update-detection/permissions/collections.html @@ -0,0 +1,3193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Collection permissions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Collection permissions

+ +

Collection detail

+ +

You can use collections to organize questions, dashboards, models, timelines, and other collections. You can set permissions on those collections to determine which groups of people can view and curate collections’ items.

+ +

Metabase starts out with a default top-level collection which is called Our analytics, which every other collection is saved inside of.

+ +

Collection permission levels

+ +

There are three permission levels for collections:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ActionCurate AccessView AccessNo Access
View items
Edit items’ title and descriptions
Move items
Delete items
Pin items
View events and timelines
Edit events and timelines
+ +

Curate access

+ +

The group can view, edit, move, delete, and pin items saved in this collection, and can save or move new items into it. The group can also create new sub-collections within this collection. The group can also create and edit events and timelines.

+ +

View access

+ +

The group can see all the questions, dashboards, and models in the collection, as well as events and timelines.

+ +

No access

+ +

The group won’t see this collection listed, and they’ll lack access to any of the items saved within it.

+ +

Collection vs data permissions

+ +

Collection permissions only apply to viewing and curating existing questions, models, and dashboards. Changing the query on an existing question, or creating a new question, requires that the group have data permissions for the underlying data.

+ +

There is one, important exception: when a group has their data permission set to Block for a database or table, the group won’t be able to view questions based on that data, even if they have curate access to the collection where those questions are saved.

+ +

Dashboards with questions from multiple collections

+ +

If a dashboard includes questions saved to other collections, the group will need view or curate access to all of those collections in order to view those questions. If not, Metabase will apologize and tell you that you lack permissions to see the cards saved to the other collections.

+ +

Dashboard with questions from multiple collections, where the person is not in a group with access to one of the collections

+ +

In general, it’s easier to manage permissions when keeping all of a dashboard’s questions in the same collection.

+ +

Setting permissions for collections

+ +

You can set permissions on collections by clicking on the lock icon in the top-right of the screen while viewing the collection and clicking on Edit permissions. Only Administrators can edit collection permissions. Each user group can have either View, Curate, or No access to a collection:

+ +

Permissions

+ +

If you want to see the bigger picture of what permissions your user groups have for all your collections, just click the link that says See all collection permissions, which takes you to the Admin Panel. You’ll see a list of your collections down along the left, and clicking on any of those will bring up a list of each group’s permission settings for that collection.

+ +

Collection Permissions

+ +

Just like with data access permissions, collection permissions are additive, meaning that if a user belongs to more than one group, if one of their groups has a more restrictive setting for a collection than another one of their groups, they’ll be given the more permissive setting. This is especially important to remember when dealing with the All Users group: since all users are members of this group, if you give the All Users group Curate access to a collection, then all users will be given Curate access for that collection, even if they also belong to a group with less access than that.

+ +

Permissions and sub-collections

+ +

A group can be given access to a collection located somewhere within one or more sub-collections without having to have access to every collection “above” it. For example, if a group had access to the “Super Secret Collection” that’s saved several layers deep within a “Marketing” collection that the group lacks access to, the “Super Secret Collection” would show up at the top-most level that the group does have access to.

+ +

Deleting collections

+ +

Users with curate permission for a collection can move collections to Trash, see Delete and Restore.

+ +

Pinning items in collections

+ +

Pins

+ +

People in groups with Curate access to a collection can pin items in the collection. Pinning an item in a collection turns the item into a handsome card at the top of the collection.

+ +

To pin an item, select the pin icon next to the item’s name.

+ +

Note that collections themselves can’t be pinned. If you’re running on a Pro or Enterprise plan, admins can designate Official Collections.

+ +

Special collections

+ +

Our analytics

+ +

The “Our analytics” collection and individual personal collections are invincible; they cannot be archived, injured, or slain. They are eternal.

+ +

Usage analytics

+ +

See Usage analytics.

+ +

Personal collections

+ +

Each person has a personal collection where they’re always allowed to save things, even if they don’t have Curate permissions for any other collections.

+ +

Administrators can see and edit the contents of every user’s personal collection (even those belonging to other Administrators) by clicking on the Other users’ personal collections link at the bottom of the sidebar when viewing “Our analytics”.

+ +

A personal collection works just like any other collection except that its permissions are fixed and cannot be changed. If a sub-collection within a personal collection is moved to a different collection, the sub-collection will inherit the permissions of its new parent collection.

+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/permissions/data-sandbox-examples.html b/_site/docs/doc-update-detection/permissions/data-sandbox-examples.html new file mode 100644 index 000000000..cda1f5cf4 --- /dev/null +++ b/_site/docs/doc-update-detection/permissions/data-sandbox-examples.html @@ -0,0 +1,3243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Data sandbox examples | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Data sandbox examples

+ +
+
+ + + + + + + +

Data sandboxes is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Data sandboxes let you:

+ + + +

Setup for all examples below

+ +

The examples below use the Sample database included with Metabase. Here’s the basic setup:

+ +
    +
  1. +

    Block permissions for the All users group: Hit cmd/ctrl + k to bring up the command palette and search for “Permissions”. In the Permissions > Data tab. Click on the All users group. For the Sample database, set the All User’s View data permission to “Blocked”.

    +
  2. +
  3. +

    Create a group called Customers. Hit cmd/ctrl + k and search for the People settings. [Create a group called “Customers”.

    +
  4. +
  5. +

    Create a user account for Cloyd Beer. We’ll create a user account for a random person from the People table in our Sample Database. Let’s go with Cloyd Beer from the Sample database’s People table.

    +
  6. +
  7. +

    Add a user attribute to the account: We’ll add a user attribute to Cloyd’s account. Since we want to be able to filter the data by user ID, we’ll grab Cloyd’s ID from the Sample database’s People table and add the ID as a user attribute: user_id: 2499 (2499 is Mr. Beer’s ID in the Sample database).

    +
  8. +
+ +

User details

+ +
    +
  1. +

    Add Mr. Beer to the Customers group: See adding people to groups.

    +
  2. +
  3. +

    Create a collection that is only viewable by Admins.. Call it “Admin collection”. We’ll use this collection to store SQL questions that we use to sandbox tables in examples 2 and 3. See Collection permissions.

    +
  4. +
+ +

Basic sandbox setup - filtering rows based on user attributes

+ +

In this example, we’ll sandbox our Orders table so that anyone in our Customers group will only be able to see rows in the Orders table where the User ID column matches the person’s user_id attribute.

+ +
    +
  1. +

    Go to the Admin settings > Permissions > data. Click on the “Customers” group.

    +
  2. +
  3. +

    Set View data to Granular. For the Sample Database, set the Customer group’s View data to “Granular”. Setting to “Granular” will allow us to set up permissions on individual tables for the Customer group.

    +
  4. +
  5. +

    Sandbox the Orders and People tables. Here, we’ll set the View data permissions on the Orders and People tables to “Sandboxed”. And since we want people to self-serve their data (by asking questions, creating dashboards, etc.), we’ll also set their Create queries permission to “Query builder only.”

    +
  6. +
+ +

Grant sandboxed access

+ +
    +
  1. Filter by a column for each table. For each table, Metabase will ask us “How do you want to filter this table for users in this group?”. In each case, we’ll keep the default selection: “Filter by a column on this table.” For the Orders table, we’ll filter by the User ID column, which we’ll set equal to the user_id attribute for people in the Customers group.
  2. +
+ +

Sandbox settings

+ +

For the People table, we’ll filter by the ID column, which we’ll set equal to that same user_id attribute.

+ +
    +
  1. Save your changes. Otherwise, all is for naught.
  2. +
+ +

Testing out the basic sandbox

+ +

To test out Mr. Beer’s sandbox, we’ll open up a new incognito/private browser window and log in using Mr. Beer’s account.

+ +
    +
  1. Log in as Cloyd Beer.
  2. +
  3. Click Browse > Databases.
  4. +
  5. Click on the Orders table.
  6. +
  7. Confirm that Metabase displays only the orders that Mr. Beer placed, that is, orders associated with the User ID of 2499.
  8. +
+ +

If Mr. Beer views any charts, dashboards, or even automated X-ray explorations that include the sandboxed Orders data, Metabase will also filter those results to show only the data Mr. Beer is permitted to see. When Mr. Beer uses the query builder to ask new questions, his results will be limited to the sandboxed data.

+ +

Custom sandbox setups

+ +

The second way you can create a sandbox is by using a saved question to define a customized view of a table to display. When someone with sandboxed access to a table queries that table, behind the scenes Metabase will instead use the saved question you created as the source data for their query.

+ +

You can:

+ + + +

Custom example 1: filtering columns

+ +

In this example, we have a table called People that we want to trim down so that Mr. Beer and other Customers can view any row, but only some columns.

+ +

Original People table

+ +
    +
  1. Create a query that limits the columns in the People table. Using the native/SQL editor, we’ll write a query that only returns the columns in that table that we do want our Customers group to see, like this:
  2. +
+ +
  ID,
+  Name,
+  'Created At',
+  State
+FROM
+  People
+
+ +

Here are the results:

+ +

Filtering question

+ +

We’ll call this question “Filtered people table”. Save it to the “Admins collection” you created in the setup (or any collection that only Admins have access to).

+ +
    +
  1. Use a saved question to create a custom view for this table: We’ll go to the Permissions section and grant this group sandboxed access to this table. This time we’ll select the second option, “Use a saved question to create a custom view for this table”, and select the saved question we just created (“Filtered people table”), like so:
  2. +
+ +

Sandbox options

+ +
    +
  1. +

    Save changes, lest our toil matter not.

    +
  2. +
  3. +

    Verify things are working correctly. We can log in as Mr. Beer, and when we go to open up the People table, we should see that Mr. Beer can instead see the results of the filtering question.

    +
  4. +
+ +

When Mr. Beer views a chart that uses data from this sandboxed table, Metabase will also apply the filtering. If the chart uses any columns excluded by the sandboxed table, the chart will NOT load for Mr. Beer.

+ +

Custom example 2: Filtering rows and columns

+ +

If we want to specify which columns and rows people can view, we can sandbox a table based on a SQL question with a variable, and associate that variable with a user attribute. To do that, we’ll give our Customers group a custom view of the Orders table, but only let each person see rows based on their user_id user attribute.

+ +
    +
  1. Create a SQL question with a variable. We’ll create a query that selects only some of the columns from the Orders table, and then add a WHERE clause with a variable that we can associate with Cloyd Beer’s user_id user attribute.
  2. +
+ +

Filtering question

+ +

And here’s the code:

+ +

+SELECT
+  id,
+  created_at,
+  product_id,
+  quantity,
+  total,
+  user_id
+FROM
+  orders
+WHERE
+  user_id = {{user_id}}
+
+
+ +

Save it to the “Admins collection” you created in the setup (or any collection that only Admins have access to).

+ +
    +
  1. Set up the sandbox: Return to the Permissions tab. Select Cloyd Beer’s Customer group, and set the View data access for the Orders table to Sandboxed. Select Use a saved question to create a custom view for this table. Open up the sandboxed access modal and select the second option and select my filtering question, we’ll see an additional section which allows me to map the variable we defined in our question with a user attribute:
  2. +
+ +

Sandboxing options

+ +
    +
  1. +

    Save your changes. Or abandon all hope.

    +
  2. +
  3. +

    Verify the sandbox: Now, when we log in as Mr. Beer and look at the Orders table, Mr. Beer will only see the columns we included in the filtering question, and the rows are filtered as specified by the variable in the question’s WHERE clause:

    +
  4. +
+ +

Results

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/permissions/data-sandboxes.html b/_site/docs/doc-update-detection/permissions/data-sandboxes.html new file mode 100644 index 000000000..9483c68b2 --- /dev/null +++ b/_site/docs/doc-update-detection/permissions/data-sandboxes.html @@ -0,0 +1,3386 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Data sandboxes | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Data sandboxes

+ +
+
+ + + + + + + +

Data sandboxes is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Data sandboxes let you give granular permissions to rows and columns for different groups of people. You can sandbox what data a group can view, as well as what data a group can query with the query builder.

+ +

You can use sandboxes to set up self-service analytics, so that each of your customers only views the rows that match their customer ID. For example, if you have an Accounts table with information about your customers, you can sandbox that table so that each customer only sees the data relevant to them.

+ +

Data sandbox examples

+ +

You can skip the theory and go straight to sandbox examples.

+ +

How sandboxes work

+ +

You can think of a data sandbox as a bundle of permissions that includes:

+ +
    +
  • The filtered version of a table that will replace your original table, everywhere that the original table is used in Metabase.
  • +
  • The group of people who should see the filtered version of the table.
  • +
+ +

You can define up to one data sandbox for each table/group combo in your Metabase. That means you can display different versions of a table for different groups, such as “Sandboxed Accounts for Sales” to your salespeople, and “Sandboxed Accounts for Managers” for sales managers.

+ +

Types of data sandboxes

+ +

Data sandboxes show specific data to each person based on their user attributes. You can:

+ +
    +
  • Restrict rows for specific people with a basic sandbox.
  • +
  • Restrict columns (as well as rows) for specific people with a custom sandbox (also known as an advanced sandbox).
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Basic sandbox (filter by a column in the table)Custom sandbox (use a saved SQL question)
Restrict rows by filtering on a single column
Restrict rows by filtering on multiple columns
Restrict columns
Edit columns
+ +

Basic data sandboxes: filter by a column in the table

+ +

To restrict rows, use a basic sandbox. A basic sandbox displays a filtered version of a table instead of the original table to a group. The filter works by setting a column in the table to a specific user attribute value.

+ +

For example, you can create a basic sandbox to filter the Accounts table for a group so that:

+ +
    +
  • A person with the user attribute value “Basic” will see rows where Plan = "Basic" (rows where the Plan column matches the value “Basic”).
  • +
  • A person with the user attribute value “Premium” will see the rows where Plan = "Premium" (rows where the Plan column matches the value “Premium”).
  • +
+ +

Custom data sandboxes: use a saved question to create a custom view of a table

+ +

To restrict columns as well as rows, use a custom sandbox (also known as an advanced sandbox). A custom sandbox displays the results of a saved SQL question in place of your original table.

+ +

For example, say your original Accounts table includes the columns: ID, Email, Plan, and Created At. If you want to hide the Email column, you can create a “Sandboxed Accounts” SQL question with the columns: ID, Plan, and Created At.

+ +

A custom sandbox will display the “Sandboxed Accounts” question result instead of the original Accounts table, to a specific group, everywhere that Accounts is used in Metabase.

+ +

You can also use a custom sandbox to:

+ + + +

Limitations

+ +

Things that don’t play well in a sandbox.

+ +

Groups with native query permissions (access to the SQL editor) cannot be sandboxed

+ +

You can’t set up query builder and native for sandboxed groups.

+ +

To enforce row-level permissions with the native query editor, check out impersonation.

+ +

SQL questions cannot be sandboxed

+ +

Since Metabase can’t parse SQL queries, the results of SQL questions will always use original tables, not sandboxed tables.

+ +

Use collection permissions to prevent sandboxed groups from viewing saved SQL questions with restricted data.

+ +

Non-SQL databases cannot be sandboxed

+ +

Data sandbox permissions are unavailable for non-SQL databases such as Apache Druid or MongoDB.

+ +

Prerequisites for basic sandboxes

+ +
    +
  • A group of people to be added to the basic sandbox.
  • +
  • User attributes for each person in the group.
  • +
+ +

A basic sandbox displays a filtered table, in place of an original table, to a specific group. How Metabase filters that table depends on the value in each person’s user attribute.

+ +

For example, you can set up a basic sandbox so that:

+ +
    +
  • Someone with the user attribute with key of “plan” and a value of “Basic” will see a version of the Accounts table with a filter for Plan = "Basic" (that is, only the rows where the Plan column matches the value “Basic”).
  • +
  • Someone with a “plan” user attribute set to “Premium” will see a different version of the Accounts table with the filter Plan = "Premium" applied.
  • +
+ +

Choosing user attributes for data sandboxes

+ +

User attributes are required for basic sandboxes, and optional for custom sandboxes. When adding a new user attribute, you’ll set up a key-value pair for each person.

+ +

Metabase uses the user attribute key to look up the user attribute value for a specific person. User attribute keys can be mapped to parameters in Metabase.

+ +

The user attribute value must be an exact, case-sensitive match for the filter value of a sandboxed table. For example, if you’re creating a basic sandbox on the Accounts table with the filter Plan = "Basic", make sure that you enter “Basic” as the user attribute value. If you set the user attribute value to lowercase “basic” (a value which doesn’t exist in the Plan column of the Accounts table), the sandboxed person will get an empty result instead of the sandboxed table.

+ +

Examples of user attributes in play:

+ + + +

Creating a basic sandbox

+ +
    +
  1. Make sure to do the prerequisites for basic sandboxes first.
  2. +
  3. Go to Admin settings > Permissions.
  4. +
  5. Select the database and table that you want to sandbox.
  6. +
  7. Find the group that you want to put in the sandbox.
  8. +
  9. Click on the dropdown under View data for that group.
  10. +
  11. Select “Sandboxed”.
  12. +
  13. Click the dropdown under Column and enter the column to filter the table on, such as “Plan”.
  14. +
  15. Click the dropdown under User attribute and enter the user attribute key, such as “Plan”.
  16. +
+ +
+

If you have saved SQL questions that use sandboxed data, make sure to move all of those questions to admin-only collections. For more info, see Permissions conflicts: saved SQL questions.

+
+ +

You can find a sample basic sandbox setup in the Data sandbox examples.

+ +

Prerequisites for custom sandboxes

+ +
    +
  • A group of people to be added to the advanced data sandbox.
  • +
  • An admin-only collection, with collection permissions set to No access for all groups except Administrators.
  • +
  • A saved SQL question with the rows and columns to be displayed to the people in the custom sandbox, stored in the admin-only collection.
  • +
  • Optional: if you want to restrict rows in a custom sandbox, set up user attributes for each of the people in the group.
  • +
+ +

Creating a SQL question for Metabase to display in an custom sandbox

+ +

In an advanced data sandbox, Metabase will display a saved question in place of an original table to a particular group.

+ +

Use a SQL question to define the exact rows and columns to be included in the sandbox. If you use a query builder (GUI) question, you might accidentally expose extra data, since GUI questions can include data from other saved questions or models.

+ +
+

Make sure to save the SQL question in an admin-only collection (collection permissions set to No access for all groups except Administrators). For more info, see Permissions conflicts: saved SQL questions.

+
+ +

Displaying edited columns in an custom sandbox

+ +

Aside from excluding rows and columns from an custom sandbox, you can also display edited columns (without changing the columns in your database).

+ +

For example, you can create a “Sandboxed Accounts” SQL question that truncates the Email column to display usernames instead of complete email addresses.

+ +

If you edit a column, the schema of the saved SQL question (the question you want to display in the sandbox) must match the schema of the original table. That means the “Sandboxed Accounts” SQL question must return the same number of columns and corresponding data types as the original Accounts table.

+ +

You cannot add a column to a custom sandbox.

+ +

Creating a custom sandbox

+ +
    +
  1. Make sure to do the prerequisites for custom sandboxes first.
  2. +
  3. Go to Admin settings > Permissions.
  4. +
  5. Select the database and table that you want to sandbox.
  6. +
  7. Find the group that you want to put in the sandbox.
  8. +
  9. Click on the dropdown under Data access for that group.
  10. +
  11. Select “Sandboxed”.
  12. +
  13. Select “Use a saved question to create a custom view for this table”.
  14. +
  15. Select your saved question. The question should be written in SQL. If the question contains parameters, those parameters must be required (they cannot be optional).
  16. +
  17. Optional: restrict rows based on people’s user attributes.
  18. +
+ +
+

If you have saved SQL questions that use sandboxed data, make sure to move all of those questions to admin-only collections.

+
+ +

You can find sample custom sandbox setups in the Data sandbox examples.

+ +

Restricting rows in an custom sandbox with user attributes

+ +

You can set up an custom sandbox to restrict different rows for each person depending on their user attributes. For example, you can display the “Sandboxed Accounts” question with the filter Plan = "Basic" for one group, and the filter Plan = "Premium" for another group.

+ +
    +
  1. Make sure you’ve done all the prerequisites for custom sandboxes.
  2. +
  3. Go to the saved SQL question that will be displayed to the people in the custom sandbox.
  4. +
  5. Add a parameterized WHERE clause to your SQL query, such as WHERE plan = {{ plan_variable }} .
  6. +
  7. Save the SQL question.
  8. +
  9. Go to Admin settings > Permissions.
  10. +
  11. Find the group and table for your custom sandbox.
  12. +
  13. Open the dropdown under View data.
  14. +
  15. Click Edit sandboxed access.
  16. +
  17. Scroll down and set Parameter or variable to the name of the parameter in your saved SQL question (such as “Plan Variable”).
  18. +
  19. Set the User attribute to a user attribute key (such as the key “User’s Plan”, not the value “Basic”).
  20. +
  21. Click Save.
  22. +
+ +

For a sample SQL variable and user attribute setup, see the Data sandbox examples.

+ +

How row restriction works in an custom sandbox

+ +

How user attributes, SQL parameters, and custom sandboxes work together to display different rows to different people.

+ +

A standard WHERE clause filters a table by setting a column to a fixed value:

+ +
WHERE column_name = column_value
+
+ +

In step 2 of the row restriction setup above, you’ll add a SQL variable so that the WHERE clause will accept a dynamic value. The SQL variable type must be text, number, or date:

+ +
WHERE plan = {{ plan_variable }}
+
+ +

In steps 9-10 of the row restriction setup above, you’re telling Metabase to map the SQL variable plan_variable to a user attribute key (such as “User’s Plan”). Metabase will use the key to look up the specific user attribute value (such as “Basic”) associated with a person’s Metabase account. When that person logs into Metabase and uses the sandboxed table, they’ll see the query result that is filtered on:

+ +
WHERE plan = "Basic"
+
+ +

Note that the parameters must be required for SQL questions used to create a custom sandbox. E.g., you cannot use an optional parameter; the following won’t work:

+ +
[[WHERE plan = {{ plan_variable }}]]
+
+ +

Learn more about SQL parameters

+ +

Preventing data sandbox permissions conflicts

+ +

Some Metabase permissions can conflict with data sandboxes to give more permissive or more restrictive data access than you intended.

+ +

Say you have an custom sandbox that hides the Email column from the Accounts table (for a particular group).

+ +

The Email column may get exposed to a sandboxed person if:

+ + + +

Multiple data sandbox permissions

+ +

Multiple data sandboxes on the same table can create a permissions conflict. You can add a person to a maximum of one data sandbox per table (via the person’s group).

+ +

For example, if you have:

+ +
    +
  • One sandbox for the group “Basic Accounts” that filters the Accounts table on Plan = "Basic".
  • +
  • Another sandbox for the group “Converted Accounts” that filters the Accounts table on Trial Converted = true.
  • +
+ +

If you put Vincent Accountman in both groups, he’ll be in conflicting sandboxes for the Accounts table, and get an error message whenever he tries to use Accounts in Metabase.

+ +

To resolve data sandbox permissions conflicts:

+ +
    +
  • Remove the person from all but one of the groups.
  • +
  • Set the all but one of the group’s View data access to the datatabase to “Blocked”.
  • +
+ +

Saved SQL questions cannot be sandboxed

+ +

Data sandbox permissions don’t apply to the results of SQL questions. That is, saved SQL questions will always display results from the original table rather than the sandboxed table.

+ +

Say that you have an custom sandbox which hides the Email column from the Accounts table. If a non-sandboxed person creates a SQL question that includes the Email column, anyone with collection permissions to view that SQL question will be able to:

+ +
    +
  • See the Email column in the SQL question results.
  • +
  • Use the SQL question to start a new question that includes the Email column.
  • +
+ +

To prevent the Email column from being exposed via a SQL question:

+ +
    +
  • Put any SQL questions that include the Email column in a separate collection.
  • +
  • Set the collection permissions to No access for sandboxed groups that should not see the Email column.
  • +
+ +

Collection permissions must be used to prevent sandboxed groups from viewing saved SQL questions that reference sandboxed tables. That’s why, when you create an custom sandbox, you have to put the saved SQL question (the one you want to display in the sandbox) in an admin-only collection.

+ +

Public sharing

+ +

Data sandbox permissions don’t apply to public questions or public dashboards. If a non-sandboxed person creates a public link using an original table, the original table will be displayed to anyone who has the public link URL.

+ +

To prevent this from happening, you’ll have to disable public sharing for your Metabase instance.

+ +

Metabase can only create a data sandbox using the group membership or user attributes of people who are logged in. Since public links don’t require logins, Metabase won’t have enough info to create the sandbox.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/permissions/data.html b/_site/docs/doc-update-detection/permissions/data.html new file mode 100644 index 000000000..1767f8e0a --- /dev/null +++ b/_site/docs/doc-update-detection/permissions/data.html @@ -0,0 +1,3402 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Data permissions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Data permissions

+ +

This page covers permissions for databases and tables. If you haven’t already, check out our Permissions overview.

+ +

Setting permissions on a database, schema, or table

+ +

To set data permissions on a database, schema, or table for a group:

+ +
    +
  1. Hit Cmd/Ctrl + K. Search for Permissions and click on the Permissions settings result. Metabase will default to the Data tab.
  2. +
+ +

Or

+ +
    +
  1. +

    Click on the gear icon in the upper right.

    +
  2. +
  3. +

    Select Admin settings.

    +
  4. +
  5. +

    Click on the Permissions tab, which defaults to the Data tab.

    +
  6. +
+ +

You can view permissions either by group or by database.

+ +

Data permission types

+ +

You can set the following types of permissions on a database, schema, or table:

+ + + +
+

If you’re upgrading from a version below Metabase 50, your permission levels may look different, but the data access hasn’t changed. See what’s changed with data permissions and why.

+
+ +

View data permissions

+ +
+
+ + + + + + + +

View data permissions is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

The View data permission determines what data people can see when viewing questions, dashboards, models, and metrics. View data permissions also determine whether a group can view the models and metrics browsers in the sidebar. To browse databases, a group will also need Create queries permissions for the relevant data.

+ +

Permission levels include:

+ + + +

View data permission settings apply to different levels in your database:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
View data permissionDatabaseSchemaTable
Can view
Granular*
Sandboxed
Impersonated
Blocked
+ +

* The “Granular” setting is not itself a type of permission; it just signals that permissions are set at a level below the current level. For example, you can select “Granular” at a schema level to set permissions per table for tables in that schema.

+ +

In the free, open-source version of Metabase, the View data setting defaults to “Can view”. Since the setting’s options aren’t available in the OSS version, Metabase will only display this View data setting in the Pro/Enterprise version.

+ +

For which questions, models, and dashboards a group can view, instead see collection permissions.

+ +

Can view data permission

+ +
+
+ + + + + + + +

Can view data permission is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Setting to Can view means the group can view all the data for the data source, provided they have collection permissions to view questions, models, and dashboards.

+ +

In order to view the data in the Browse databases section, the group would additionally need to be able to Create queries.

+ +

Granular view data permission

+ +
+
+ + + + + + + +

Granular view data permission is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

This option lets you set View data permissions for individual schemas or tables. Available only for databases and schemas. If you select Granular for a database or schema, Metabase will open that data source and ask you to set permissions for each individual schema or table.

+ +

For tables, you have the option to set either Can view or Sandboxed.

+ +

Sandboxed view data permission

+ +
+
+ + + + + + + +

Sandboxed view data permission is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Allows you to set row-level permissions based on user attributes. Can only be configured at the table level.

+ +

See Data sandboxes.

+ +

Impersonated view data permission

+ +
+
+ + + + + + + +

Impersonated view data permission is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

The Impersonated option lets you use a role in your database to specify what data people can view and query. Impersonation can only be set at the database level, as Metabase will defer to the permissions granted to the database role.

+ +

See impersonated view data permissions

+ +

Blocked view data permission

+ +
+
+ + + + + + + +

Blocked view data permission is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Blocked ensures people in a group can’t see the data from this database, schema, or table, regardless of their permissions at the collection level.

+ +

The Blocked view data permission can be set at the database, schema, or table level. Essentially, what Blocked does is make collections permissions insufficient to view a question. For example, even if a question is in a collection that the group has access to, but that question queries a data source that is Blocked for that group, people in that group won’t be able to view that question unless they’re in another group with the data permissions to that data source.

+ +

Setting blocked access for a group ALWAYS prevents the group from viewing questions built with the native query editor that query ANY tables from the same database. So even if you only block a single table in a database, the group won’t be able to view the results of SQL questions that query ANY table in that database. The reason: Metabase doesn’t (yet) parse SQL queries, so it can’t know for sure whether the SQL queries the table you want to block.

+ +

If a person in a Blocked group belongs to another group that has its View data permission set to “Can view”, that more permissive access will take precedence, and they’ll be able to view that question.

+ +

Create queries permissions

+ +

Specifies whether a group can create new questions based on the data source. Creating queries includes the ability to drill-through and filter questions, or anything that involves changing the results. This permission also determines whether a group will get access to the database browser to explore that data source.

+ +

To enable Create queries permissions for a group, that group must be able to view the data source (“Can view” permission.)

+ +

Create query levels include:

+ +

Query builder and native create queries permission

+ +

People can use Metabase’s query builder or its native/SQL editor.

+ +

Query builder only create queries permission

+ +

People can create new questions and drill-through existing questions using Metabase’s query builder.

+ +

Granular

+ +

The granular option lets you define Create queries permissions for each schema and/or table in the database.

+ +

Download results permissions

+ +
+
+ + + + + + + +

Download permissions is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

You can set permissions on whether people in a group can download results (and how many rows) from a data source. Options are:

+ +
    +
  • No (they can’t download results)
  • +
  • Granular (you want to set access for individual tables or schemas)
  • +
  • 10 thousand rows
  • +
  • 1 million rows
  • +
+ +

Manage table metadata permissions

+ +
+
+ + + + + + + +

Data model permissions is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

You can define whether a group can edit table metadata. Options are:

+ +
    +
  • Yes (meaning, they can edit metadata for that data source).
  • +
  • No
  • +
  • Granular (to set permissions specific to each table).
  • +
+ +

Manage database permissions

+ +
+
+ + + + + + + +

Database management permissions is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

The Manage database permission grants access to the settings page for a given database (i.e., the page at Admin settings > Databases > your database).

+ +

On the database settings page, you can:

+ + + +

Note that only admins can delete database connections in your Metabase, so people with Manage database permissions won’t see the Remove database button.

+ +

Revoke access even though “All Users” has greater access

+ +

If you see this modal pop-up, Metabase is telling you that the people in the All Users group (that is, everyone in your Metabase), have a higher level of access to the database, schema, or table that you’re setting permissions on. To limit your current group to your preferred permission level, the All Users group must have a less permissive level of access to the data source in question.

+ +

Upload permissions

+ +

See Upload permissions.

+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/permissions/images/admin-panel-collections.png b/_site/docs/doc-update-detection/permissions/images/admin-panel-collections.png new file mode 100644 index 000000000..87838610f Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/admin-panel-collections.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/advanced-example-1-filtering-question.png b/_site/docs/doc-update-detection/permissions/images/advanced-example-1-filtering-question.png new file mode 100644 index 000000000..16789b02b Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/advanced-example-1-filtering-question.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/advanced-example-1-people-table.png b/_site/docs/doc-update-detection/permissions/images/advanced-example-1-people-table.png new file mode 100644 index 000000000..60dfaf968 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/advanced-example-1-people-table.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/advanced-example-1-sandbox-modal.png b/_site/docs/doc-update-detection/permissions/images/advanced-example-1-sandbox-modal.png new file mode 100644 index 000000000..efc22e7a7 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/advanced-example-1-sandbox-modal.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/advanced-example-2-filtering-question.png b/_site/docs/doc-update-detection/permissions/images/advanced-example-2-filtering-question.png new file mode 100644 index 000000000..2b239a1d7 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/advanced-example-2-filtering-question.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/advanced-example-2-results.png b/_site/docs/doc-update-detection/permissions/images/advanced-example-2-results.png new file mode 100644 index 000000000..e9a700216 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/advanced-example-2-results.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/advanced-example-2-sandboxing-options.png b/_site/docs/doc-update-detection/permissions/images/advanced-example-2-sandboxing-options.png new file mode 100644 index 000000000..2982560a1 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/advanced-example-2-sandboxing-options.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/change-permissions.png b/_site/docs/doc-update-detection/permissions/images/change-permissions.png new file mode 100644 index 000000000..3c9f263ca Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/change-permissions.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/collection-detail.png b/_site/docs/doc-update-detection/permissions/images/collection-detail.png new file mode 100644 index 000000000..bbcda41a5 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/collection-detail.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/collection-permissions.png b/_site/docs/doc-update-detection/permissions/images/collection-permissions.png new file mode 100644 index 000000000..0a8f315d4 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/collection-permissions.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/create-new-folder-modal.png b/_site/docs/doc-update-detection/permissions/images/create-new-folder-modal.png new file mode 100644 index 000000000..3b90cd19d Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/create-new-folder-modal.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/dashboard-no-permissions.png b/_site/docs/doc-update-detection/permissions/images/dashboard-no-permissions.png new file mode 100644 index 000000000..26a8b317f Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/dashboard-no-permissions.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/edit-user-details.png b/_site/docs/doc-update-detection/permissions/images/edit-user-details.png new file mode 100644 index 000000000..43355a76a Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/edit-user-details.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/enterprise-add-snippet.png b/_site/docs/doc-update-detection/permissions/images/enterprise-add-snippet.png new file mode 100644 index 000000000..77a9c8732 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/enterprise-add-snippet.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/grant-sandboxed-access.png b/_site/docs/doc-update-detection/permissions/images/grant-sandboxed-access.png new file mode 100644 index 000000000..0aa0ceb67 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/grant-sandboxed-access.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/pinned-items.png b/_site/docs/doc-update-detection/permissions/images/pinned-items.png new file mode 100644 index 000000000..efd9c4500 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/pinned-items.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/select-user-attribute.png b/_site/docs/doc-update-detection/permissions/images/select-user-attribute.png new file mode 100644 index 000000000..51902cd88 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/select-user-attribute.png differ diff --git a/_site/docs/doc-update-detection/permissions/images/snippet-folder.png b/_site/docs/doc-update-detection/permissions/images/snippet-folder.png new file mode 100644 index 000000000..d8dc63c85 Binary files /dev/null and b/_site/docs/doc-update-detection/permissions/images/snippet-folder.png differ diff --git a/_site/docs/doc-update-detection/permissions/impersonation.html b/_site/docs/doc-update-detection/permissions/impersonation.html new file mode 100644 index 000000000..59e7beffc --- /dev/null +++ b/_site/docs/doc-update-detection/permissions/impersonation.html @@ -0,0 +1,3143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Impersonation access | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Impersonation permissions

+ +
+
+ + + + + + + +

Impersonation access is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +
+

For now, impersonation access is only available for PostgreSQL, Redshift, and Snowflake.

+
+ +
+

If you’re using views in PostgresSQL, the row-level security policies on views will only work on Postgres versions 15 and higher.

+
+ +

This page covers the View data permission level called Impersonation.

+ +

Impersonation access allows admins to “outsource” View data permissions to roles in your database. Admins can associate user attributes with database-defined roles and their privileges. If someone is in a group with their View data permission set to Impersonation, the person will be able to view and query data based on the privileges granted to the role specified by their user attribute.

+ +

Setting up connection impersonation

+ +
+

**For impersonation to work for Redshift databases, the user account Metabase uses to connect to your Redshift database must be a superuser, as Metabase will need to be able to run the SET SESSION AUTHORIZATION command, which can only be run by a database superuser.

+
+ +

For impersonation access to work, you’ll first need to set up roles in your database for Metabase to impersonate, then configure Metabase to impersonate those roles when people view or query data.

+ +

In your database, set up roles

+ +
    +
  1. Create a new role (in Redshift, this would be a new user).
  2. +
  3. Grant that role privileges.
  4. +
+ +

For exactly how to create a new role in your database and grant that role privileges, you’ll need to consult your database’s documentation. We also have some docs on users, roles, and privileges that can help you get started.

+ +

In your Metabase, set up impersonation and specify a user attribute

+ +
    +
  1. +

    Create a new group, or select an existing group.

    +
  2. +
  3. +

    Assign a user attribute to people in that group. You’ll use this user attribute to associate people in that group with a role that you created in your database. For example, if you created a role named sales in your database with access to a subset of tables relevant to the sales team, you would add a user attribute called db_role (or whatever you want to call the attribute) and assign the value sales to the person’s db_role. The value of the attribute (sales in this case) should match the name of the role in your database. Only some databases enforce case sensitivity, so you might want to make sure the attribute’s value and the database’s role match exactly.

    +
  4. +
  5. +

    Apply the impersonation access to that group.. Hit Cmd/Ctrl + K to bring up the command palette. Search for Permissions. Or go to Admin settings > Permissions > Data.

    +
  6. +
  7. +

    Select the database you want to set permissions on.

    +
  8. +
  9. +

    Find the group that you want to associate with the database role you created. Under View data setting for that group, select Impersonation.

    +
  10. +
  11. +

    From the dropdown, select the user attribute that you added that maps to the role you want the group to use when querying the database.

    +
  12. +
  13. +

    Save your changes.

    +
  14. +
+ +

People in a group with impersonation access to data do not necessarily share the same privileges

+ +

Metabase will use whatever role you specify in the user attribute for each person. E.g., if you select the db_role attribute for impersonation, one person’s db_role could be sales, another person’s could be engineering, or whatever other value that maps to a valid role in your database.

+ +

Use impersonation to set up row-level SQL access

+ +

You can use impersonation to give people access to the native/SQL editor, while restricting their access to data based on a specific database role. And not just table-level access, but row-level access—or however you define access for that role in your database. Effectively, you can use impersonation to set up data sandbox-like access to your data, while letting people use the SQL editor to query that data. The difference is that, instead of setting up a data sandbox in Metabase, you need to set up that row-level security via the privileges granted to a role in your database.

+ +

If instead you want to give a group SQL access to some, but not all, of the schemas or tables in that database, you can create an additional role in your database that only includes a subset of those tables—or even specific row-level access—and then use Metabase’s impersonation feature to associate a user attribute with that role. Essentially what Metabase will do is take the user attribute and pass that attribute as a string into a SET ROLE or USE ROLE command for the database before Metabase executes the query.

+ +

Connection impersonation doesn’t apply to people in the Metabase admins group, as their more permissive privileges take precedence.

+ +

For more about how to set this up, check out Use Impersonation to get row-level permissions with both GUI and SQL queries.

+ +

Metabase gives people the most permissive access to data across all of their groups

+ +

So if a person is in two groups with different permissions for the same database:

+ +
    +
  • Red group with impersonated access that limits what they can see.
  • +
  • Blue group with View data set to “Can view” and Create queries set to “Query builder and native”.
  • +
+ +

Blue group’s more permissive access would override the impersonated access.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/permissions/introduction.html b/_site/docs/doc-update-detection/permissions/introduction.html new file mode 100644 index 000000000..3cc4feacb --- /dev/null +++ b/_site/docs/doc-update-detection/permissions/introduction.html @@ -0,0 +1,3118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Permissions introduction | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Permissions introduction

+ +

There are always going to be sensitive bits of information in your data, and thankfully Metabase provides a rich set of tools to ensure that people on your team only see the data they’re supposed to.

+ +

If instead you’re wondering about what data Metabase the company can see, check out our page on data privacy and security.

+ +

Key points regarding permissions

+ +
    +
  • Permissions are granted to groups, not people.
  • +
  • People can be in more than one group.
  • +
  • If a person is in multiple groups, they will have the most permissive access granted to them across all of their groups. For example, if a person is in three groups, and any one of those groups has Curate access to a collection, then that person will have curate access to that collection.
  • +
+ +

What you can set permissions on

+ + + +

Data permissions

+ +

Data permissions allow you to set permissions on database and their schemas and tables.

+ + + +

Collection permissions

+ +

Collection permissions dictate which groups can view/edit items in collections, including:

+ +
    +
  • Questions
  • +
  • Dashboards
  • +
  • Models
  • +
  • Metrics
  • +
  • Events
  • +
  • Timelines
  • +
+ +

Application permissions

+ +

Application permissions (available on Pro and Enterprise plans) dictate access to Metabase application-level features, including:

+ +
    +
  • Settings: The Settings tab in the Admin panel.
  • +
  • Monitoring access: The Tools and Troubleshooting tabs in the Admin panel.
  • +
  • Subscriptions and Alerts. Which groups can create/edit dashboard subscriptions and alerts.
  • +
+ +

Snippet folder permissions

+ +

For plans that include Snippet Folders, you can also set permissions on those folders.

+ +

Changing permissions

+ +

Whenever you change permissions for a group, make sure you:

+ +
    +
  • Save your changes.
  • +
  • Click yes to confirm your choices.
  • +
+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/permissions/no-self-service-deprecation.html b/_site/docs/doc-update-detection/permissions/no-self-service-deprecation.html new file mode 100644 index 000000000..7b151826c --- /dev/null +++ b/_site/docs/doc-update-detection/permissions/no-self-service-deprecation.html @@ -0,0 +1,3273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Migrating from legacy permissions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Migrating from legacy permissions

+ +

In Metabase 50, we overhauled our data permissions system to make it more expressive and easier to reason about. This page explains what changed and why.

+ +

The TL;DR: we split the old Data access setting into two settings: View data and Create Queries. Your data permissions may look different, but the access hasn’t changed.

+ +

How Metabase migrated your permissions

+ +

If you’re migrating from Metabase 50 or earlier, Metabase will (with one exception) automatically update your permissions to the new system. While group permissions will be slightly different (and we hope easier to reason about), your groups will have the same levels of access as before.

+ +

Why we updated our permissions system

+ +

The original Data access permission setting contained five levels of access: unrestricted, impersonated, granular, no self-service, and block. These levels aren’t at the same axis. They combined on one axis, whether you could view data, and on another axis, whether you could query that data. This created a two-dimensional setting:

+ +
    +
  • No self-service. Restricts groups from using the query builder to create or edit questions.
  • +
  • Sandbox and block. Restricts view and query builder access to the underlying data.
  • +
+ +

Mixing two axes (querying + viewing) to a single permissions setting could yield unexpected behavior. For example, by changing access from “Sandboxed” to “No self-service”, an admin might think that they would be restricting that group’s access to data. But in that case, the group could potentially see more data, provided the group also had access to collections with existing models, questions, or dashboards.

+ +

What our overhaul of data permissions accomplishes

+ +
    +
  • Splits view access and query access into two permission dimensions. This splitting allows admins to, for example, sandbox tables with or without access to the query builder (previously it wasn’t possible to configure sandboxing as view only).
  • +
  • Makes permissions easier to reason about. A more restrictive permission never gives more access than a less restrictive one.
  • +
+ +

Migration table from old permissions to new

+ +

This table is just if you’re interested in Metabase archeologically. Metabase handles the migration for you.

+ +

Before, Metabase had Data access and Native query editing. Now, Metabase has View data and Create queries. Here’s how Metabase migrated each pairing to the new system.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data accessNative query editing>View dataCreate queries
UnrestrictedYes>Can viewQuery builder and native code
UnrestrictedNo>Can viewQuery builder
No self-serviceNo>Can viewNo
BlockedNo>BlockedNo
ImpersonatedYes>ImpersonatedQuery builder and native code
ImpersonatedNo>ImpersonatedQuery builder
Unrestricted (granular)No>Can viewQuery builder (granular)
Sandboxed (granular)No>Sandboxed (granular)Query builder (granular)
No self-service (granular)No>Can viewNo (granular)
+ +

The No self-service (deprecated) View access level

+ +

If you see the No self-service (deprecated) permission setting in View data for any group, you should manually change it at some point.

+ +

For any group that has their View data access set to No self-service (deprecated), you’ll need to change the View data permission to one of the new options:

+ + + +

If you take no action, Metabase will change any groups with View data access set to No self-service (deprecated) to Blocked in a future release. We’re defaulting to “Blocked”, the least permissive View data access, to prevent any unintended access to data. But this change to Blocked could cause people to lose access to data they previously had access to.

+ +

Why we couldn’t migrate this setting manually

+ +

In the old permissions system, consider people in multiple groups.

+ +
    +
  • Unrestricted data access meant that blocks, sandboxes, or impersonations from your other groups DO NOT affect you.
  • +
  • No Self Service data access meant that blocks, sandboxes, or impersonations from your other groups DO affect you.
  • +
+ +

Say you have the following groups in the old permissions framework:

+ + + + + + + + + + + + + + + + + + + + + + +
 Group AGroup BGroup CGroup DGroup E
Data AccessUnrestrictedNo self-serviceBlockedSandboxedImpersonated
+ +

If you’re a member of Group A and one of Group C, D, or E, you’ll have full, unrestricted access to the data, with no blocks, sandboxes, or impersonations applied.

+ +

If you’re a member of Group B and one of Group C, D, or E, you’ll have limited access to the data: either blocked, sandboxed, or impersonated.

+ +

We could migrate the permissions like so:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Group AGroup BGroup CGroup DGroup E
View dataCan view?BlockedSandboxedImpersonated
Create queriesQuery Builder onlyNoNoQuery Builder onlyQuery Builder only
+ +

We can’t really make a call on what Group B’s View data should be. If we switch it to Can view, the person won’t be affected by the Blocked, Sandboxed, or Impersonated settings in their other group. If we set it to Blocked, they could lose access to data that you think they should have access to. So we created an interim setting, No self-service (legacy) to manage this (temporarily) awkward transition.

+ +

For some permission setups with groups that have “No self-service” and “Sandboxed” data access, you may need to create a new group to replicate the setup in 50 or higher

+ +

In Metabase 49, the (more permissive) “No self-service” data access couldn’t override the (less permissive) “Sandboxed” access, you could set up Metabase 49 in ways that were difficult to reason about.

+ +

In the new permission system starting in Metabase 50, more permissive settings always override less permissive settings. This consistent behavior makes permissions a lot easier to reason about. One consequence of this improvement, however, is that in order to recreate certain permissions setups when upgrading to Metabase 50, you may need to create an additional group.

+ +

For example, let’s say you have two groups in Metabase 49 under the old data access permission, the All users group and the Foo group.

+ +

Permission setup in 49:

+ +
    +
  • All users group has “No self-service” data access to all of the tables in the Sample Database.
  • +
  • Foo group has “Sandboxed” access to the tables in the Sample Database.
  • +
+ +

This data access setup in 49 would allow people to view questions and dashboards in collections they have access to. People in the Foo group, however, would get a sandboxed view of the items. In this case, the less permissive “Sandboxed” data access in the Foo group overrode the more permissive “No self-service” in the All users group.

+ +

Starting with Metabase 50, however, more permissive settings always override less permissive settings. So in order to keep Foo’s sandboxes in tact, we’d need to make the All users group have a View data permission setting that is less permissive than the “Sandboxed” setting. So we’ll need to set the View data permission for All users to “Blocked.”

+ +

But if you still want everyone else who isn’t in the Foo group to view items in collections they have access to, you’ll need to create an additional group, Bar, that contains everyone except for people in the Foo group, and grant that Bar group “Can view” access to the Sample database. The Bar group’s “Can view” access will override the All Users group’s “Blocked” setting, and they’ll be able to view the questions and dashboards. Meanwhile, Foo group still has its sandboxes. Here’s a summary of the settings for 50 that you’d need:

+ +

Permission setup in 50:

+ +
    +
  • All users group is “Blocked” for all tables in the Sample database.
  • +
  • Foo group has View data permission of “Sandboxed” for all tables in the Sample database.
  • +
  • Create a new group, Bar, that includes everyone in the All users group except for people in the Foo group. Set this Bar group’s View data permission to “Can view” for the Sample database.
  • +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/permissions/notifications.html b/_site/docs/doc-update-detection/permissions/notifications.html new file mode 100644 index 000000000..c69d84347 --- /dev/null +++ b/_site/docs/doc-update-detection/permissions/notifications.html @@ -0,0 +1,3105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Notification permissions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Notification permissions

+ +

Notifications in Metabase include alerts and dashboard subscriptions.

+ +

Who can edit dashboard subscriptions and alerts

+ +

What you can do with alerts and dashboard subscriptions depends on whether you’re in the Administrators group or in a sandboxed group.

+ + + +

All Users group notification permissions

+ +

Everyone’s in the All Users group. Which means that everyone can:

+ +
    +
  • Create alerts and dashboard subscriptions.
  • +
  • Add new recipients to dashboard subscriptions that they created. Non-admins can only add themselves to alerts.
  • +
  • Unsubscribe from any alert or subscription in their Account settings.
  • +
+ +

When a notification creator adds new recipients to an alert or subscription, Metabase will display data to the recipients using the creator’s data permissions and collection permissions.

+ +

Sandboxed accounts notification permissions

+ +

Same as everyone in the All Users group, but with a special case: people in sandboxed groups will only see themselves in the list of recipients when creating an alert or subscription.

+ +

Administrators group notification permissions

+ +

People in the admin group can:

+ +
    +
  • View all subscriptions and alerts.
  • +
  • Add or remove recipients from an existing subscription or alert. Admins can safely add and remove recipients without changing the permissions of the alert or subscription. For example, if an admin adds Anya to a subscription created by Beau, Anya will receive emails with the same data that Beau can see (not what the admin can see).
  • +
  • Delete subscriptions or alerts.
  • +
+ +

What notification recipients can see

+ +

Notification recipients can see whatever the notification creator can see. For example, if:

+ +
    +
  • Beau creates a subscription to a dashboard saved in their personal collection.
  • +
  • Beau adds Anya to the dashboard subscription.
  • +
  • Anya will see the dashboard results in her email, even though she lacks permissions to view that dashboard in Beau’s personal collection.
  • +
+ +

More control over email options

+ +

On Enterprise and Pro plans, Admins can:

+ + + +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/permissions/snippets.html b/_site/docs/doc-update-detection/permissions/snippets.html new file mode 100644 index 000000000..fd03f22fc --- /dev/null +++ b/_site/docs/doc-update-detection/permissions/snippets.html @@ -0,0 +1,3147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Snippet folder permissions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Snippet folder permissions

+ +
+
+ + + + + + + +

Snippet controls is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

This article covers Snippet folders, which allow you to organize and set permissions on Snippets.

+ +

Folder permissions should not be considered a security feature, but instead a feature that helps organize and standardize snippets. Although folders are distinct and separate from Collections, they both serve an organizational function: Collections gather and permission dashboards and questions; folders gather and permission snippets. For more info, see the discussion on permissions below.

+ +

Folders

+ +

Folders work similarly to a file system. You can add snippets to folders, and put folders inside of other folders. You can nest as many folders as your Metabase instance can handle or the laws of physics allow (whichever yields first).

+ +

The Top folder is the snippet sidebar’s default folder. It is the root folder that contains all folders and snippets.

+ +

Creating a new Snippet folder

+ +

You can create a Snippet folder from the Snippets menu in the SQL editor.

+ +

Create new snippet folder

+ +
    +
  1. Click on the Snippets menu icon (the snippet icon looks like a block of text or code with three uneven horizontal lines).
  2. +
  3. Click on the + icon and select New folder.
  4. +
  5. Give your folder a name, and optionally Add a description and/or place the folder in an existing folder (the Folder this should be in option).
  6. +
+ +

Create new folder modal

+ +

Creating a new Snippet

+ +

On some plans, when creating a Snippet, you’ll also see an additional option to add that snippet to an existing folder (the Folder this should be in option).

+ +

Add a snippet enterprise modal

+ +

The default location is the Top folder, which is the root folder for all snippets and folders. You can add a snippet to a folder at any time (or relocate a snippet to another folder, provided you have Edit permission to both folders).

+ +

Note that snippet names must be unique; folders do not affect this requirement.

+ +

Permissions

+ +

Administrators (and only administrators) can set snippet visibility and editability by placing snippets in folders, then granting groups one of three permission levels with respect to those folders. If you’re familiar with collection permissions, the functionality is similar. For more on how collection and folder permissions work together, see how folder permissions work below.

+ +

Changing permissions on a folder

+ +

Administrators can set the permissions on a folder by clicking on the ellipsis () next to a folder, and selecting Change permissions.

+ +

You can additionally change the currently selected folder by mousing over to the top of the Snippets sidebar, clicking on the ellipsis () to the left of the +, and selecting Change permissions. When at the Top folder, selecting the at the top of the sidebar will give Administrators the option to set permissions for all snippets, folders, and sub-folders.

+ +

When changing permissions on a folder that has sub-folders, you have an option to extend those permissions to that folder’s sub-folders by toggling the Also change sub-folders setting.

+ +

Options for folder permissions

+ +

Change permissions

+ +

There are three options for changing snippet folder permissions:

+ +
    +
  • Edit access (green checkmark icon). The default setting. When a folder is created, all users (who have SQL editor permissions for at least one database) can view, edit, and archive or unarchive the folder’s snippets.
  • +
  • View access (yellow eye icon). Users in groups with view access can view snippets in the folder, but not edit or archive/unarchive them. They can, of course, copy snippet code and create new snippets, with no effect on the existing snippets.
  • +
  • Revoke access (red X icon). Users in groups with neither edit nor view permissions to a snippet folder will not see that folder’s snippets in the sidebar, nor will any snippets in that folder appear in typeahead suggestions for those users. Note that if people have access to a question with a snippet they don’t have permission to, they will still be able to get results from that question. See the discussion below on how folder permissions work.
  • +
+ +

Archiving does not affect permissions

+ +

Archiving or unarchiving snippets does not affect a snippet’s permissions. If, for example, only one group, say the Accounting group, has edit permissions on a folder, only people in the Accounting group (and admins) would be able to archive and unarchive snippets in that folder, as archiving and unarchiving is considered editing the snippet.

+ +

How folder permissions work

+ +

As with collection permissions, folder permissions are additive, meaning that the more permissive access overrules less permissive access. See Setting permissions for a more detailed discussion.

+ +

But snippet folder permissions require some more effort to unpack, as permissions for snippet folders must work in conjunction with permissions for data and collections.

+ +

Here’s the basic rule: data is more sensitive than code, so permissions that apply to data will take precedence over permissions that apply to code. Let’s work through an example to illustrate how this works in practice.

+ +

Permissions example

+ +

Consider the following scenario (and here’s a sentence that merits slow reading): a group could have permission to a Collection that contains a question that uses a snippet housed in a folder that the group does not have permissions to. To rephrase: people in that group have permissions to run questions in a collection, but they do not have permission to a folder containing a snippet used in one of the collection’s questions. How will Metabase resolve permissions in this case?

+ +

In three parts:

+ +
    +
  1. People in that group can run the question and get results. They have permission to see that data (the question results), so they should be able to see that data. The group’s permission to the collection takes precedence over permissions to the folder (the snippet code).
  2. +
  3. The snippet would not show up in the Snippet sidebar. However, just because people in that group can run the question without issue, they still don’t have permission to the snippet’s folder, so they wouldn’t be able to see or edit that snippet (or the snippet’s folder) in the Snippet sidebar.
  4. +
  5. People with SQL query access can still run the snippet if they know its name, regardless if they have permissions to the snippet’s folder. They wouldn’t be able to view or edit the snippet, but they could include it in a query if they knew its name, e.g, {{snippet: Example snippet I don't have permissions to but can still use }}.
  6. +
+ +

Because of how snippet folder permissions work, we recommend that you consider snippet folder permissions as an additional tool for snippet organization, not as method of preventing access to the SQL code those snippets contain. Use folder permissions to keep the snippet sidebar tidy by exposing teams to folders relevant to their analytical domain, and restrict editing permissions to key snippets in your organization to keep important SQL code accurate and safe from bugs introduced by unvetted edits.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/permissions/start.html b/_site/docs/doc-update-detection/permissions/start.html new file mode 100644 index 000000000..0a2d876cb --- /dev/null +++ b/_site/docs/doc-update-detection/permissions/start.html @@ -0,0 +1,3071 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Permissions overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Permissions overview

+ +

Metabase has a simple, but powerful permissions system.

+ +

Permissions introduction

+ +

Get a lay of the permissions land.

+ +

Data permissions

+ +

Restricting group access to databases, schemas, and tables.

+ +

Collection permissions

+ +

Granting group access to collections of questions, dashboards, models, and sub-collections.

+ +

Application permissions

+ +

Granting group access to different Metabase features.

+ +

Data sandboxing

+ +

Creating data sandboxes to restrict access to rows and columns in tables.

+ +

Snippet folder permissions

+ +

Organize snippets into folders that require permissions to view.

+ +

Notification permissions

+ +

Notes on how permissions interact with dashboard subscriptions and alerts.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/privacy.html b/_site/docs/doc-update-detection/privacy.html new file mode 100644 index 000000000..c796bf02a --- /dev/null +++ b/_site/docs/doc-update-detection/privacy.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/alerts.html b/_site/docs/doc-update-detection/questions/alerts.html new file mode 100644 index 000000000..8c6bd353b --- /dev/null +++ b/_site/docs/doc-update-detection/questions/alerts.html @@ -0,0 +1,3216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Alerts | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Alerts

+ +

Set up an alert to send the results of questions to people via email or Slack, or to a webhook.

+ +

Alerts are for questions only. If you instead want to get the results of a dashboard sent to you, check out dashboard subscriptions.

+ +

Prerequisite for alerts

+ +

To start using alerts, an administrator will need to have set up at least one of the following notification channels.

+ + + +

Creating an alert

+ +

Get alerts

+ +

To create an alert:

+ +
    +
  1. Save your question.
  2. +
  3. Click on the sharing icon in the top-right of the screen.
  4. +
  5. Select Create an alert.
  6. +
  7. Select what you want to be alerted about. The alert options will depend on the question’s visualization. See types of alerts.
  8. +
  9. Select when you want Metabase to check the results. Metabase can check for results by the minute, hourly, daily, weekly, monthly, or on a custom schedule that you set using the Quartz cron syntax.
  10. +
  11. Select the alert’s destination: email, Slack, or to a webhook.
  12. +
+ +

You’ll also have the option to only send the alert once. To test the alert, you can hit the Send now button. But just make sure that the question returns results. If the question doesn’t return any results, Metabase won’t send the alert.

+ +

Types of alerts

+ + + +

Results alerts

+ +

Metabase can send you an alert on a schedule when one of your questions returns any result. This kind of alert is also particularly useful if you have a question that doesn’t usually return any results, but you want to know when the question does return results.

+ +

For example, you might have a table called Reviews, and you want to know any time a customer leaves a bad review, which you consider to be anything below three stars. To set up an alert for this situation, you’d go and create a raw data question (i.e., a question that returns a list of reviews), and add a filter to only include results with fewer than three stars.

+ +

You probably don’t want to be alerted about all the bad reviews you’ve ever gotten, but just recent ones. So you can add a filter to only include results from yesterday or today, depending on how often you want to check for these bad reviews. At this point, when you check the results of this question, it probably won’t return any results, which is a good thing.

+ +

Save the question, create an alert, and select how often you want Metabase to check this question for results. That’s it!

+ +

Goal line alerts

+ +

Requires a bar, line, or area chart with a goal line.

+ +

Goal line alerts are useful when you’re doing things like tracking daily active users (DAU) and you want to know when you reach a certain number of DAU, or when you’re tracking orders per week and you want to know whenever the number of orders ever goes below a certain threshold.

+ +

To start, you’ll need a line, area, or bar chart displaying a number over time.

+ +

Next, you need to set up a goal line on your chart. Open up the visualization settings by clicking the gear icon in the bottom-left. Then click on the Display tab, and turn on the Show goal setting. Choose a value for your goal (and optionally a label) and click Done.

+ +

You can choose:

+ +
    +
  • Whether you want Metabase to alert you when the time series goes above the goal line or when it goes below the goal line.
  • +
  • Whether you want Metabase to alert you every time the time series crosses a goal line, or only the first time it crosses the goal line.
  • +
  • How often you want Metabase to check to see if the goal line has been crossed.
  • +
+ +

Click Done, and your alert will be all set up!

+ +

If you need to edit or unsubscribe from the alert you set up, just click that same icon. You’ll see the Edit and Unsubscribe buttons. This is also where you’ll see alerts about this question that admins might have added you to.

+ +

Metabase will email you when:

+ +
    +
  • You set up an alert
  • +
  • You’ve been unsubscribed from an alert
  • +
  • One of your alerts has stopped working
  • +
  • You unsubscribed from an alert
  • +
  • An admin added you to an alert
  • +
+ +

Progress bar alerts

+ +

Requires the progress bar visualization.

+ +

If you want to set up an alert when a single number reaches a goal, you can use a progress bar visualization.

+ +
    +
  1. Create a question that returns a single number as its result,
  2. +
  3. Choose the Progress Bar chart type,
  4. +
  5. In Visualization settings, select a goal value
  6. +
  7. Save your question,
  8. +
  9. Create an alert by clicking on the Sharing icon in top right
  10. +
+ +

You’ll see the options for when you want to get alerts about this progress bar:

+ +
    +
  • Whether to alert when the progress bar reaches the goal line or below the goal,
  • +
  • Whether to alert only the first time the progress bar reaches the goal line, or every time
  • +
  • How often you want Metabase to check to see if the goal has been reached.
  • +
+ +

Editing and deleting alerts

+ +

To edit or delete alerts on a question, click on the Sharing icon in the top right corner. What you can edit depends on whether you’re an admin.

+ +

Everyone:

+ +
    +
  • Everyone can edit alerts that they’ve personally set up (but not alerts set up by other people).
  • +
  • Everyone can view and unsubscribe from all alerts they receive by clicking on the gear icon in the upper right and navigating to Account settings > Notifications.
  • +
+ +

Admins:

+ +
    +
  • Admins can edit and delete any alert. This can’t be undone, so be careful!
  • +
  • Admins can add or remove recipients on any alert, even ones that they didn’t create themselves.
  • +
  • Admins can bulk manage alerts per person from the People menu in Admin settings.
  • +
+ +

Avoid changing the name of the alerted channel in Slack

+ +

Once you set up an alert to a Slack channel, avoid changing the name of that channel in Slack. If you rename the channel in Slack, but you want Metabase to continue to send alerts to that renamed channel, you’ll need to update the alert in Metabase to point to the new channel name.

+ +

Alert expiration and special cases

+ +

Some circumstances will automatically change or delete alerts:

+ +
    +
  • You rename the target Slack channel. Well, technically the alert won’t get deleted, but Metabase will no longer have anywhere to send the alerts to. You’ll need to update the alert’s target channel in Metabase to the new channel’s name.
  • +
  • If a goal line is removed from the question powering a “Goal line” alert, the alert will change to a “Results” type alert.
  • +
  • If the question is deleted, Metabase will delete any alerts set up for that question.
  • +
+ +

Alerts will continue to work even if the person who set up the alert no longer has an active account. For example, if an alert with multiple recipients (or to a Slack channel) was set up by someone whose account has since been deactivated, that alert will continue to work (though Metabase will stop sending the alerts to the deactivated account).

+ +

Admins can see all alerts

+ +
+
+ + + + + + + +

Usage analytics is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Admins can view a list of all alerts and dashboard subscriptions that people have set up in your Metabase in the Usage analytics collection. See Usage analytics.

+ +

How permissions work with alerts

+ +

See Notification permissions.

+ +

Sending alerts to private Slack channels

+ +

See Sending alerts and subscriptions to private Slack channels.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/exporting-results.html b/_site/docs/doc-update-detection/questions/exporting-results.html new file mode 100644 index 000000000..b4c91b7d1 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/exporting-results.html @@ -0,0 +1,3137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Exporting results | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Exporting results

+ +

You can export the results of a question or dashboard.

+ +

Exporting results of a question

+ +

To export the results of a questions, click on the Download button in the lower right of a question.

+ +

Exporting results of a question +You can export the results of a question as:

+ +
    +
  • .csv
  • +
  • .xlsx
  • +
  • .json
  • +
  • .png (if a chart)
  • +
+ +

You can choose between downloading the results as:

+ +
    +
  • Formatted: With any formatting changes you’ve applied in Metabase.
  • +
  • Unformatted: Metabase will export the raw results of the question without applying any of the formatting you applied to the columns in the question. For example, if you formatted a floating point number to display only the first two decimal digits in the table results, exporting the unformatted results would include additional decimal digits (if any) found in the raw results.
  • +
+ +

If you don’t see the option to export results, you may not have permissions to download results.

+ +

Exporting pivot tables

+ +

If you’re exporting a pivot table, you’ll have the option to keep the table pivoted. By default, Metabase will export the unpivoted results.

+ +

Export limits

+ +

You can export (download) up to 1 million rows.

+ +

You can change this limit with an environment variable: MB_DOWNLOAD_ROW_LIMIT.

+ +

Cell character limit in Excel exports

+ +

Just something to be aware of: when exporting results to an Excel document (.xlsx), Metabase will limit the numbers of characters per cell to 32,767, which is the character limit enforced by Excel. So if you have a bonkers number of characters in a single cell, Metabase will truncate the number of characters to fit within that limit.

+ + + +

You can also create a public link that people can use to download data in a specific format, as well as raw, unformatted question results.

+ +

Exporting question data via alerts

+ +

You can also export data by setting up an alert.

+ +

Exporting results of a dashboard

+ +

You can export the results of a dashboard and its cards in different ways.

+ + + +

Export dashboard as PDF

+ +

You can export a dashboard as a PDF. Click on the Sharing button, then select Export as PDF.

+ +

Exporting a dashboard as a PDF

+ +

The PDF will only include screenshots of the charts as they are visible on the dashboard.

+ +

Exporting results of a dashboard card

+ +

To export the results of a particular card, hover over the dashboard card, click on the three dot menu (), and select Download results.

+ +

Export results of a dashboard card

+ +

From here you can select:

+ +
    +
  • .csv
  • +
  • .xlsx
  • +
  • .json
  • +
  • .png (if a chart)
  • +
+ +

To export the raw, unformatted results, hold down the option key for Macs, or Alt key for Windows, then click on the download file format.

+ +

If you don’t see this option, you may not have permissions to download results.

+ +

Exporting results of a dashboard via dashboard subscriptions

+ +

You can use dashboard subscriptions to regularly export data from all questions on a dashboard, and include those results as an attachment.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/expressions/cumulativecount.html b/_site/docs/doc-update-detection/questions/expressions/cumulativecount.html new file mode 100644 index 000000000..3931ce7f6 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/expressions/cumulativecount.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/expressions/cumulativesum.html b/_site/docs/doc-update-detection/questions/expressions/cumulativesum.html new file mode 100644 index 000000000..3931ce7f6 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/expressions/cumulativesum.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/images/02-widget.png b/_site/docs/doc-update-detection/questions/images/02-widget.png new file mode 100644 index 000000000..73ea0194f Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/02-widget.png differ diff --git a/_site/docs/doc-update-detection/questions/images/SQL-filter-widget.png b/_site/docs/doc-update-detection/questions/images/SQL-filter-widget.png new file mode 100644 index 000000000..1232072f7 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/SQL-filter-widget.png differ diff --git a/_site/docs/doc-update-detection/questions/images/SQLInterface.png b/_site/docs/doc-update-detection/questions/images/SQLInterface.png new file mode 100644 index 000000000..4aa8972ff Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/SQLInterface.png differ diff --git a/_site/docs/doc-update-detection/questions/images/VisualizeChoices.png b/_site/docs/doc-update-detection/questions/images/VisualizeChoices.png new file mode 100644 index 000000000..059481584 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/VisualizeChoices.png differ diff --git a/_site/docs/doc-update-detection/questions/images/add-comparison.png b/_site/docs/doc-update-detection/questions/images/add-comparison.png new file mode 100644 index 000000000..0af2d9234 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/add-comparison.png differ diff --git a/_site/docs/doc-update-detection/questions/images/after-sql-formatting.png b/_site/docs/doc-update-detection/questions/images/after-sql-formatting.png new file mode 100644 index 000000000..6caab952c Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/after-sql-formatting.png differ diff --git a/_site/docs/doc-update-detection/questions/images/aggregation-expression.png b/_site/docs/doc-update-detection/questions/images/aggregation-expression.png new file mode 100644 index 000000000..925e86e5f Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/aggregation-expression.png differ diff --git a/_site/docs/doc-update-detection/questions/images/area.png b/_site/docs/doc-update-detection/questions/images/area.png new file mode 100644 index 000000000..45f242313 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/area.png differ diff --git a/_site/docs/doc-update-detection/questions/images/auto-format.png b/_site/docs/doc-update-detection/questions/images/auto-format.png new file mode 100644 index 000000000..5deab8067 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/auto-format.png differ diff --git a/_site/docs/doc-update-detection/questions/images/bar.png b/_site/docs/doc-update-detection/questions/images/bar.png new file mode 100644 index 000000000..517e099c2 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/bar.png differ diff --git a/_site/docs/doc-update-detection/questions/images/before-sql-formatting.png b/_site/docs/doc-update-detection/questions/images/before-sql-formatting.png new file mode 100644 index 000000000..4696bb5b5 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/before-sql-formatting.png differ diff --git a/_site/docs/doc-update-detection/questions/images/bin-by-latlong.png b/_site/docs/doc-update-detection/questions/images/bin-by-latlong.png new file mode 100644 index 000000000..89c702e95 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/bin-by-latlong.png differ diff --git a/_site/docs/doc-update-detection/questions/images/build-a-funnel-query.png b/_site/docs/doc-update-detection/questions/images/build-a-funnel-query.png new file mode 100644 index 000000000..4e8914c4c Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/build-a-funnel-query.png differ diff --git a/_site/docs/doc-update-detection/questions/images/bulk-filter-modal.png b/_site/docs/doc-update-detection/questions/images/bulk-filter-modal.png new file mode 100644 index 000000000..c8c059701 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/bulk-filter-modal.png differ diff --git a/_site/docs/doc-update-detection/questions/images/chart-formatting-options.png b/_site/docs/doc-update-detection/questions/images/chart-formatting-options.png new file mode 100644 index 000000000..b74c0b523 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/chart-formatting-options.png differ diff --git a/_site/docs/doc-update-detection/questions/images/column-header-formatting.png b/_site/docs/doc-update-detection/questions/images/column-header-formatting.png new file mode 100644 index 000000000..d96567b3b Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/column-header-formatting.png differ diff --git a/_site/docs/doc-update-detection/questions/images/column-selection.png b/_site/docs/doc-update-detection/questions/images/column-selection.png new file mode 100644 index 000000000..7729242d3 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/column-selection.png differ diff --git a/_site/docs/doc-update-detection/questions/images/combo-chart-data-1.png b/_site/docs/doc-update-detection/questions/images/combo-chart-data-1.png new file mode 100644 index 000000000..59b2cec27 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/combo-chart-data-1.png differ diff --git a/_site/docs/doc-update-detection/questions/images/combo-chart-data-2.png b/_site/docs/doc-update-detection/questions/images/combo-chart-data-2.png new file mode 100644 index 000000000..b6371aad8 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/combo-chart-data-2.png differ diff --git a/_site/docs/doc-update-detection/questions/images/combo-chart.png b/_site/docs/doc-update-detection/questions/images/combo-chart.png new file mode 100644 index 000000000..f3868f1f7 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/combo-chart.png differ diff --git a/_site/docs/doc-update-detection/questions/images/conditional-formatting.png b/_site/docs/doc-update-detection/questions/images/conditional-formatting.png new file mode 100644 index 000000000..58ffeba79 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/conditional-formatting.png differ diff --git a/_site/docs/doc-update-detection/questions/images/count-and-average.png b/_site/docs/doc-update-detection/questions/images/count-and-average.png new file mode 100644 index 000000000..335fde93e Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/count-and-average.png differ diff --git a/_site/docs/doc-update-detection/questions/images/cumulative-date-category.png b/_site/docs/doc-update-detection/questions/images/cumulative-date-category.png new file mode 100644 index 000000000..62f6d5ab8 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/cumulative-date-category.png differ diff --git a/_site/docs/doc-update-detection/questions/images/cumulative-multiple-datetimes.png b/_site/docs/doc-update-detection/questions/images/cumulative-multiple-datetimes.png new file mode 100644 index 000000000..ca2a963b4 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/cumulative-multiple-datetimes.png differ diff --git a/_site/docs/doc-update-detection/questions/images/cumulative-no-datetime-order.png b/_site/docs/doc-update-detection/questions/images/cumulative-no-datetime-order.png new file mode 100644 index 000000000..2165c7968 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/cumulative-no-datetime-order.png differ diff --git a/_site/docs/doc-update-detection/questions/images/cumulative-no-datetime.png b/_site/docs/doc-update-detection/questions/images/cumulative-no-datetime.png new file mode 100644 index 000000000..dc47eac75 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/cumulative-no-datetime.png differ diff --git a/_site/docs/doc-update-detection/questions/images/custom-column.png b/_site/docs/doc-update-detection/questions/images/custom-column.png new file mode 100644 index 000000000..698c975bc Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/custom-column.png differ diff --git a/_site/docs/doc-update-detection/questions/images/custom-expression-editor.png b/_site/docs/doc-update-detection/questions/images/custom-expression-editor.png new file mode 100644 index 000000000..8d808377b Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/custom-expression-editor.png differ diff --git a/_site/docs/doc-update-detection/questions/images/data-picker.png b/_site/docs/doc-update-detection/questions/images/data-picker.png new file mode 100644 index 000000000..72e246f8a Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/data-picker.png differ diff --git a/_site/docs/doc-update-detection/questions/images/detail.png b/_site/docs/doc-update-detection/questions/images/detail.png new file mode 100644 index 000000000..2e5aff237 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/detail.png differ diff --git a/_site/docs/doc-update-detection/questions/images/diff-and-percentage.png b/_site/docs/doc-update-detection/questions/images/diff-and-percentage.png new file mode 100644 index 000000000..3449b835b Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/diff-and-percentage.png differ diff --git a/_site/docs/doc-update-detection/questions/images/download-card-results.png b/_site/docs/doc-update-detection/questions/images/download-card-results.png new file mode 100644 index 000000000..f18be9aec Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/download-card-results.png differ diff --git a/_site/docs/doc-update-detection/questions/images/drill-through-menu.png b/_site/docs/doc-update-detection/questions/images/drill-through-menu.png new file mode 100644 index 000000000..156397325 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/drill-through-menu.png differ diff --git a/_site/docs/doc-update-detection/questions/images/editor.png b/_site/docs/doc-update-detection/questions/images/editor.png new file mode 100644 index 000000000..fa8b1b061 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/editor.png differ diff --git a/_site/docs/doc-update-detection/questions/images/explore-results.png b/_site/docs/doc-update-detection/questions/images/explore-results.png new file mode 100644 index 000000000..4e8601e99 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/explore-results.png differ diff --git a/_site/docs/doc-update-detection/questions/images/export-dashboard-as-pdf.png b/_site/docs/doc-update-detection/questions/images/export-dashboard-as-pdf.png new file mode 100644 index 000000000..af403c3df Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/export-dashboard-as-pdf.png differ diff --git a/_site/docs/doc-update-detection/questions/images/exporting-the-results-of-a-question.png b/_site/docs/doc-update-detection/questions/images/exporting-the-results-of-a-question.png new file mode 100644 index 000000000..627fb656c Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/exporting-the-results-of-a-question.png differ diff --git a/_site/docs/doc-update-detection/questions/images/filter-expression.png b/_site/docs/doc-update-detection/questions/images/filter-expression.png new file mode 100644 index 000000000..fc910e27e Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/filter-expression.png differ diff --git a/_site/docs/doc-update-detection/questions/images/filter-step.png b/_site/docs/doc-update-detection/questions/images/filter-step.png new file mode 100644 index 000000000..af569cf4d Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/filter-step.png differ diff --git a/_site/docs/doc-update-detection/questions/images/function-browser.png b/_site/docs/doc-update-detection/questions/images/function-browser.png new file mode 100644 index 000000000..1257bb174 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/function-browser.png differ diff --git a/_site/docs/doc-update-detection/questions/images/funnel-as-sql.png b/_site/docs/doc-update-detection/questions/images/funnel-as-sql.png new file mode 100644 index 000000000..cbad6d22b Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/funnel-as-sql.png differ diff --git a/_site/docs/doc-update-detection/questions/images/funnel-settings.png b/_site/docs/doc-update-detection/questions/images/funnel-settings.png new file mode 100644 index 000000000..ef9a3c041 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/funnel-settings.png differ diff --git a/_site/docs/doc-update-detection/questions/images/funnel.png b/_site/docs/doc-update-detection/questions/images/funnel.png new file mode 100644 index 000000000..3fff9554f Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/funnel.png differ diff --git a/_site/docs/doc-update-detection/questions/images/gauge-format.png b/_site/docs/doc-update-detection/questions/images/gauge-format.png new file mode 100644 index 000000000..b5eeb3af9 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/gauge-format.png differ diff --git a/_site/docs/doc-update-detection/questions/images/gauge-labeled.png b/_site/docs/doc-update-detection/questions/images/gauge-labeled.png new file mode 100644 index 000000000..52782b5e4 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/gauge-labeled.png differ diff --git a/_site/docs/doc-update-detection/questions/images/gauge.png b/_site/docs/doc-update-detection/questions/images/gauge.png new file mode 100644 index 000000000..ed3c01792 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/gauge.png differ diff --git a/_site/docs/doc-update-detection/questions/images/get-alerts-about-this.png b/_site/docs/doc-update-detection/questions/images/get-alerts-about-this.png new file mode 100644 index 000000000..322de387b Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/get-alerts-about-this.png differ diff --git a/_site/docs/doc-update-detection/questions/images/goal-line.png b/_site/docs/doc-update-detection/questions/images/goal-line.png new file mode 100644 index 000000000..34ac0d8d0 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/goal-line.png differ diff --git a/_site/docs/doc-update-detection/questions/images/grid-map.png b/_site/docs/doc-update-detection/questions/images/grid-map.png new file mode 100644 index 000000000..bad9f3b0e Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/grid-map.png differ diff --git a/_site/docs/doc-update-detection/questions/images/group-by-week-of-year.png b/_site/docs/doc-update-detection/questions/images/group-by-week-of-year.png new file mode 100644 index 000000000..525b22ab8 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/group-by-week-of-year.png differ diff --git a/_site/docs/doc-update-detection/questions/images/highlight_and_save_as_snippet.gif b/_site/docs/doc-update-detection/questions/images/highlight_and_save_as_snippet.gif new file mode 100644 index 000000000..e30aeaf41 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/highlight_and_save_as_snippet.gif differ diff --git a/_site/docs/doc-update-detection/questions/images/histogram-bins.png b/_site/docs/doc-update-detection/questions/images/histogram-bins.png new file mode 100644 index 000000000..bdd9c8b98 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/histogram-bins.png differ diff --git a/_site/docs/doc-update-detection/questions/images/histogram.png b/_site/docs/doc-update-detection/questions/images/histogram.png new file mode 100644 index 000000000..2e246dd0b Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/histogram.png differ diff --git a/_site/docs/doc-update-detection/questions/images/info-sidesheet.png b/_site/docs/doc-update-detection/questions/images/info-sidesheet.png new file mode 100644 index 000000000..580cdf343 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/info-sidesheet.png differ diff --git a/_site/docs/doc-update-detection/questions/images/join-a-b-c.png b/_site/docs/doc-update-detection/questions/images/join-a-b-c.png new file mode 100644 index 000000000..aadfea585 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/join-a-b-c.png differ diff --git a/_site/docs/doc-update-detection/questions/images/join-operator.png b/_site/docs/doc-update-detection/questions/images/join-operator.png new file mode 100644 index 000000000..c70b54b7a Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/join-operator.png differ diff --git a/_site/docs/doc-update-detection/questions/images/join-pick-data.png b/_site/docs/doc-update-detection/questions/images/join-pick-data.png new file mode 100644 index 000000000..a3a27346a Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/join-pick-data.png differ diff --git a/_site/docs/doc-update-detection/questions/images/join-step.png b/_site/docs/doc-update-detection/questions/images/join-step.png new file mode 100644 index 000000000..14e526d5d Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/join-step.png differ diff --git a/_site/docs/doc-update-detection/questions/images/joining-on-multiple-columns.png b/_site/docs/doc-update-detection/questions/images/joining-on-multiple-columns.png new file mode 100644 index 000000000..1881079e7 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/joining-on-multiple-columns.png differ diff --git a/_site/docs/doc-update-detection/questions/images/latlong-binned-result.png b/_site/docs/doc-update-detection/questions/images/latlong-binned-result.png new file mode 100644 index 000000000..5b957401d Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/latlong-binned-result.png differ diff --git a/_site/docs/doc-update-detection/questions/images/legend.png b/_site/docs/doc-update-detection/questions/images/legend.png new file mode 100644 index 000000000..5ddf1b86d Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/legend.png differ diff --git a/_site/docs/doc-update-detection/questions/images/line-options.png b/_site/docs/doc-update-detection/questions/images/line-options.png new file mode 100644 index 000000000..de0eaa640 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/line-options.png differ diff --git a/_site/docs/doc-update-detection/questions/images/map-alternative.png b/_site/docs/doc-update-detection/questions/images/map-alternative.png new file mode 100644 index 000000000..1482ced23 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/map-alternative.png differ diff --git a/_site/docs/doc-update-detection/questions/images/map-tiles.png b/_site/docs/doc-update-detection/questions/images/map-tiles.png new file mode 100644 index 000000000..c3b766df6 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/map-tiles.png differ diff --git a/_site/docs/doc-update-detection/questions/images/map-types.png b/_site/docs/doc-update-detection/questions/images/map-types.png new file mode 100644 index 000000000..0d3f17cd4 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/map-types.png differ diff --git a/_site/docs/doc-update-detection/questions/images/map.png b/_site/docs/doc-update-detection/questions/images/map.png new file mode 100644 index 000000000..bedffed94 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/map.png differ diff --git a/_site/docs/doc-update-detection/questions/images/metrics-in-tooltip.png b/_site/docs/doc-update-detection/questions/images/metrics-in-tooltip.png new file mode 100644 index 000000000..6a2d1b8c7 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/metrics-in-tooltip.png differ diff --git a/_site/docs/doc-update-detection/questions/images/multiple-metrics.png b/_site/docs/doc-update-detection/questions/images/multiple-metrics.png new file mode 100644 index 000000000..8fc3065da Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/multiple-metrics.png differ diff --git a/_site/docs/doc-update-detection/questions/images/multiple-summarize-steps.png b/_site/docs/doc-update-detection/questions/images/multiple-summarize-steps.png new file mode 100644 index 000000000..f9e483c83 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/multiple-summarize-steps.png differ diff --git a/_site/docs/doc-update-detection/questions/images/native-editor.png b/_site/docs/doc-update-detection/questions/images/native-editor.png new file mode 100644 index 000000000..2b8d0552e Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/native-editor.png differ diff --git a/_site/docs/doc-update-detection/questions/images/notebook-editor.png b/_site/docs/doc-update-detection/questions/images/notebook-editor.png new file mode 100644 index 000000000..aa9c23a86 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/notebook-editor.png differ diff --git a/_site/docs/doc-update-detection/questions/images/number.png b/_site/docs/doc-update-detection/questions/images/number.png new file mode 100644 index 000000000..c42ac28d5 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/number.png differ diff --git a/_site/docs/doc-update-detection/questions/images/paginate-table-on-dashboard-card.png b/_site/docs/doc-update-detection/questions/images/paginate-table-on-dashboard-card.png new file mode 100644 index 000000000..c748cf391 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/paginate-table-on-dashboard-card.png differ diff --git a/_site/docs/doc-update-detection/questions/images/pie-other-slice.png b/_site/docs/doc-update-detection/questions/images/pie-other-slice.png new file mode 100644 index 000000000..124523a47 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/pie-other-slice.png differ diff --git a/_site/docs/doc-update-detection/questions/images/pie-sunburst-demo.png b/_site/docs/doc-update-detection/questions/images/pie-sunburst-demo.png new file mode 100644 index 000000000..a0f0c88f8 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/pie-sunburst-demo.png differ diff --git a/_site/docs/doc-update-detection/questions/images/pin-data-shape.png b/_site/docs/doc-update-detection/questions/images/pin-data-shape.png new file mode 100644 index 000000000..f72c67d11 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/pin-data-shape.png differ diff --git a/_site/docs/doc-update-detection/questions/images/pin-map-with-tooltip.png b/_site/docs/doc-update-detection/questions/images/pin-map-with-tooltip.png new file mode 100644 index 000000000..abc35c63d Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/pin-map-with-tooltip.png differ diff --git a/_site/docs/doc-update-detection/questions/images/pivot-table-notebook.png b/_site/docs/doc-update-detection/questions/images/pivot-table-notebook.png new file mode 100644 index 000000000..e29b37a68 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/pivot-table-notebook.png differ diff --git a/_site/docs/doc-update-detection/questions/images/pivot-table-options.png b/_site/docs/doc-update-detection/questions/images/pivot-table-options.png new file mode 100644 index 000000000..187f227d8 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/pivot-table-options.png differ diff --git a/_site/docs/doc-update-detection/questions/images/pivot.png b/_site/docs/doc-update-detection/questions/images/pivot.png new file mode 100644 index 000000000..d1620bf8f Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/pivot.png differ diff --git a/_site/docs/doc-update-detection/questions/images/plain-pie.png b/_site/docs/doc-update-detection/questions/images/plain-pie.png new file mode 100644 index 000000000..cac0cc060 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/plain-pie.png differ diff --git a/_site/docs/doc-update-detection/questions/images/preview-table.png b/_site/docs/doc-update-detection/questions/images/preview-table.png new file mode 100644 index 000000000..d7a63f2a2 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/preview-table.png differ diff --git a/_site/docs/doc-update-detection/questions/images/progress-bar-elements.png b/_site/docs/doc-update-detection/questions/images/progress-bar-elements.png new file mode 100644 index 000000000..80ffc13a4 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/progress-bar-elements.png differ diff --git a/_site/docs/doc-update-detection/questions/images/progress-with-format.png b/_site/docs/doc-update-detection/questions/images/progress-with-format.png new file mode 100644 index 000000000..55497ce33 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/progress-with-format.png differ diff --git a/_site/docs/doc-update-detection/questions/images/progress.png b/_site/docs/doc-update-detection/questions/images/progress.png new file mode 100644 index 000000000..e161f5fda Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/progress.png differ diff --git a/_site/docs/doc-update-detection/questions/images/question.png b/_site/docs/doc-update-detection/questions/images/question.png new file mode 100644 index 000000000..1a5cd8a84 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/question.png differ diff --git a/_site/docs/doc-update-detection/questions/images/read-a-funnel.png b/_site/docs/doc-update-detection/questions/images/read-a-funnel.png new file mode 100644 index 000000000..7a1f4f502 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/read-a-funnel.png differ diff --git a/_site/docs/doc-update-detection/questions/images/region-map-query.png b/_site/docs/doc-update-detection/questions/images/region-map-query.png new file mode 100644 index 000000000..aa686f728 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/region-map-query.png differ diff --git a/_site/docs/doc-update-detection/questions/images/region-maps.png b/_site/docs/doc-update-detection/questions/images/region-maps.png new file mode 100644 index 000000000..78c020807 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/region-maps.png differ diff --git a/_site/docs/doc-update-detection/questions/images/rolling-average.png b/_site/docs/doc-update-detection/questions/images/rolling-average.png new file mode 100644 index 000000000..dddcf6f85 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/rolling-average.png differ diff --git a/_site/docs/doc-update-detection/questions/images/row.png b/_site/docs/doc-update-detection/questions/images/row.png new file mode 100644 index 000000000..94e426df2 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/row.png differ diff --git a/_site/docs/doc-update-detection/questions/images/sankey-data-options.png b/_site/docs/doc-update-detection/questions/images/sankey-data-options.png new file mode 100644 index 000000000..92ba39f00 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/sankey-data-options.png differ diff --git a/_site/docs/doc-update-detection/questions/images/sankey-gray-edges.png b/_site/docs/doc-update-detection/questions/images/sankey-gray-edges.png new file mode 100644 index 000000000..56df08738 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/sankey-gray-edges.png differ diff --git a/_site/docs/doc-update-detection/questions/images/sankey-left-aligned.png b/_site/docs/doc-update-detection/questions/images/sankey-left-aligned.png new file mode 100644 index 000000000..c9b2d2a3a Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/sankey-left-aligned.png differ diff --git a/_site/docs/doc-update-detection/questions/images/sankey-right-aligned.png b/_site/docs/doc-update-detection/questions/images/sankey-right-aligned.png new file mode 100644 index 000000000..5d1bf7fa5 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/sankey-right-aligned.png differ diff --git a/_site/docs/doc-update-detection/questions/images/sankey-summarize-count-source-target.png b/_site/docs/doc-update-detection/questions/images/sankey-summarize-count-source-target.png new file mode 100644 index 000000000..7648a0130 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/sankey-summarize-count-source-target.png differ diff --git a/_site/docs/doc-update-detection/questions/images/scatter.png b/_site/docs/doc-update-detection/questions/images/scatter.png new file mode 100644 index 000000000..91060d975 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/scatter.png differ diff --git a/_site/docs/doc-update-detection/questions/images/search-dropdown.png b/_site/docs/doc-update-detection/questions/images/search-dropdown.png new file mode 100644 index 000000000..5f1aeb67f Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/search-dropdown.png differ diff --git a/_site/docs/doc-update-detection/questions/images/select-region-map.png b/_site/docs/doc-update-detection/questions/images/select-region-map.png new file mode 100644 index 000000000..6e279a6be Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/select-region-map.png differ diff --git a/_site/docs/doc-update-detection/questions/images/show-row-index.png b/_site/docs/doc-update-detection/questions/images/show-row-index.png new file mode 100644 index 000000000..f6a59a745 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/show-row-index.png differ diff --git a/_site/docs/doc-update-detection/questions/images/snippet_sidebar_and_insertion.gif b/_site/docs/doc-update-detection/questions/images/snippet_sidebar_and_insertion.gif new file mode 100644 index 000000000..16941df34 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/snippet_sidebar_and_insertion.gif differ diff --git a/_site/docs/doc-update-detection/questions/images/sort-step.png b/_site/docs/doc-update-detection/questions/images/sort-step.png new file mode 100644 index 000000000..ea865a53b Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/sort-step.png differ diff --git a/_site/docs/doc-update-detection/questions/images/sql-sidebar.png b/_site/docs/doc-update-detection/questions/images/sql-sidebar.png new file mode 100644 index 000000000..181200aaa Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/sql-sidebar.png differ diff --git a/_site/docs/doc-update-detection/questions/images/stacked-100.png b/_site/docs/doc-update-detection/questions/images/stacked-100.png new file mode 100644 index 000000000..d20461561 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/stacked-100.png differ diff --git a/_site/docs/doc-update-detection/questions/images/stacked-bar-chart.png b/_site/docs/doc-update-detection/questions/images/stacked-bar-chart.png new file mode 100644 index 000000000..1ff7acb0c Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/stacked-bar-chart.png differ diff --git a/_site/docs/doc-update-detection/questions/images/state-field-filter.png b/_site/docs/doc-update-detection/questions/images/state-field-filter.png new file mode 100644 index 000000000..f66b4c178 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/state-field-filter.png differ diff --git a/_site/docs/doc-update-detection/questions/images/sum-of-totals-for-previous-period.png b/_site/docs/doc-update-detection/questions/images/sum-of-totals-for-previous-period.png new file mode 100644 index 000000000..123c3b864 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/sum-of-totals-for-previous-period.png differ diff --git a/_site/docs/doc-update-detection/questions/images/summarize-by-week-of-year.png b/_site/docs/doc-update-detection/questions/images/summarize-by-week-of-year.png new file mode 100644 index 000000000..ef294da62 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/summarize-by-week-of-year.png differ diff --git a/_site/docs/doc-update-detection/questions/images/summarize-step.png b/_site/docs/doc-update-detection/questions/images/summarize-step.png new file mode 100644 index 000000000..c1d23d964 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/summarize-step.png differ diff --git a/_site/docs/doc-update-detection/questions/images/summarize-timeseries-breakout.png b/_site/docs/doc-update-detection/questions/images/summarize-timeseries-breakout.png new file mode 100644 index 000000000..f3d5fb490 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/summarize-timeseries-breakout.png differ diff --git a/_site/docs/doc-update-detection/questions/images/summarize-timeseries.png b/_site/docs/doc-update-detection/questions/images/summarize-timeseries.png new file mode 100644 index 000000000..cbaef351e Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/summarize-timeseries.png differ diff --git a/_site/docs/doc-update-detection/questions/images/sunburst-metric-options.png b/_site/docs/doc-update-detection/questions/images/sunburst-metric-options.png new file mode 100644 index 000000000..707e82393 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/sunburst-metric-options.png differ diff --git a/_site/docs/doc-update-detection/questions/images/sunburst-settings-showcase.png b/_site/docs/doc-update-detection/questions/images/sunburst-settings-showcase.png new file mode 100644 index 000000000..dc9697c66 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/sunburst-settings-showcase.png differ diff --git a/_site/docs/doc-update-detection/questions/images/sunburst-two-levels.png b/_site/docs/doc-update-detection/questions/images/sunburst-two-levels.png new file mode 100644 index 000000000..e2ebcfafb Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/sunburst-two-levels.png differ diff --git a/_site/docs/doc-update-detection/questions/images/switch-to-editor.png b/_site/docs/doc-update-detection/questions/images/switch-to-editor.png new file mode 100644 index 000000000..287678689 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/switch-to-editor.png differ diff --git a/_site/docs/doc-update-detection/questions/images/tooltip.png b/_site/docs/doc-update-detection/questions/images/tooltip.png new file mode 100644 index 000000000..6e0dab42a Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/tooltip.png differ diff --git a/_site/docs/doc-update-detection/questions/images/trend-lines.png b/_site/docs/doc-update-detection/questions/images/trend-lines.png new file mode 100644 index 000000000..21ce33f61 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/trend-lines.png differ diff --git a/_site/docs/doc-update-detection/questions/images/trend-settings.png b/_site/docs/doc-update-detection/questions/images/trend-settings.png new file mode 100644 index 000000000..2f1b7fb7e Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/trend-settings.png differ diff --git a/_site/docs/doc-update-detection/questions/images/unpinned-from-zero-y-axis.png b/_site/docs/doc-update-detection/questions/images/unpinned-from-zero-y-axis.png new file mode 100644 index 000000000..b37449e7a Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/unpinned-from-zero-y-axis.png differ diff --git a/_site/docs/doc-update-detection/questions/images/view-the-sql.png b/_site/docs/doc-update-detection/questions/images/view-the-sql.png new file mode 100644 index 000000000..5d118de41 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/view-the-sql.png differ diff --git a/_site/docs/doc-update-detection/questions/images/visualize-native.png b/_site/docs/doc-update-detection/questions/images/visualize-native.png new file mode 100644 index 000000000..25cba6560 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/visualize-native.png differ diff --git a/_site/docs/doc-update-detection/questions/images/viz-options.png b/_site/docs/doc-update-detection/questions/images/viz-options.png new file mode 100644 index 000000000..b215f39ef Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/viz-options.png differ diff --git a/_site/docs/doc-update-detection/questions/images/waterfall-chart.png b/_site/docs/doc-update-detection/questions/images/waterfall-chart.png new file mode 100644 index 000000000..25562fffc Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/waterfall-chart.png differ diff --git a/_site/docs/doc-update-detection/questions/images/week-instance.png b/_site/docs/doc-update-detection/questions/images/week-instance.png new file mode 100644 index 000000000..347454663 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/week-instance.png differ diff --git a/_site/docs/doc-update-detection/questions/images/week-iso.png b/_site/docs/doc-update-detection/questions/images/week-iso.png new file mode 100644 index 000000000..82cf0608b Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/week-iso.png differ diff --git a/_site/docs/doc-update-detection/questions/images/week-us.png b/_site/docs/doc-update-detection/questions/images/week-us.png new file mode 100644 index 000000000..6177879f0 Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/week-us.png differ diff --git a/_site/docs/doc-update-detection/questions/images/year-over-year-sum-totals.png b/_site/docs/doc-update-detection/questions/images/year-over-year-sum-totals.png new file mode 100644 index 000000000..335ce262b Binary files /dev/null and b/_site/docs/doc-update-detection/questions/images/year-over-year-sum-totals.png differ diff --git a/_site/docs/doc-update-detection/questions/introduction.html b/_site/docs/doc-update-detection/questions/introduction.html new file mode 100644 index 000000000..77580ab64 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/introduction.html @@ -0,0 +1,3167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Questions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Questions

+ +

Metabase question

+ +

Questions in Metabase are queries, their results, and their visualization. Questions are the basic analytical unit in Metabase. You can think about questions as saved queries that you can display as tables or charts. You can organize questions into collections and dashboards. You can embed questions, share links to them, export their results, and have them alert you when results are interesting.

+ +

Creating a new question

+ +

You can create a new question from scratch, or build off of an existing question. To create a question from scratch, you can click on + New and select how you want to query your data: either with the graphical query builder, or the SQL/native editor.

+ +

Query builder

+ +

Query builder editor

+ +

Selecting Question will take you to the editor in the graphical query builder.

+ +

Native editor

+ +

Native editor

+ +

Selecting SQL/native code will open the native code editor.

+ +

Even if you know SQL, you should still check out the graphical query builder, as you can use it to build interactive charts.

+ +

From an existing question

+ +

You can also build a new question from an existing question. You won’t overwrite the existing question, so feel free to play around. You can use either the query builder or the native code editor.

+ +

Some kinds of saved questions, however, can’t be used as source data:

+ +
    +
  • Druid questions
  • +
  • Mongo questions
  • +
  • Questions that use Cumulative Sum or Cumulative Count aggregations
  • +
  • Questions that have columns that are named the same or similar thing, like Count and Count 2
  • +
+ +

Saving questions

+ +

Once you’ve built your query and visualized its results, you can save a question to a dashboard (the default), or to a collection. You’ll need to name the question, include an optional description, and save it to a dashboard or a collection.

+ +

Saving questions to dashboards

+ +

Questions that live in a dashboard are only visible in that dashboard. These questions can’t be used in other dashboards. When you save a question to a dashboard, you’ll need to arrange the card on one of the dashboard’s tab, then save the dashboard.

+ +

Saving questions to collections

+ +

Questions saved to a collection can be added to multiple dashboards. Moving a question from one collection to another collection won’t have any effect on the dashboards the question has been added to. In order to save a question to a collection, you’ll need to be in a group with curate access to that collection.

+ +

Moving questions from collections to dashboards (and vice versa)

+ +

Whether you can move a question in a collection into a dashboard depends on how many other dashboards use that question.

+ +

You can move the question from a collection into a dashboard if either:

+ +
    +
  • No other dashboards use that question.
  • +
  • The other dashboards that use that question live in collections you have curate access to. In this case, Metabase will tell you which other dashboards use that question, and you’ll have to decide whether you’re okay with removing the question from those dashboards.
  • +
+ +

Info about your question

+ +

Once you save a question, you can click on the info icon in the upper right to see some metadata about your question:

+ +

Info sidesheet

+ +

Overview tab

+ +
    +
  • Description, which you can add–descriptions even support Markdown!
  • +
  • Who created the question, and who edited it last
  • +
  • The collection or dashboard the question is saved in
  • +
  • The data the question is based on.
  • +
  • The question’s Entity ID (which you can use with Serialization to keep IDs consistent across multiple Metabases).
  • +
+ +

History tab

+ +

See history.

+ +

Downloading your question’s results

+ +

See exporting results.

+ +

Verifying a question

+ +

See content verification.

+ +

Bookmark a question

+ +

Click the bookmark icon to pin a question to your Metabase sidebar. See Bookmarks.

+ +

Turning a question into a model

+ +

You can turn a question saved to a collection into a model to let others know that the results make a good starting point for new questions. (You can’t turn a question saved to a dashboard into a model; you’ll first need to move the question to a collection). See models.

+ +

Caching question results

+ +
+
+ + + + + + + +

Caching question results is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

See caching per question.

+ +

Setting up alerts

+ +

You can set up questions to run periodically and notify you if the results are interesting. Check out alerts.

+ +

Viewing events on your chart

+ +

If your results are a time series, you can display events on along the x-axis. See events and timelines.

+ +

Deleting a question

+ +

See delete and restore.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/native-editor/data-model-reference.html b/_site/docs/doc-update-detection/questions/native-editor/data-model-reference.html new file mode 100644 index 000000000..bfdbd24fc --- /dev/null +++ b/_site/docs/doc-update-detection/questions/native-editor/data-model-reference.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/native-editor/referencing-saved-questions-in-queries.html b/_site/docs/doc-update-detection/questions/native-editor/referencing-saved-questions-in-queries.html new file mode 100644 index 000000000..89057c3bb --- /dev/null +++ b/_site/docs/doc-update-detection/questions/native-editor/referencing-saved-questions-in-queries.html @@ -0,0 +1,3105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Referencing models and saved questions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Referencing models and saved questions

+ +

With SQL databases, we can use a model or an existing question as the basis for a new query, or as a common table expression CTE.

+ +

For example, let’s say we have a lot of data spread across a number of tables, but people are most interested in a subset of that data. We can perform a complicated query once to return those results, and save that question as a model, which people can refer to in their queries just like they would with any other table.

+ +

Search for models and questions as you type

+ +

First, create and save a question or model that returns the result set you’d like to make available for people to query.

+ +

To reference that question or model in a SQL query, use typeahead search in a variable prefixed with #.

+ +

Type {{#your search term }} and Metabase will display a list of models and questions relevant to your search term.

+ +

Typeahead search dropdown for referencing questions and models in SQL queries

+ +

You can also find the question or model ID by navigating in Metabase to the model or question you’d like to reference in your query. The ID is in the URL in your browser’s address bar. The ID will be the number after /model/ or /question/. E.g., for https://metabase.example.com/model/12345-example-name, the model’s ID would be 12345.

+ +

Only the # and ID is required. Metabase just displays the model or question name to make the query more readable.

+ +

Model, table, or saved question as a Common Table Expression (CTE)

+ +

The same syntax can be used in Common Table Expressions (CTEs) (with SQL databases that support CTEs):

+ +
WITH gizmo_orders AS {{#5-gizmo-orders-in-2019}}
+SELECT count(*)
+FROM gizmo_orders
+
+ +

When this query is run, the {{#5-gizmo-orders-in-2019}} tag will be substituted with the SQL query of the referenced question, surrounded by parentheses. So it’ll look like this under the hood:

+ +
WITH
+  gizmo_orders AS (
+    SELECT
+      *
+    FROM
+      orders AS o
+      INNER JOIN products AS p ON o.product_id = p.id
+    WHERE
+      p.category = 'Gizmo'
+      AND o.created_at BETWEEN '2019-01-01' AND '2019-12-31'
+  )
+SELECT
+  count(*)
+FROM
+  gizmo_orders
+
+ +

Limitations and tradeoffs

+ +
    +
  • You can only reference a model or saved question in a query when working with a SQL database like PostgreSQL, MySQL, Snowflake or SQL Server.
  • +
  • The model or saved question you select has to be one that’s based on the same database as the one you’ve currently selected in the native query editor.
  • +
  • You cannot refer to variables in sub-queries. You only have access to the results of the model or saved question, not the model or saved question’s query. For example, if you have a saved question that uses a field filter, you won’t be able to reference that variable. If you need to change how the saved question has filtered the results, you’ll need to update (or duplicate) that question and apply the filter.
  • +
+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/native-editor/snippets.html b/_site/docs/doc-update-detection/questions/native-editor/snippets.html new file mode 100644 index 000000000..6dc0ea980 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/native-editor/snippets.html @@ -0,0 +1,3144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Snippets | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Snippets

+ +

Highlight and save as snippet

+ +

Snippets are reusable bits of SQL or native queries. Anyone with permissions to the SQL editor can create and edit snippets, which are then available for all SQL authors.

+ +

For example, if you frequently perform queries that involve multiple tables, you can save the SQL code that joins those tables as a snippet so that you (and others in your organization) can reuse that code in multiple questions.

+ +

How to create a snippet

+ +

Here’s a simple query with a join using the Sample Database included with Metabase.

+ +
SELECT *
+FROM orders AS o
+LEFT JOIN products AS p
+ON o.product_id = p.id
+
+ +

Let’s save everything after FROM as a snippet to reuse in other queries.

+ +

In the SQL editor:

+ +
    +
  1. +

    Highlight a section of SQL that you want to save. In this case, we’ll select the following SQL code:

    + +
    orders AS o
    +LEFT JOIN products AS p
    +ON o.product_id = p.id
    +
    +
  2. +
  3. Right-click on the highlighted section.
  4. +
  5. Select Save as snippet to create a snippet. A modal will pop up with the SQL statement you highlighted.
  6. +
  7. Edit, name, and describe your snippet. Snippet names must be unique. Click the save button to create the snippet.
  8. +
+ +

In this case, we named the snippet “Orders and Products”. The snippet will now be available for anyone to use. Here’s what the snippet looks like in the SQL editor:

+ +
SELECT *
+FROM {{snippet: Orders and Products}}
+
+ +

When writing in the SQL editor, you can now start typing {{snippet:}} and Metabase will present autocomplete options for available snippets.

+ +

Note: if you use aliases in a snippet, you’ll need to observe those aliases outside of the snippet as well. For example, if a snippet aliases products AS p, code outside of the snippet will need to use the alias p to reference columns in that table (as in p.column_name).

+ +

Snippet menu

+ +

Snippet sidebar and insertion

+ +

The SQL editor sidebar has a Snippets menu to list available and archived snippets.

+ +

Click on the snippet icon on the right side of the SQL editor, below the Data Reference book icon and the Variables χ icon. Metabase will slide out a sidebar menu that lists available snippets.

+ +

From the Snippets menu, you can:

+ +
    +
  • Create a snippet. Click on the + in the upper right of the Snippets sidebar to create a new snippet.
  • +
  • Preview snippets. Click on the down arrow to the right of a snippet to see its description and a preview of its SQL code. There’s also an option to edit the snippet.
  • +
  • Insert a snippet. Click on a snippet’s name to insert it into your query at the cursor’s current location.
  • +
  • Search for snippets. If you’ve saved over 15 snippets, a Search icon (the classic magnifying glass) will appear to the left of the + button. Note that search results only include snippets the user has permissions for. Snippet folders do not populate the search results.
  • +
  • Edit a snippet. You can change a snippet’s name, description and code.
  • +
  • Archive and unarchive a snippet. From the Edit modal, you can archive a snippet, which removes the snippet from the snippet menu and autocomplete options in the SQL editor.
  • +
+ +

Editing snippets

+ +

You can edit a snippet at any time by selecting the snippet from the Snippets sidebar menu in the SQL editor. Click on the down arrow to the right of the snippet, then click Edit. You can change the SQL code, snippet name, and snippet description.

+ +

Editing snippets is a great way to make changes to many questions at once. If, for example, you’ve saved the SQL code to pull user data from tables X, Y, and Z as the snippet User Data, but you need to change how that data is pulled (such as by adding data from another column or table), you can update the SQL code in the snippet, and all questions that use the snippet User Data will have the updated code.

+ +

Editing a snippet’s name. Changing a snippet’s name will update the snippet’s name in every question that uses that snippet. It won’t break any existing questions (the underlying SQL remains unchanged), but be aware that other users may be caught off guard to discover you renamed a snippet they use frequently from “Orders and Products” to “All the things”, or whatever.

+ +

Editing a snippet’s SQL. Here’s where we have to remind you that with great power comes great responsibility. There is one major caveat when editing snippets, worthy of a callout:

+ +
+

Caution: if you edit a snippet and include broken code, you will break every question that uses that snippet. Make sure to test your code before saving it to an existing snippet.

+
+ +

Archiving snippets

+ +

Archiving snippets can help keep dated or less relevant snippets out of the way. When you archive a snippet, the snippet no longer populates in the snippet autocomplete dropdown, and the snippet will no longer show up in the main list of snippets in the SQL editor sidebar.

+ +

Archiving a snippet does not affect any existing queries that use the snippet, so you can safely archive a snippet without impacting any questions.

+ +

You can access an archived snippet from the snippet sidebar menu by clicking on the archived button in the bottom left of the sidebar.

+ +

Although there is no way to delete a snippet, you can archive and unarchive a snippet at any time.

+ +

Note: two snippets cannot share the same name, as even if a snippet is archived, that snippet might still be active in questions.

+ +

Snippet permissions

+ +

Any user who has SQL editor permissions to at least one of your connected databases will be able to view the snippets sidebar, and will be able to create, edit, and archive or unarchive any and all snippets — even snippets intended to be used with databases the user lacks SQL editing access to.

+ +

Some plans contain additional functionality for organizing snippets into folders and setting permissions on those folders. See our docs on Snippet folders and permissions.

+ +

Learn more

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/native-editor/sql-parameters.html b/_site/docs/doc-update-detection/questions/native-editor/sql-parameters.html new file mode 100644 index 000000000..916b38472 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/native-editor/sql-parameters.html @@ -0,0 +1,3488 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SQL parameters | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SQL parameters

+ +

You can create SQL templates by adding variables to your SQL queries in the Native/SQL editor. These variables will create filter widgets that you can use to change the variable’s value in the query. You can also add parameters to your question’s URL to set the filters’ values, so that when the question loads, those values are inserted into the variables.

+ +

Variables

+ +

Defining variables

+ +

Typing {{variable_name}} in your native query creates a variable called variable_name.

+ +

Field Filters, a special type of filter, have a slightly different syntax.

+ +

This example defines a Text variable called category:

+ +

+SELECT
+  count(*)
+FROM
+  products
+WHERE
+  category = {{category}}
+
+
+ +

Metabase will read the variable and attach a filter widget to the query, which people can use to change the value inserted into the cat variable with quotes. So if someone entered “Gizmo” into the filter widget, the query Metabase would run would be:

+ +
SELECT
+  count(*)
+FROM
+  products
+WHERE
+  category = 'Gizmo'
+
+ +

If you’re writing a native MongoDB query, your query would look more like this, with the cat variable being defined inside of the match clause.

+ +
[{ $match: { category: {{cat}} } }]
+
+ +

Setting SQL variables

+ +

To set a SQL variable to a value, you can either:

+ +
    +
  • Enter a value into the filter widget, and re-run the question, or
  • +
  • Add a parameter to the URL and load the page.
  • +
+ +

To add a value to the URL, follow this syntax:

+ +
?variable_name=value
+
+ +

For example, to set the {{cat}} variable on a question to the value “Gizmo”, your URL would look something like:

+ +
https://metabase.example.com/question/42-eg-question?cat=Gizmo
+
+ +

To set multiple variables, separate parameters with an ampersand (&):

+ +
https://metabase.example.com/question/42-eg-question?cat=Gizmo&maxprice=50
+
+ +

SQL variable types

+ +

When you define a variable, the Variables side panel will appear. You can set a type for a variable, which changes the kind of filter widget that Metabase presents.

+ +

There are four types of variables:

+ +
    +
  • Text: a plain input box.
  • +
  • Number: a plain input box.
  • +
  • Date: a simple date picker. If you want a more expressive date picker, like specifying a range, you’ll want to use a Field Filter.
  • +
  • Field Filter: different filter widgets, depending on the mapped field.
  • +
+ +

That last variable type, Field Filter, is special; it lets you create “smart” filter widgets, like a search box, or a dropdown menu of values, or a dynamic date picker that allows you to specify a date range.

+ +

You can include multiple variables in the query, and Metabase will add multiple filter widgets to the question. When you have multiple filter widgets, you can click on a filter widget and drag it around to rearrange the order.

+ +

The Field Filter variable type

+ +

Setting a variable to the Field Filter type allows you to map the variable to a field in any table in the current database. Field filters let you create a “smart” filter widget that makes sense for that field.

+ +

Field Filter variables should be used inside of a WHERE clause in SQL, or a $match clause in MongoDB.

+ +

Field Filter compatible types

+ +

Field Filters ONLY work with the following field types:

+ +
    +
  • Category
  • +
  • Entity Name
  • +
  • Entity Key
  • +
  • Foreign Key
  • +
  • City
  • +
  • State
  • +
  • ZIP or Postal Code
  • +
+ +

The field can also be a date or timestamp, which can be left as “No semantic type” in the Table Metadata.

+ +

When you set the Variable type to “Field Filter”, Metabase will present an option to set the Field to map to, as well as the Filter widget type. The options available for the Filter widget type depend on the field’s type. For example, if you map to a field of type Category, you’ll see options for either “Category” or None. If you map to a Date Field, you’ll see options for None, Month and year, Quarter and year, Single date, Date range, or Date filter.

+ +

If you’re not seeing the option to display a filter widget, make sure the mapped field is set to one of the above types, and then try manually syncing your database from the “Databases” section of the Admin Panel to force Metabase to scan and cache the field’s values.

+ +

If you want to map a Field Filter to a field that isn’t one of the compatible types listed above, you’ll need an Admin to change the field type for that column. See metadata editing.

+ +

Field Filter syntax

+ +

Let’s say you want to create a Field Filter that filters the People table by state, and you want people to be able to select multiple states at a time. Here’s the query:

+ +

The syntax for Field Filters differs from a Text, Number, or Date variable.

+ +

+SELECT
+  *
+FROM
+  PEOPLE
+WHERE
+  {{state}}
+
+
+ +

Then, in the side panel, select the “Field Filter” variable type, and choose which field to map your variable to (in this case, State).

+ +

Note the lack of the column and operator (like =). The reason you need to structure Field Filters this way is to handle cases where Metabase generates the code for you. For example, for handling cases where someone selects multiple values in the filter widget, or a range of dates. With Field Filters, you can’t control the generated SQL, so if you need greater control, you should use one (or more) Text, Number, or Date variables.

+ +

A MongoDB native query example might look like this:

+ +
[ {$match: {{date_var}} } ]
+
+ +

For a more in-depth guide, check out Field Filters: create smart filter widgets for SQL questions.

+ +

Field filters in BigQuery and Oracle

+ +

Make sure your SQL dialect matches the database you’ve selected. Common issues involving how tables are quoted in the query:

+ + + + + + + + + + + + + + + + + + + + + +
DatabaseDialect quirkExample
BigQuerySchemas and tables must be quoted with backticks.FROM `dataset.table`
OracleSchemas and tables must be quoted in double quotes.FROM schema.table
+ +

For more help, see Troubleshooting SQL error messages.

+ +

How to create different types of filter widgets

+ +

The kind of filter widget that Metabase displays when you create a Field Filter widget depends on a setting for that field in Metabase called Filtering on this field. Admins can set this field option to:

+ +
    +
  • Plain input box
  • +
  • Search box
  • +
  • A list of all values (also known as a dropdown menu)
  • +
+ +

Date fields will either have a simple date filter (for Date variables) or a dynamic date picker (for Field Filters mapped to a date field).

+ +

If you want to change the filter widget for a particular field, you’ll need to ask an Admin to update that field in the Table Metadata and set the desired “Filtering on this field” option.

+ +

Filter widget with plain input box

+ +

Create a simple Text or Number variable. Additionally, you can use a Field Filter with a field that has its Filtering on this field value set to “Plain input box”.

+ +

Note: to guard against SQL injection attacks, Metabase converts whatever is in the Search box to a string. If you want to use wildcards, check out our Learn article.

+ + + +
    +
  • Include a SQL variable in your query.
  • +
  • Set the Variable type to Field Filter.
  • +
  • Set the Field to map to to a field of type “Category” that has its Filtering on this field option set to “Search box”
  • +
+ + + +

To create a dropdown menu with search and a list of all values, you need to:

+ +
    +
  • Include a SQL variable in your query.
  • +
  • Set the Variable type to Field Filter.
  • +
  • Set the Field to map to to a field of type “Category” that has its Filtering on this field option set to “A list of all values”.
  • +
  • Set the Filter widget type to “Category”.
  • +
+ +

If the field you want to create a dropdown for is not set to the type “Category” with Filtering on this field set to “A list of all values”, an Admin will need to update the settings for that field. For example, if you want to create a dropdown menu for an incompatible field type like an Email field, an admin will need to change that field type to “Category”, set the Filtering on this field option to A list of all values, then re-scan the values for that field.

+ +

If however, there are too many different values in that column to display in a dropdown menu, Metabase will simply display a search box instead. So if you have a lot of email addresses, you may just get a search box anyway. The dropdown menu widgets work better when there’s a small set of values to choose from (like the fifty U.S. states).

+ +

Field filter limitations

+ +

Some things that could trip you up when trying to set up a Field Filter variable.

+ +

Field Filters don’t work with table aliases

+ +

You won’t be able to select values from field filters in queries that use table aliases for joins or CTEs.

+ +

The reason is that field filters generate SQL based on the mapped field; Metabase doesn’t parse the SQL, so it can’t tell what an alias refers to. You have three options for workarounds, depending on the complexity of your query.

+ +
    +
  1. Use full table names.
  2. +
  3. Replace CTEs with subqueries.
  4. +
  5. Create a view in your database, and use the view as the basis of your query.
  6. +
+ +

Field Filters must be connected to fields included in the query

+ +

Your main query should be aware of all the tables that your Field Filter variable is pointing to, otherwise you’ll get a SQL syntax error. For example, let’s say that your main query includes a field filter like this:

+ +

+SELECT
+  *
+FROM
+  ORDERS
+WHERE
+  {{ product_category }}
+
+
+ +

Let’s say the {{ product_category }} variable refers to another question that uses the Products table. For the field filter to work, you’ll need to include a join to Products in your main query.

+ +

+SELECT
+  *
+FROM
+  ORDERS
+  JOIN PRODUCTS ON ORDERS.product_id = PRODUCTS.id
+WHERE
+  {{ product_category }}
+
+
+ +

Customizing dropdown lists and search box values

+ +

With Text and Field filter variables, you can tell Metabase what values people can choose from when using a filter with a dropdown list or search box.

+ +
    +
  1. In the native editor, add a {{variable}} in double braces.
  2. +
  3. If the sidebar doesn’t open, you can click on the {x} icon on the right to open the Variables sidebar.
  4. +
  5. In the Settings tab, set the Variable type to either “Text” or “Field Filter”.
  6. +
  7. In the sidebar, go to How should users filter on this variable? Pick either Dropdown list or Search box.
  8. +
  9. Next to the option you chose, click Edit.
  10. +
  11. Metabase will pop up a modal where you can select Where the values should come from.
  12. +
+ +

You can choose:

+ +
    +
  • From connected fields If you selected the Field filter variable type, you’ll also have the option to use the connected field.
  • +
  • From another model or question. If you select this option, you’ll need to pick a model or question, then a field from that model or question that Metabase will use to supply the values for that dropdown or search box. For example, if you want the dropdown to list the different plans an account could be on, you could select an “Account” model you created, and select the field “Plan” to power that dropdown. The dropdown would then list all of the distinct plan options that appear in the “Plan” column in the Accounts model.
  • +
  • Custom list. Enter each item on a line. You can enter any string values you like.
  • +
+ +

You can also change a dashboard filter’s selectable values.

+ +

Setting a default value in the filter widget

+ +

In the variables sidebar, you can set a default value for your variable. This value will be inserted into the corresponding filter widget by default (even if the filter widget is empty). You’ll need to insert a new value into the filter widget to override the default.

+ +

Setting complex default values in the query

+ +

You can also define default values directly in your query by enclosing comment syntax inside the end brackets of an optional parameter.

+ +
WHERE column = [[ {{ your_parameter }} --]] your_default_value
+
+ +

The comment will “activate” whenever you pass a value to your_parameter.

+ +

This is useful when defining complex default values (for example, if your default value is a function like CURRENT_DATE). Here’s a PostgreSQL example that sets the default value of a Date filter to the current date using CURRENT_DATE:

+ +

+SELECT
+  *
+FROM
+  orders
+WHERE
+  DATE(created_at) = [[ {{dateOfCreation}} --]] CURRENT_DATE
+
+
+ +

If you pass a value to the variable, the WHERE clause runs, including the comment syntax that comments out the default CURRENT_DATE function.

+ +

Note that the hash (--) used to comment the text might need to be replaced by the comment syntax specific to the database you’re using.

+ +

Requiring a value for a filter widget

+ +

In the Variable settings sidebar, you can toggle the Always require a value option. If you turn this on:

+ +
    +
  • You must enter a default value.
  • +
  • The default value will override any optional syntax in your code (like an optional WHERE clause). If no value is passed to the filter, Metabase will run the query using the default value. Click on the Eye icon in the editor to preview the SQL Metabase will run.
  • +
+ +

Making variables optional

+ +

You can make a clause optional in a query. For example, you can create an optional WHERE clause that contains a SQL variable, so that if no value is supplied to the variable (either in the filter or via the URL), the query will still run as if there were no WHERE clause.

+ +

To make a variable optional in your native query, put [[ .. ]] brackets around the entire clause containing the {{variable}}. If someone inputs a value in the filter widget for the variable, Metabase will place the clause in the template; otherwise Metabase will ignore the clause and run the query as though the clause didn’t exist.

+ +

In this example, if no value is given to cat, then the query will just select all the rows from the products table. But if cat does have a value, like “Widget”, then the query will only grab the products with a category type of Widget:

+ +

+SELECT
+  count(*)
+FROM
+  products
+[[WHERE category = {{cat}}]]
+
+
+ +

Your SQL must also be able to run without the optional clause in [[ ]]

+ +

You need to make sure that your SQL is still valid when no value is passed to the variable in the bracketed clause.

+ +

For example, excluding the WHERE keyword from the bracketed clause will cause an error if there’s no value given for cat:

+ +
-- this will cause an error:
+
+SELECT
+  count(*)
+FROM
+  products
+WHERE
+  [[category = {{cat}}]]
+
+
+ +

That’s because when no value is given for cat, Metabase will try to execute SQL as if the clause in [[ ]] didn’t exist:

+ +
SELECT
+  count(*)
+FROM
+  products
+WHERE
+
+ +

which is not a valid SQL query.

+ +

Instead, put the entire WHERE clause in [[ ]]:

+ +

+SELECT
+  count(*)
+FROM
+  products
+[[WHERE
+  category = {{cat}}]]
+
+
+ +

When there’s no value given for cat, Metabase will just execute:

+ +

+SELECT
+  count(*)
+FROM
+  products
+
+
+ +

which is still a valid query.

+ +

You need at least one WHERE when using multiple optional clauses

+ +

To use multiple optional clauses, you must include at least one regular WHERE clause followed by optional clauses, each starting with AND:

+ +

+SELECT
+  count(*)
+FROM
+  products
+WHERE
+  TRUE
+  [[AND id = {{id}}]
+  [[AND {{category}}]]
+
+
+ +

That last clause uses a Field filter (note the lack of a column in the AND clause). When using a field filter, you must exclude the column in the query; you need to map the variable in the side panel.

+ +

Optional variables in MongoDB

+ +

If you’re using MongoDB, you can make an clause optional like so:

+ +

+[
+    [[{
+        $match: {category: {{cat}}}
+    },]]
+    {
+        $count: "Total"
+    }
+]
+
+
+ +

Or with multiple optional filters:

+ +

+[
+    [[{ $match: {{cat}} },]]
+    [[{ $match: { price: { "$gt": {{minprice}} } } },]]
+    {
+        $count: "Total"
+    }
+]
+
+
+ +

Connecting a SQL question to a dashboard filter

+ +

In order for a saved SQL/native question to be usable with a dashboard filter, the question must contain at least one variable.

+ +

The kind of dashboard filter that can be used with the SQL question depends on the field. For example, if you have a field filter called {{var}} and you map it to a State field, you can map a Location dashboard filter to your SQL question. In this example, you’d create a new dashboard (or go to an existing dashboard), click the Pencil icon to enter Dashboard edit mode, add the SQL question that contains your State Field Filter variable, add a new dashboard filter (or edit an existing Location filter), then click the dropdown on the SQL question card to see the State Field Filter.

+ +

If you add a Date variable to the question, then it’s only possible to use the dashboard filter option Single Date. So if you are trying to use one of the other Time options on the dashboard, you’ll need to change the variable to a Field Filter variable and map it to a date column.

+ +

Field filter

+ +

More on Dashboard filters.

+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/native-editor/sql-snippets.html b/_site/docs/doc-update-detection/questions/native-editor/sql-snippets.html new file mode 100644 index 000000000..0a5dff266 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/native-editor/sql-snippets.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/native-editor/writing-sql.html b/_site/docs/doc-update-detection/questions/native-editor/writing-sql.html new file mode 100644 index 000000000..16ad59949 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/native-editor/writing-sql.html @@ -0,0 +1,3154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SQL editor | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SQL editor

+ +

If you ever need to ask questions that can’t be expressed using the query builder, you can use SQL instead.

+ +

What’s SQL?

+ +

SQL (pronounced “sequel”, or sometimes as S.Q.L. — people argue about this) stands for Structured Query Language, and is a widely used standard for getting data from databases. We won’t try to teach you all about SQL right now, but to learn more about it, check out Working with SQL.

+ +

Even if you don’t understand SQL or how to use it, it’s worthwhile to get an idea of how it works inside Metabase, because sometimes other people will share SQL-based questions that might be useful to you.

+ +

Starting a new SQL query

+ +

Select + New in the main nav bar. If you have the permissions to use the SQL editor, you’ll see an option to start a new SQL query next to a little console icon.

+ +

After clicking SQL query, you’ll see an editor where you can write and run queries in SQL (or your database’s native querying language).

+ +

SQL editor

+ +

To try it out, make sure you’ve selected the Sample Database, then paste in this short SQL query:

+ +
SELECT
+    sum(subtotal),
+    created_at
+FROM orders
+GROUP BY created_at;
+
+ +

Don’t worry if you don’t understand this just yet. Click the blue Run query button to execute your query.

+ +

You’ll notice that the table that comes back is the same as if you had used the query builder to ask for the sum of Subtotal in the Orders table, grouped by the Created At date.

+ +

Running query selections

+ +

You can run your SQL query by pressing ctrl + enter on Windows and Linux, or ⌘ + return on a Mac. You can also run only part of a query by highlighting the part you’d like to run before clicking the run button or using the run shortcut key.

+ +

Questions asked using SQL can be saved, downloaded, converted to models, and added to dashboards just like questions asked using the query builder.

+ +

You can also refer to models and saved questions in your SQL queries.

+ +

Use ?? instead of ? operator

+ +

If you’re using the ? JSON operator in PostgreSQL, use the equivalent ?? operator instead.

+ +

This is due to limitations of JDBC that interprets a single question mark ? as a parameter placeholder.

+ +

Format SQL queries

+ +

You can format your SQL queries by clicking on the “document” icon in the editor sidebar.

+ + + + + + + + + + + + + + +
Before formatAfter format
a SQL query before formattinga SQL query after formatting
+ +

The formatter works only for SQL queries, and isn’t available for SQLite and SQL Server.

+ +

Using SQL filters

+ +

If you or someone else wrote a SQL query that includes variables, that question might have filter widgets at the top of the screen above the editor. Filter widgets let you modify the SQL query before it’s run, changing the results you might get.

+ +

SQL filter

+ +

Writing SQL queries that use variables or parameters can be very powerful, but it’s also a bit more advanced, so that topic has its own page if you’d like to learn more.

+ +

Snippets

+ +

You can use Snippets to save, reuse, and share SQL code across multiple questions that are composed using the SQL editor.

+ +

How Metabase executes SQL queries

+ +

When you run a query from the SQL editor, Metabase sends the query to your database exactly as it is written. Any results or errors displayed in Metabase are the same as the results or errors that you would get if you ran the query directly against your database. If the SQL syntax of your query doesn’t match the SQL dialect used by your database, your database won’t be able to run the query.

+ +

Question version history

+ +

For questions, dashboards, and models, Metabase keeps a version history for the previous fifteen versions of that item.

+ +

See History.

+ +

Explore SQL question results using the Query Builder

+ +

On saved SQL questions without parameters, you’ll get the Explore results button. It will create a new Query Builder question that uses the SQL question results as a data source.

+ +

Explore results button

+ +

Drill-though in SQL questions

+ +

Visualizations created with SQL have limited drill-through capabilities:

+ +
    +
  • You can filter results of SQL queries by clicking on data points, zoom in on time series or maps, and use some column header actions.
  • +
  • You won’t be able to drill down to unaggregated records, change time granularity, or break out by categories or locations.
  • +
+ +

Caching results

+ +

See Caching question policies.

+ +

Learn more

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/editor.html b/_site/docs/doc-update-detection/questions/query-builder/editor.html new file mode 100644 index 000000000..908332c27 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/editor.html @@ -0,0 +1,3181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +The query builder | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

The query builder

+ +

Metabase includes a graphical query builder that lets you build interactive charts.

+ +

With the query builder you can:

+ + + +

When viewing a chart, you can also click through questions to explore the data in greater detail.

+ +

Drill-through menu

+ +

The drill-through menu will present different options depending on what you click on. You can then optionally save any exploration as a new question. Full drill-through menu is only available for questions built using the query builder. Questions built with the SQL/native editor will have only have limited drill-through actions. For more on how drill-through works, check out Creating interactive charts.

+ +

Creating a new question with the query builder

+ +

From the + New dropdown, select Question, then pick your starting data:

+ +

You can start a question from:

+ +
    +
  • A model. A model is a special kind of saved question meant to be used as a good starting point for questions. Sometimes these are called derived tables, as they usually pull together data from multiple raw tables.
  • +
  • A metric. Metrics are pre-defined calculations. If you pick a metric as a starting point for a question, Metabase will create a question with the same data source as the selected metric, and apply the metric. You’ll be able to add more joins, filter, and summaries.
  • +
  • Tables. You’ll need to specify the database and the table in that database as the starting point for your question.
  • +
  • A saved question. You can use the results of any question as the starting point for a new question.
  • +
+ +

Note that there are some kinds of saved questions that can’t be used as source data:

+ +
    +
  • Druid questions
  • +
  • Mongo questions
  • +
  • Questions that use Cumulative Sum or Cumulative Count aggregations
  • +
  • Questions that have columns that are named the same or similar thing, like Count and Count 2
  • +
+ +

The editor

+ +

Once you select your data, Metabase will take you to the query builder’s editor. Say you selected Tables > Sample database > Orders, then you’ll see something like this:

+ +

Metabase query builder

+ +

This is the query builder’s editor. It has three default steps.

+ + + +

You can also add steps for joining data, custom columns, and sorting results, and limiting results.

+ +

To the right of each completed step is a Preview button (looks like a Play button - a triangle pointing to the right) that shows you the first 10 rows of the results of your question up to that step.

+ +

Previewing results

+ +

Picking data

+ +

The data section is where you select the data you want to work with. Here you’ll pick a model, a metric, a table from a database, or a saved question.

+ +

data picker

+ +

You can see the data source in a new browser tab by Cmd/Ctrl+Clicking on the data source’s name in the query builder.

+ +

To choose which columns to include in your query, click on the arrow next to the data source. If you uncheck a column, you’ll still be able to use the column while building a query (for example, in filters) but Metabase won’t display the column in results.

+ +

You can hide columns from the table views.

+ +
+

Hiding columns should not be used to secure sensitive information. Hiding columns in table visualization settings only affects the visibility of the columns in the visualization, not in the query results. Even people with only “view data” permissions to the question will be able to change the visualization settings and unhide columns. To exclude a column from the results of a specific query, uncheck the column in the “Data” block of the query builder.

+
+ +

Joining data

+ +

You can also select multiple tables from the same database by joining them.

+ +

Filtering data

+ +

See filters.

+ +

Visualizing your data

+ +

Check out visualizing results.

+ +

Column heading drill-through

+ +

When viewing a table, clicking on the heading of a column gives you different options, depending on the columns data type. See table.

+ +

Custom expressions

+ +

Custom expressions allow you to use spreadsheet-like functions and simple arithmetic within or between aggregation functions.

+ +

Custom expression

+ +

For example, you could do Average(sqrt[FieldX]) + Sum([FieldY]) or Max(floor([FieldX] - [FieldY])), where FieldX and FieldY are fields in the currently selected table. Learn more about writing expressions.

+ +

Custom columns

+ +

Custom column

+ +

Custom columns are helpful when you need to create a new column based on a calculation, such as subtracting the value of one column from another, or extracting a portion of an existing text column. Custom columns that you add aren’t permanently added to your table; the columns will only be present in the given question.

+ +

You can use the following math operators in your formulas: +, , * (multiplication), and / (division), along with a whole host of spreadsheet-like functions. You can also use parentheses to clarify the order of operations. See list of expressions.

+ +

Sorting results

+ +

Sorting

+ +

The sorting step lets you pick one or more columns to sort your results by. For each column you pick, you can also choose whether to sort ascending or descending; just click the arrow to change from ascending (up arrow) to descending (down arrow).

+ +

Setting a row limit

+ +

The row limit step lets you cap how many rows you want from the previous results. When used in conjunction with sorting, limits can let you do things like create a top-10 list, by first sorting by one of the columns in your result, then adding a row limit of 10. Unlike other steps, the row limit step can only be added at the end of your question. If you do want to add more steps to limited results, you can always save the limited results as a question, then start a new question based on those results.

+ +

Viewing the native query that powers your question

+ +

View the SQL

+ +

Under the hood, all Metabase questions are converted to SQL or another language native to your query engine. To view the native query that Metabase will run when you click Visualize, click the View SQL or View query button in the top right of the query builder. Metabase will preview the native query in a sidebar:

+ +

SQL sidebar

+ +

To view the native query, you must have query builder and native permissions.

+ +

Convert a query-builder question to SQL

+ +

You can also convert the question to a native editor question. From the query builder screen:

+ +
    +
  1. Click the Console icon in the upper right of the query builder.
  2. +
  3. Click Convert the question to SQL option in the bottom right below the SQL code.
  4. +
+ +

Conversion is a one-way street: you can’t convert a SQL question back into a query builder question.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions-list.html b/_site/docs/doc-update-detection/questions/query-builder/expressions-list.html new file mode 100644 index 000000000..7ff377c9f --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions-list.html @@ -0,0 +1,4069 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +List of expressions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

List of expressions

+ +

For an introduction to expressions, check out the overview of custom expressions.

+ + + +

Aggregations

+ +

Aggregation expressions take into account all values in a field. They can only be used in the Summarize section of the query builder.

+ +

Average

+ +

Returns the average of the values in the column.

+ +

Syntax: Average(column)

+ +

Example: Average([Quantity]) would return the mean for the Quantity field.

+ +

Count

+ +

Returns the count of rows (also known as records) in the selected data.

+ +

Syntax: Count

+ +

Example: Count If a table or result returns 10 rows, Count will return 10.

+ +

CountIf

+ +

Only counts rows where the condition is true.

+ +

Syntax: CountIf(condition)

+ +

Example: CountIf([Subtotal] > 100) would return the number of rows where the subtotal were greater than 100.

+ +

Distinct

+ +

The number of distinct values in this column.

+ +

Syntax: Distinct(column)

+ +

Example: Distinct([Last Name]). Returns the count of unique last names in the column. Duplicates (of the last name “Smith” for example) are not counted.

+ +

DistinctIf

+ +

Returns the count of distinct values in a column where the condition is true.

+ +

Syntax: DistinctIf(column, condition)

+ +

Example: DistinctIf([ID], [Category] = "Gizmo") would return the count of unique IDs where the Category column is “Gizmo”.

+ +

Max

+ +

Returns the largest value found in the column.

+ +

Syntax: Max(column)

+ +

Example: Max([Age]) would return the oldest age found across all values in the Age column.

+ +

Related: Min, Average, Median.

+ +

Median

+ +

Returns the median value of the specified column.

+ +

Syntax: Median(column)

+ +

Example: Median([Age]) would find the midpoint age where half of the ages are older, and half of the ages are younger.

+ +

Databases that don’t support median: Druid, MariaDB, MongoDB, MySQL, SQLite, Vertica, and SQL Server. Presto only provides approximate results.

+ +

Related: Min, Max, Average.

+ +

Min

+ +

Returns the smallest value found in the column.

+ +

Syntax: Min(column)

+ +

Example: Min([Salary]) would find the lowest salary among all salaries in the Salary column.

+ +

Related: Max, Median, Average.

+ +

Percentile

+ +

Returns the value of the column at the percentile value.

+ +

Syntax: Percentile(column, percentile-value)

+ +

Example: Percentile([Score], 0.9) would return the value at the 90th percentile for all values in that column.

+ +

Databases that don’t support percentile: Druid, H2, MariaDB, MySQL, MongoDB, SQL Server, SQLite, Vertica. Presto only provides approximate results.

+ +

Share

+ +

Returns the percent of rows in the data that match the condition, as a decimal.

+ +

Syntax: Share(condition)

+ +

Example: Share([Color] = "Blue") would return the number of rows with the Color field set to Blue, divided by the total number of rows.

+ +

StandardDeviation

+ +

Calculates the standard deviation of the column, which is a measure of the variation in a set of values. Low standard deviation indicates values cluster around the mean, whereas a high standard deviation means the values are spread out over a wide range.

+ +

Syntax: StandardDeviation(column)

+ +

Example: StandardDeviation([Population]) would return the SD for the values in the Population column.

+ +

Databases that don’t support StandardDeviation: Druid, SQLite.

+ +

Sum

+ +

Adds up all the values of the column.

+ +

Syntax: Sum(column)

+ +

Example: Sum([Subtotal]) would add up all the values in the Subtotal column.

+ +

SumIf

+ +

Sums up the specified column only for rows where the condition is true.

+ +

Syntax: SumIf(column, condition)

+ +

Example:SumIf([Subtotal], [Order Status] = "Valid") would add up all the subtotals for orders with a status of “Valid”.

+ +

Variance

+ +

Returns the numeric variance for a given column.

+ +

Syntax: Variance(column)

+ +

Example: Variance([Temperature]) will return a measure of the dispersion from the mean temperature for all temps in that column.

+ +

Related: StandardDeviation, Average.

+ +

Databases that don’t support Variance: Druid, SQLite.

+ +

Functions

+ +

Function expressions apply to each individual value. They can be used to alter or filter values in a column, or create new, custom columns.

+ +

Logical functions

+ +

Logical functions determine if a condition is satisfied or determine what value to return based on a condition.

+ +

between

+ +

Returns true if the value of a date or number column falls within a specified range. Otherwise returns false.

+ +

Syntax: between(column, start, end)

+ +

Example: If you filtered with the expression between([Created At], "2019-01-01", "2020-12-31"), Metabase would return rows that returned true for that expression, in this case where the Created At date fell within the range of January 1, 2019 and December 31, 2020, including the start (2019-01-01) and end (2020-12-31) dates.

+ +

Related: interval.

+ +

case

+ +

case (alias if) tests an expression against a list of cases and returns the corresponding value of the first matching case, with an optional default value if nothing else is met.

+ +

Syntax: case(condition, output, …)

+ +

Example: case([Weight] > 200, "Large", [Weight] > 150, "Medium", "Small") If a Weight is 250, the expression would return “Large”. In this case, the default value is “Small”, so any Weight 150 or less would return “Small”.

+ +

coalesce

+ +

Looks at the values in each argument in order and returns the first non-null value for each row.

+ +

Syntax: coalesce(value1, value2, …)

+ +

Example: coalesce([Comments], [Notes], "No comments"). If both the Comments and Notes columns are null for that row, the expression will return the string “No comments”.

+ +

if

+ +

if is an alias for case. Tests an expression against a list of conditionals and returns the corresponding value of the first matching case, with an optional default value if nothing else is met.

+ +

Syntax: if(condition, output, ...)

+ +

Example: if([Weight] > 200, "Large", [Weight] > 150, "Medium", "Small") If a Weight is 250, the expression would return “Large”. In this case, the default value is “Small”, so any Weight 150 or less would return “Small”.

+ +

isNull

+ +

Returns true if the column is null.

+ +

Syntax: isNull(column)

+ +

Example: isNull([Tax]) would return true if no value were present in the column for that row.

+ +

Related: notNull, isEmpty

+ +

notNull

+ +

Returns true if the column contains a value.

+ +

Syntax: notNull(column)

+ +

Example: notNull([Tax]) would return true if there is a value present in the column for that row.

+ +

Related: isNull, notEmpty

+ +

Math functions

+ +

Math functions implement common mathematical operations.

+ +

abs

+ +

Returns the absolute (positive) value of the specified column.

+ +

Syntax: abs(column)

+ +

Example: abs([Debt]). If Debt were -100, abs(-100) would return 100.

+ +

ceil

+ +

Rounds a decimal up (ceil as in ceiling).

+ +

Syntax: ceil(column)

+ +

Example: ceil([Price]). ceil(2.99) would return 3.

+ +

Related: floor, round.

+ +

exp

+ +

Returns Euler’s number, e, raised to the power of the supplied number. (Euler sounds like “Oy-ler”).

+ +

Syntax: exp(column)

+ +

Example: exp([Interest Months])

+ +

Related: power.

+ +

floor

+ +

Rounds a decimal number down.

+ +

Syntax: floor(column)

+ +

Example: floor([Price]). If the Price were 1.99, the expression would return 1.

+ +

Related: ceil, round.

+ +

log

+ +

Returns the base 10 log of the number.

+ +

Syntax: log(column)

+ +

Example: log([Value]).

+ +

power

+ +

Raises a number to the power of the exponent value.

+ +

Syntax: power(column, exponent)

+ +

Example: power([Length], 2). If the length were 3, the expression would return 9 (3 to the second power is 3*3).

+ +

Databases that don’t support power: SQLite.

+ +

Related: exp.

+ +

round

+ +

Rounds a decimal number either up or down to the nearest integer value.

+ +

Syntax: round(column)

+ +

Example: round([Temperature]). If the temp were 13.5 degrees centigrade, the expression would return 14.

+ +

Example: round([Temperature] * 10) / 10. If the temp were 100.75, the expression would return 100.8.

+ +

sqrt

+ +

Returns the square root of a value.

+ +

Syntax: sqrt(column)

+ +

Example: sqrt([Hypotenuse]).

+ +

Databases that don’t support sqrt: SQLite.

+ +

Related: Power.

+ +

String functions

+ +

String functions manipulate or validate string data.

+ +

concat

+ +

Combine two or more strings together.

+ +

Syntax: concat(value1, value2, …)

+ +

Example: concat([Last Name], ", ", [First Name]) would produce a string of the format “Last Name, First Name”, like “Palazzo, Enrico”.

+ +

contains

+ +

Checks to see if string1 contains string2 within it.

+ +

Performs case-sensitive match by default. +You can pass an optional parameter "case-insensitive" to perform a case-insensitive match.

+ +

Syntax: contains(string1, string2) for case-sensitive match.

+ +

contains(string1, string2, "case-insensitive") for case-insensitive match.

+ +

Example: contains([Status], "Class").

+ +

If Status were “Classified”, the expression would return true. If the Status were “classified”, the expression would return false, because the case does not match.

+ +

Related: doesNotContain, regexextract.

+ +

date

+ +
+

Only available for PostgreSQL.

+
+ +

Converts an ISO 8601 date string to a date. The string must be in a valid ISO 8601 format.

+ +

Syntax: date(value)

+ +

Example: date("2025-03-20") would return a date value so that you can use all the date features in the query builder: group by month, filter by previous 30 days, etc.

+ +

ISO 8601 standard format:

+ +
    +
  • Year (YYYY): 2025
  • +
  • Month (MM): 03
  • +
  • Day (DD): 25
  • +
  • Time separator (T)
  • +
  • Hours (HH): 14
  • +
  • Minutes (MM): 30
  • +
  • Seconds (SS): 45
  • +
  • UTC timezone indicator (Z)
  • +
+ +

Valid ISO 8601 examples include:

+ +
    +
  • Date only: 2025-03-25
  • +
  • Date with time: 2025-03-25T14:30:45
  • +
  • Date with time and timezone offset: 2025-03-25T14:30:45+01:00
  • +
+ +

doesNotContain

+ +

Checks to see if string1 contains string2 within it.

+ +

Performs case-sensitive match by default. +You can pass an optional parameter "case-insensitive" to perform a case-insensitive match.

+ +

Syntax: doesNotContain(string1, string2) for case-sensitive match.

+ +

doesNotContain(string1, string2, "case-insensitive") for case-insensitive match.

+ +

Example: doesNotContain([Status], "Class"). If Status were “Classified”, the expression would return false.

+ +

Related: contains, regexextract.

+ +

domain

+ +

Extracts the domain name from a URL or email.

+ +

Syntax: domain(urlOrEmail)

+ +

Example: domain([Page URL]). If the [Page URL] column had a value of https://www.metabase.com, domain([Page URL]) would return metabase. domain([Email]) would extract metabase from hello@metabase.com.

+ +

Related: host, path, subdomain.

+ +

endsWith

+ +

Returns true if the end of the text matches the comparison text.

+ +

Performs case-sensitive match by default. +You can pass an optional parameter "case-insensitive" to perform a case-insensitive match.

+ +

Syntax: endsWith(text, comparison) for case-sensitive match.

+ +

endsWith(text, comparison, "case-insensitive") for case-insensitive match.

+ +

Example: endsWith([Appetite], "hungry")

+ +

Related: startsWith, contains, doesNotContain.

+ +

host

+ +

Extracts the host, which is the domain and the TLD, from a URL or email.

+ +

Syntax: host(urlOrEmail)

+ +

Example: host([Page URL]). If the [Page URL] column had a value of https://www.metabase.com, host([Page URL]) would return metabase.com. host([Email]) would extract metabase.com from hello@metabase.com.

+ +

Related: domain, path, subdomain.

+ +

in

+ +

Returns true if value1 equals value2 (or value3, etc., if specified).

+ +
in(value1, value2, ...)
+
+ +

value1 is the column or value to check.

+ +

value2, ... is the list of columns or values to check.

+ +

Related: contains, startsWith, endsWith.

+ +

isEmpty

+ +

Returns true if a string column contains an empty string or is null. Calling this function on a non-string column will cause an error. You can use isNull for non-string columns.

+ +

Syntax: isEmpty(column)

+ +

Example: isEmpty([Feedback]) would return true if Feedback was an empty string ('') or did not contain a value.

+ +

Related: notEmpty, isNull

+ +

integer

+ +
+

Only available for PostgreSQL.

+
+ +

Converts a string to an integer value. Useful if you want to do some math on numbers, but your data is stored as strings.

+ +

Syntax: integer(value)

+ +

Example: integer("123") would return 123 as an integer. The string must evaluate to an integer (so integer("123.45") would return an error.)

+ +

lTrim

+ +

Removes leading whitespace from a string of text.

+ +

Syntax: lTrim(text)

+ +

Example: lTrim([Comment]). If the comment were " I'd prefer not to", lTrim would return "I'd prefer not to".

+ +

Related: trim and rTrim.

+ +

length

+ +

Returns the number of characters in text.

+ +

Syntax: length(text)

+ +

Example: length([Comment]). If the comment were “wizard”, length would return 6 (“wizard” has six characters).

+ +

lower

+ +

Returns the string of text in all lower case.

+ +

Syntax: lower(text)

+ +

Example: lower([Status]). If the Status were “QUIET”, the expression would return “quiet”.

+ +

Related: upper.

+ +

notEmpty

+ +

Returns true if a string column contains a value that is not the empty string. Calling this function on a non-string column will cause an error. You can use notNull on non-string columns.

+ +

Syntax: notEmpty(column)

+ +

Example: notEmpty([Feedback]) would return true if Feedback contains a value that isn’t the empty string ('').

+ +

Related: isEmpty, isNull, notNull

+ +

path

+ +

Extracts the pathname from a URL.

+ +

Syntax: path(url)

+ +

Example: path([Page URL]). For example, path("https://www.example.com/path/to/page.html?key1=value") would return /path/to/page.html.

+ +

Related: domain, host, subdomain.

+ +

regexextract

+ +
+

⚠️ regexextract is unavailable for MongoDB, SQLite, and SQL Server. For Druid, regexextract is only available for the Druid-JDBC driver.

+
+ +

Extracts matching substrings according to a regular expression.

+ +

Syntax: regexextract(text, regular_expression)

+ +

Example: regexextract([Address], "[0-9]+")

+ +

Databases that don’t support regexextract: H2, SQL Server, SQLite.

+ +

Related: contains, doesNotContain, substring.

+ +

replace

+ +

Replaces all occurrences of a search text in the input text with the replacement text.

+ +

Syntax: replace(text, find, replace)

+ +

Example: replace([Title], "Enormous", "Gigantic")

+ +

splitPart

+ +
+

Only available on PostgreSQL.

+
+ +

Splits a string on a specified delimiter and returns the nth substring.

+ +

Syntax: splitPart(text, delimiter, position)

+ +

text: The column or text to return a portion of.

+ +

delimiter: The pattern describing where each split should occur.

+ +

position: Which substring to return after the split. Index starts at position 1.

+ +

Example: splitPart([Date string], " ", 1). If the value for Date string was "2024-09-18 16:55:15.373733-07", splitPart would return "2024-09-18" because it split the data on space (" ", and took the first part (the substring at index 1)).

+ +

Another example: splitPart("First name, Middle Name, Last name", ", ", 3) would return "Last Name" (because we used the comma and space ", " as the delimiter to split the string into parts, and took the third substring).

+ +

rTrim

+ +

Removes trailing whitespace from a string of text.

+ +

Syntax: rTrim(text)

+ +

Example: rTrim([Comment]). If the comment were “Fear is the mindkiller. “, the expression would return “Fear is the mindkiller.”

+ +

Related: trim and lTrim.

+ +

startsWith

+ +

Returns true if the beginning of the text matches the comparison text. Performs case-sensitive match by default. +You can pass an optional parameter "case-insensitive" to perform a case-insensitive match.

+ +

Syntax: startsWith(text, comparison) for case-sensitive match.

+ +

startsWith(text, comparison, "case-insensitive") for case-insensitive match.

+ +

Example: startsWith([Course Name], "Computer Science") would return true for course names that began with “Computer Science”, like “Computer Science 101: An introduction”.

+ +

It would return false for “Computer science 201: Data structures” because the case of “science” does not match the case in the comparison text.

+ +

startsWith([Course Name], "Computer Science", "case-insensitive") would return true for both “Computer Science 101: An introduction” and “Computer science 201: Data structures”.

+ +

Related: endsWith, contains, doesNotContain.

+ +

subdomain

+ +

Extracts the subdomain from a URL. Ignores www (returns a blank string).

+ +

Syntax: subdomain(url)

+ +

Example: subdomain([Page URL]). If the [Page URL] column had a value of https://status.metabase.com, subdomain([Page URL]) would return status.

+ +

Related: domain, host, path.

+ +

substring

+ +

Returns a portion of the supplied text, specified by a starting position and a length.

+ +

Syntax: substring(text, position, length)

+ +

Example: substring([Title], 1, 10) returns the first 10 letters of a string (the string index starts at position 1).

+ +

Related: regexextract, replace.

+ +

text

+ +
+

Only available for PostgreSQL.

+
+ +

Converts a number or date to text (a string). Useful for applying text filters or joining with other columns based on text comparisons.

+ +

Syntax: text(value)

+ +

Example: text(Created At]) would take a datetime (Created At) and return that datetime converted to a string (like "2024-03-17 16:55:15.373733-07").

+ +

trim

+ +

Removes leading and trailing whitespace from a string of text.

+ +

Syntax: trim(text)

+ +

Example: trim([Comment]) will remove any whitespace characters on either side of a comment.

+ +

upper

+ +

Returns the text in all upper case.

+ +

Syntax: upper(text)

+ +

Example: upper([Status]). If status were “hyper”, upper("hyper") would return “HYPER”.

+ +

Related: lower.

+ +

Date functions

+ +

Date functions manipulate, extract, or create date and time values.

+ +

convertTimezone

+ +

Shifts a date or timestamp value into a specified time zone.

+ +

Syntax: convertTimezone(column, target, source)

+ +

Example: convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Eastern") would return the value 2022-12-28T09:00:00, displayed as December 28, 2022, 9:00 AM.

+ +

See the database limitations for convertTimezone.

+ +

datetimeAdd

+ +

Adds some unit of time to a date or timestamp value.

+ +

Syntax: datetimeAdd(column, amount, unit)

+ +

Example: datetimeAdd("2021-03-25", 1, "month") would return the value 2021-04-25, displayed as April 25, 2021.

+ +

amount must be an integer, not a fractional number. For example, you cannot add “half a year” (0.5).

+ +

Related: between, datetimeSubtract.

+ +

datetimeDiff

+ +

Returns the difference between two datetimes in some unit of time. For example, datetimeDiff(d1, d2, "day") will return the number of days between d1 and d2.

+ +

Syntax: datetimeDiff(datetime1, datetime2, unit)

+ +

Example: datetimeDiff("2022-02-01", "2022-03-01", "month") would return 1.

+ +

See the database limitations for datetimediff.

+ +

datetimeSubtract

+ +

Subtracts some unit of time from a date or timestamp value.

+ +

Syntax: datetimeSubtract(column, amount, unit)

+ +

Example: datetimeSubtract("2021-03-25", 1, "month") would return the value 2021-02-25, displayed as February 25, 2021.

+ +

amount must be an integer, not a fractional number. For example, you cannot subtract “half a year” (0.5).

+ +

Related: between, datetimeAdd.

+ +

day

+ +

Takes a datetime and returns the day of the month as an integer.

+ +

Syntax: day([datetime column])

+ +

Example: day("2021-03-25T12:52:37") would return the day as an integer, 25.

+ +

dayName

+ +

Returns the localized name of a day of the week, given the day’s number (1-7). Respects the first day of the week setting.

+ +

Syntax: dayName(dayNumber)

+ +

Example: dayName(1) would return Sunday, unless you change the first day of the week setting.

+ +

Related: quarterName, monthName.

+ +

hour

+ +

Takes a datetime and returns the hour as an integer (0-23).

+ +

Syntax: hour([datetime column])

+ +

Example: hour("2021-03-25T12:52:37") would return 12.

+ +

interval

+ +

Checks a date column’s values to see if they’re within the relative range.

+ +

Syntax: interval(column, number, text)

+ +

Example: interval([Created At], -1, "month")

+ +

The number must be an integer. You cannot use a fractional value.

+ +

Related: between.

+ +

minute

+ +

Takes a datetime and returns the minute as an integer (0-59).

+ +

Syntax: minute([datetime column])

+ +

Example: minute("2021-03-25T12:52:37") would return 52.

+ +

month

+ +

Takes a datetime and returns the month number (1-12) as an integer.

+ +

Syntax: month([datetime column])

+ +

Example: month("2021-03-25T12:52:37") would return the month as an integer, 3.

+ +

monthName

+ +

Returns the localized short name for the given month.

+ +

Syntax: monthName([Birthday Month])

+ +

Example: monthName(10) would return Oct for October.

+ +

Related: dayName, quarterName.

+ +

now

+ +

Returns the current date and time using your Metabase report timezone.

+ +

Syntax: now

+ +

quarter

+ +

Takes a datetime and returns the number of the quarter in a year (1-4) as an integer.

+ +

Syntax: quarter([datetime column])

+ +

Example: quarter("2021-03-25T12:52:37") would return 1 for the first quarter.

+ +

quarterName

+ +

Given the quarter number (1-4), returns a string like Q1.

+ +

Syntax: quarterName([Fiscal Quarter])

+ +

Example: quarterName(3) would return Q3.

+ +

Related: dayName, monthName.

+ +

relativeDateTime

+ +

Gets a timestamp relative to the current time.

+ +

Syntax: relativeDateTime(number, text)

+ +

number: Period of interval, where negative values are back in time. The number must be an integer. You cannot use a fractional value.

+ +

text: Type of interval like "day", "month", "year"

+ +

relativeDateTime can only be used as part of a conditional expression.

+ +

Example: [Orders → Created At] < relativeDateTime(-30, "day") will filter for orders created over 30 days ago from current date.

+ +

Related: datetimeAdd, datetimeSubtract.

+ +

second

+ +

Takes a datetime and returns the number of seconds in the minute (0-59) as an integer.

+ +

Syntax: second([datetime column])

+ +

Example: second("2021-03-25T12:52:37") would return the integer 37.

+ +

timeSpan

+ +

Gets a time interval of specified length.

+ +

Syntax: timeSpan(number, text)

+ +

number: Period of interval, where negative values are back in time. The number must be an integer. You cannot use a fractional value.

+ +

text: Type of interval like "day", "month", "year"

+ +

Example: [Orders → Created At] + timeSpan(7, "day") will return the date 7 days after the Created At date.

+ +

week

+ +

Takes a datetime and returns the week as an integer.

+ +

Syntax: week(column, mode)

+ +

Example: week("2021-03-25T12:52:37") would return the week as an integer, 12.

+ +
    +
  • column: the name of the column of the date or datetime value.
  • +
  • mode: Optional. +
      +
    • ISO: (default) Week 1 starts on the Monday before the first Thursday of January.
    • +
    • US: Week 1 starts on Jan 1. All other weeks start on Sunday.
    • +
    • Instance: Week 1 starts on Jan 1. All other weeks start on the day defined in your Metabase localization settings.
    • +
    +
  • +
+ +

Note that summarizing by week of year in the query builder uses a different mode of determining the first week, see Week of year for more information.

+ +

weekday

+ +

Takes a datetime and returns an integer (1-7) with the number of the day of the week.

+ +

Syntax: weekday(column)

+ +
    +
  • column: The datetime column.
  • +
+ +

Example:

+ +
case(
+  weekday([Created At]) = 1, "Sunday",
+  weekday([Created At]) = 2, "Monday",
+  weekday([Created At]) = 3, "Tuesday",
+  weekday([Created At]) = 4, "Wednesday",
+  weekday([Created At]) = 5, "Thursday",
+  weekday([Created At]) = 6, "Friday",
+  weekday([Created At]) = 7, "Saturday")
+
+ +

year

+ +

Takes a datetime and returns the year as an integer.

+ +

Syntax: year([datetime column])

+ +

Example: year("2021-03-25T12:52:37") would return the year 2021 as an integer, 2,021.

+ +

Window functions

+ +

Window functions can only be used in the Summarize section. They cannot be used to create a custom column or a custom filter.

+ +

CumulativeCount

+ +

For more info, check out our page on cumulative functions.

+ +

The additive total of rows across a breakout.

+ +

Syntax: CumulativeCount

+ +

CumulativeSum

+ +

For more info, check out our page on cumulative functions.

+ +

The rolling sum of a column across a breakout.

+ +

Syntax: CumulativeSum(column)

+ +

Example: CumulativeSum([Subtotal])

+ +

Related: Sum and SumIf.

+ +

Offset

+ +
+

⚠️ The Offset function is currently unavailable for MySQL/MariaDB, MongoDB, and Druid.

+
+ +

For more info, check out our page on Offset.

+ +

Returns the value of an expression in a different row. Offset can only be used in the query builder’s Summarize step (you cannot use Offset to create a custom column).

+ +

Syntax: Offset(expression, rowOffset)

+ +

The expression is the value to get from a different row.

+ +

The rowOffset is the number relative to the current row. For example, -1 for the previous row, or 1 for the next row.

+ +

Example: Offset(Sum([Total]), -1) would get the Sum([Total]) value from the previous row.

+ +

Limitations

+ + + +

Database limitations

+ +

Limitations are noted for each aggregation and function above, and here there are in summary:

+ +

H2 (including Metabase Sample Database): Median, Percentile, convertTimezone and regexextract.

+ +

Athena: convertTimezone.

+ +

Databricks: convertTimezone.

+ +

Druid: Median, Percentile, StandardDeviation, power, log, exp, sqrt, Offset. Function regexextract is only available for the Druid-JDBC driver.

+ +

MongoDB: Median, Percentile, power, log, exp, sqrt, Offset, regexextract

+ +

MariaDB: Median, Percentile, Offset.

+ +

MySQL: Median, Percentile, Offset.

+ +

Presto: convertTimezone. Only provides approximate results for Median and Percentile.

+ +

SparkSQL: convertTimezone.

+ +

SQL Server: Median, Percentile and regexextract.

+ +

SQLite: exp, log, Median, Percentile, power, regexextract, StandardDeviation, sqrt and Variance.

+ +

Vertica: Median and Percentile.

+ +

If you’re using or maintaining a third-party database driver, please refer to the wiki to see how your driver might be impacted.

+ +

Check out our tutorial on custom expressions in the query builder to learn more.

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions.html b/_site/docs/doc-update-detection/questions/query-builder/expressions.html new file mode 100644 index 000000000..3fbeb3fde --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions.html @@ -0,0 +1,3152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Custom expressions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Custom expressions

+ +

Custom expression editor

+ +

Custom expressions are like formulas in spreadsheet software like Excel, Google Sheets, and LibreOffice Calc. They are the power tools in the query builder’s editor that allow you to ask more complicated questions.

+ +

You can also skip to the complete list of expressions.

+ +

Custom expressions to create filters, metrics, and custom columns

+ +

To use the custom expression editor, create a Custom Column (where the custom expression is used as a Field Formula to calculate values for the new column), or click on Filter or Summarize and select Custom Expression.

+ +

When using the query builder, you can use expressions to create new:

+ +
    +
  • Custom columns. You could use [Subtotal] / [Quantity] to create a new column, which you could name “Item price”.
  • +
  • Filters. The expression contains([comment], "Metabase") would filter for rows where the comment field contained the word “Metabase”.
  • +
  • Summaries. Also known as metrics or aggregations. Share([Total] > 50) would return the percentage of orders with totals greater than 50 dollars.
  • +
+ +

Type in your expression, give it a name, and click Done. If the Done button is grayed out, check that your expression is valid, and that you’ve given the expression a name (which you enter at the bottom of the expression editor).

+ +

This page covers the basics of expressions. You can check out a full list of expressions in Metabase, or walk through a tutorial that shows you how you can use custom expressions in the notebook editor.

+ +

Types of expressions

+ +

There are two basic types of expressions, Aggregations and Functions. Check out a full list of expressions.

+ +

Aggregations

+ +

Aggregations take values from multiple rows to perform a calculation, such as finding the average value from all values in a column. Aggregations functions can only be used in the Summarize section of the notebook editor, because aggregations use values from all rows for that column. So while you could create a custom column with the formula [Subtotal] + [Tax], you could not write Sum([Subtotal] + [Tax]), unless you were creating a custom metric expression (that would add up all the subtotals and taxes together).

+ +

Functions

+ +

Functions, by contrast, do something to each value in a column, like searching for a word in each value (contains), rounding each value up to the nearest integer (the ceil function), and so on.

+ +

Function browser

+ +

Function browser

+ +

The expression editor includes a function browser to help you find the function you need. To view the browser, flick on the f on the right of the expression editor. See also a list of functions and aggregations.

+ +

Auto-format

+ +

Auto-format expression

+ +

To format expressions, click on the auto-format button on the right side of the expression editor (the lightning bolt wrapped in braces).

+ +

Basic mathematical operators

+ +

Use +, -, * (multiply), / (divide) on numeric columns with numeric values, like integers, floats, and double. You can use parentheses, ( and ), to group parts of your expression.

+ +

For example, you could create a new column that calculates the difference between the total and subtotal of a order: [Total] - [Subtotal].

+ +

To do math on timestamp columns, you can use Date functions like dateDiff.

+ +

Conditional operators

+ +
    +
  • AND
  • +
  • OR
  • +
  • NOT
  • +
  • >
  • +
  • >= (greater than or equal to)
  • +
  • <
  • +
  • <= (less than or equal to)
  • +
  • =
  • +
  • != (not equal to)
  • +
+ +

For example, you could create a filter for customers from California or Vermont: [State] = "CA" OR [State] = "VT".

+ +

You can also use conditionals with the case function (alias if):

+ +
case([Size] = "L", "LARGE", [SIZE] = "M", "MEDIUM", "SMALL")
+
+ +

See case.

+ +

Referencing other columns

+ +

You can refer to columns in the current table, or to columns that are linked via a foreign key relationship. Column names should be included inside of square brackets, like this: [Name of Column]. Columns in connected tables can be referred to like this: [ConnectedTableName.Column].

+ +

Referencing Segments and Metrics

+ +

You can refer to saved metrics and segments that are present in the currently selected table. You write these out the same as with columns, like this: [Valid User Sessions].

+ +

Filter expressions and conditionals

+ +

Some things to keep in mind about filter expressions and conditionals:

+ +
    +
  • Filter expressions are different in that they must return a Boolean value (something that’s either true or false). For example, you could write [Subtotal] + [Tax] < 100. Metabase would look at each row, add its subtotal and tax, the check if that sum is greater than 100. If it is, the statement evaluates as true, and Metabase will include the row in the result. If instead you were to (incorrectly) write [Subtotal] + [Tax], Metabase wouldn’t know what to do, as that expression doesn’t evaluate to true or false.
  • +
  • You can use functions inside of the conditional portion of the CountIf and SumIf aggregations, like so: CountIf( round([Subtotal]) > 100 OR floor([Tax]) < 10 ).
  • +
+ +

Working with dates in filter expressions

+ +

If you want to work with dates in your filter expressions, the dates need to follow the format, "YYYY-MM-DD" — i.e., four characters for the year, two for the month, and two for the day, enclosed in quotes " and separated by dashes -.

+ +

Example:

+ +

between([Created At], "2020-01-01", "2020-03-31") OR [Received At] > "2019-12-25"

+ +

This expression would return rows where Created At is between January 1, 2020 and March 31, 2020, or where Received At is after December 25, 2019.

+ +

List of expressions

+ +

See a full list of expressions.

+ +

For a tutorial on expressions, see Custom expressions in the query builder.

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/case.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/case.html new file mode 100644 index 000000000..8203339f0 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/case.html @@ -0,0 +1,3670 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Case | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Case

+ +

case (alias if) checks if a value matches a list of conditions, and returns some output based on the first condition that’s met. if and case work exactly the same.

+ +

You can optionally tell case to return a default output if none of the conditions are met. If you don’t set a default output, case will return null after checking all of your conditions (null values are displayed as blank values in Metabase).

+ +

Use the case expression whenever you need to:

+ + + + + + + + + + + + + + + + + +
Syntax
case(condition1, output1, condition2, output2, ..., default_output)
Returns the output from the first condition that’s met.
+ + + + + + + + + + + + + + + +
Example
case(isempty("glass half full"), "empty glass", isnull("glass half full"), "missing glass", "glass half full")
“glass half full”
+ +

Bucketing data for frequency tables or histograms

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
AmountBucket
60-9
1810-19
3130-39
5750+
+ +

where Bucket is a custom column with the expression:

+ +
case([Amount] >= 0  AND [Amount] <=  9,  "0-9",
+     [Amount] >= 10 AND [Amount] <= 19,  "10-19",
+     [Amount] >= 20 AND [Amount] <= 29,  "20-29",
+     [Amount] >= 30 AND [Amount] <= 39,  "30-39",
+     [Amount] >= 40 AND [Amount] <= 49,  "40-49", "50+")
+
+ +

Labeling a row based on conditions from multiple columns

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sighting IDHas WingsHas FaceSighting Type
1TrueTrueBird
2TrueFalsePlane
3FalseFalseSuperman
4FalseTrueUnknown
+ +

where Sighting Type is a custom column with the expression:

+ +
case([Has Wings] = TRUE  AND [Has Face] = TRUE,  "Bird",
+     [Has Wings] = TRUE  AND [Has Face] = FALSE, "Plane",
+     [Has Wings] = FALSE AND [Has Face] = TRUE,  "Superman", "Unknown")
+
+ +

You can use the columns holding your “labels” to:

+ + + +

Aggregating data based on conditions from multiple columns

+ +

You can combine case with aggregate functions to only aggregate rows that meet your conditions.

+ +

For example, if we want to count the unique number of orders for each order date, but only those with a “Shipped” status:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Order IDOrder DateStatus
12022-04-01Paid
12022-04-03Shipped
22022-05-12Paid
22022-05-12Cancelled
+ +
    +
  1. Create the custom expression distinct(case([Status] = "Shipped", [Order ID])) and name it “Total Orders Shipped”.
  2. +
  3. Choose Order Date as the group by column.
  4. +
  5. Click Visualize to return the result:
  6. +
+ + + + + + + + + + + + + + + + + + +
Order DateTotal Orders Shipped
2022-04-011
2022-05-010
+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with case
String
Number
Timestamp
Boolean
JSON
+ +

Limitations

+ +

All of the outputs must have the same data type.

+ +

Avoid::

+ +
case(condition1, "string", condition2, TRUE, condition3, 1)
+
+ +

Do::

+ +
case(condition1, "string", condition2, "TRUE", condition3, "1")
+
+ + + +

This section covers functions and formulas that can be used interchangeably with the Metabase case expression, with notes on how to choose the best option for your use case.

+ +

Metabase expressions

+ + + +

Other tools

+ + + +

Coalesce

+ +

Using the table from the Coalesce: Consolidating values example:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NotesCommentscoalesce([Notes], [Comments] "No notes or comments.")
I have a note.I have a comment.I have a note.
 I have a comment.I have a comment.
I have a note. I have a note.
  No notes or comments.
+ +

The Metabase coalesce expression

+ +
coalesce([Notes], [Comments] "No notes or comments.")
+
+ +

is equivalent to the case expression

+ +
case(ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = FALSE, [Notes],
+     ISBLANK([Notes]) = TRUE  AND ISBLANK([Comments]) = False, [Comments],
+     ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = TRUE,  [Notes],
+     ISBLANK([Notes]) = TRUE  AND ISBLANK([Comments]) = TRUE,  "No notes or comments")
+
+ +

coalesce is much nicer to write if you don’t mind taking the first value when both of your columns are non-blank. Use case if you want to define a specific output for this case (such as, “I have a note and a comment”).

+ +

Countif

+ +

Using the table from the Aggregating data example:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Order IDOrder DateStatus
12022-04-01Paid
12022-04-03Shipped
22022-05-12Paid
22022-05-12Cancelled
+ +

The Metabase countif expression

+ +
countif(case([Status] = "Shipped"))
+
+ +

is equivalent to the case expression:

+ +
count(case([Status] = "Shipped", [Row ID]))
+
+ +

countif is equivalent to case when you are counting all rows in the table that meet your conditions. It is not equivalent if you want to count unique rows that meet your conditions.

+ +

Sumif

+ +

Using an expanded version of the table from the Aggregating data example:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Row IDOrder IDOrder DateStatusAmount
112022-04-01Paid$20
212022-04-03Shipped$20
322022-05-12Paid$80
422022-05-12Cancelled$80
+ +

The Metabase sumif expression

+ +
sumif([Amount], [Status] = "Shipped")
+
+ +

is equivalent to the case expression:

+ +
sum(case([Status] = "Shipped", [Amount]))
+
+ +

sumif is equivalent to case when you sum a single column for single condition.

+ +

You should use case if you want to sum a second column under a second, separate condition. For example, if you want to sum the Amount column when Status = “Shipped” and another (hypothetical) column like Refunded Amount when Status = “Refunded”.

+ +

SQL

+ +

In most cases (unless you’re using a NoSQL database), questions created from the notebook editor are converted into SQL queries that run against your database or data warehouse. Metabase case expressions are converted into SQL CASE WHEN statements.

+ +

Using the table from the Labeling rows example:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sighting IDHas WingsHas FaceSighting Type
1TrueTrueBird
2TrueFalsePlane
3FalseFalseSuperman
4FalseTrueUnknown
+ +

The SQL CASE WHEN statement:

+ +
SELECT
+    CASE WHEN "Has Wings" = TRUE  AND "Has Face" = TRUE  THEN "Bird"
+         WHEN "Has Wings" = TRUE  AND "Has Face" = FALSE THEN "Plane"
+         WHEN "Has Wings" = FALSE AND "Has Face" = TRUE  THEN "Superman"
+         ELSE "Unknown" END
+FROM mystery_sightings
+
+ +

is equivalent to the case expression used for Sighting Type:

+ +
case([Has Wings] = TRUE  AND [Has Face] = TRUE,  "Bird",
+     [Has Wings] = TRUE  AND [Has Face] = FALSE, "Plane",
+     [Has Wings] = FALSE AND [Has Face] = TRUE,  "Superman", "Unknown")
+
+ +

For example, this SQL trick to order bar charts could be written using a Metabase case expression instead.

+ +

Spreadsheets

+ +

Using the table from the Labeling rows example:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sighting IDHas WingsHas FaceSighting Type
1TrueTrueBird
2TrueFalsePlane
3FalseFalseSuperman
4FalseTrueUnknown
+ +

The spreadsheet formula

+ +
=IF(AND(B2 = TRUE, C2 = TRUE), "Bird",
+    IF(AND(B2 = TRUE, C2 = FALSE), "Plane",
+       IF(AND(B2 = FALSE, C2 = TRUE), "Superman", "Unknown")
+      )
+    )
+
+ +

is equivalent to the case expression used for Sighting Type:

+ +
case([Has Wings] = TRUE  AND [Has Face] = TRUE,  "Bird",
+     [Has Wings] = TRUE  AND [Has Face] = FALSE, "Plane",
+     [Has Wings] = FALSE AND [Has Face] = TRUE,  "Superman", "Unknown")
+
+ +

Python

+ +

There are many ways to implement conditional logic using Python. We’ll cover the approaches that make sense to convert into Metabase case expressions.

+ +

Using the table from the Labeling rows example (and assuming it’s in a dataframe called df):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sighting IDHas WingsHas FaceSighting Type
1TrueTrueBird
2TrueFalsePlane
3FalseFalseSuperman
4FalseTrueUnknown
+ +

numpy select()

+ +
conditions = [
+    (df["has_wings"] == True) & (df["has_face"] == True),
+    (df["has_wings"] == True) & (df["has_face"] == False),
+    (df["has_wings"] == False) & (df["has_face"] == True)]
+
+outputs = ["Bird", "Plane", "Superman"]
+
+df["Sighting Type"] = np.select(conditions, outputs, default="Unknown")
+
+ +

Helper function with pandas apply()

+ +
def Identify(df):
+    if ((df["has_wings"] == True) & (df["has_face"] == True)):
+        return "Bird"
+    elif ((df["has_wings"] == True) & (df["has_face"] == False)):
+        return "Plane"
+    elif ((df["has_wings"] == False) & (df["has_face"] == True)):
+        return "Superman"
+    else:
+        return "Unknown"
+
+df["Sighting Type"]= df.apply(Identify, axis=1)
+
+ +

The approaches above are equivalent to the case expression used for Sighting Type:

+ +
case([Has Wings] = TRUE  AND [Has Face] = TRUE,  "Bird",
+     [Has Wings] = TRUE  AND [Has Face] = FALSE, "Plane",
+     [Has Wings] = FALSE AND [Has Face] = TRUE,  "Superman", "Unknown")
+
+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/coalesce.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/coalesce.html new file mode 100644 index 000000000..9c53c6fea --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/coalesce.html @@ -0,0 +1,3350 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Coalesce | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Coalesce

+ +

coalesce looks at the values in a list (in order), and returns the first non-null value.

+ +

This function is useful when you want to:

+ + + + + + + + + + + + + + + + + + + + +
SyntaxExample
coalesce(value1, value2, …)coalesce("null", "null", "bananas", "null" …)
Returns the first non-null value from a list of values.“bananas”
+ +

Filling in empty or null values

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
left_table_colright_table_colcoalesce([right_table_col], 0)
111
2null0
3null0
444
+ +

You may want to fill in empty or null values if you have:

+ +
    +
  • Sparse data.
  • +
  • null values created by a left join (the example shown above).
  • +
+ +

For a more detailed example, see Filling in data for missing report dates.

+ +

Consolidating values from different columns

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NotesCommentscoalesce([Notes], [Comments] "No notes or comments.")
I have a note.I have a comment.I have a note.
 I have a comment.I have a comment.
I have a note. I have a note.
  No notes or comments.
+ +

Creating calculations across different columns

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SubtotalDiscountcoalesce([Subtotal], 0) - coalesce([Discount], 0)
10.000.159.85
21.00 21.00
16.001.6014.40
4.00 4.00
+ +

Calculations in Metabase will return null if any of the input columns are null. This is because null values in your data represent “missing” or “unknown” information, which isn’t necessarily the same as an amount of “0”. That is, adding 1 + “unknown” = “unknown”.

+ +

If you want to treat “unknown” values as zeroes (or some other value that means “nothing” in your data), we recommend using coalesce to wrap the columns used in your calculations.

+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with coalesce
String
Number
Timestamp
Boolean
JSON
+ +

Limitations

+ +

Use the same data types within a single coalesce function. If you want to coalesce values that have different data types:

+ + + +

If you want to use coalesce with JSON or JSONB data types, you’ll need to flatten the JSON objects first. For more information, look up the JSON functions that are available in your SQL dialect. You can find some common SQL reference guides here.

+ + + +

This section covers functions and formulas that can be used interchangeably with the Metabase coalesce expression, with notes on how to choose the best option for your use case.

+ +

Metabase expressions

+ + + +

Other tools

+ + + +

All examples use the custom expression and sample data from the Consolidating values example:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NotesCommentscoalesce([Notes], [Comments] "No notes or comments.")
I have a note.I have a comment.I have a note.
 I have a comment.I have a comment.
I have a note. I have a note.
  No notes or comments.
+ +

Case

+ +

The Metabase case expression

+ +
case(ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = FALSE, [Notes],
+     ISBLANK([Notes]) = TRUE  AND ISBLANK([Comments]) = False, [Comments],
+     ISBLANK([Notes]) = FALSE AND ISBLANK([Comments]) = TRUE,  [Notes],
+     ISBLANK([Notes]) = TRUE  AND ISBLANK([Comments]) = TRUE,  "No notes or comments")
+
+ +

is equivalent to the Metabase coalesce expression:

+ +
coalesce([Notes], [Comments] "No notes or comments.")
+
+ +

coalesce is much nicer to write if you don’t mind taking the first value when both of your columns are non-blank. Use case if you want to define a specific output (e.g., if you want to return “I have a note and a comment” instead of “I have a note”.).

+ +

SQL

+ +

In most cases (unless you’re using a NoSQL database), questions created from the notebook editor are converted into SQL queries that run against your database or data warehouse.

+ +

The SQL coalesce function

+ +
SELECT
+    COALESCE(notes, comments, "no notes or comments")
+FROM
+    sample_table;
+
+ +

is equivalent to the Metabase coalesce expression:

+ +
coalesce([Notes], [Comments] "No notes or comments.")
+
+ +

Spreadsheets

+ +

If your notes and comments table is in a spreadsheet where “Notes” is in column A, and “Comments” is in column B, then the formula

+ +
=IF(ISBLANK($A2),$B2,IF(ISBLANK($B2),$A2,"No notes or comments."))
+
+ +

is equivalent to the Metabase coalesce expression:

+ +
coalesce([Notes], [Comments] "No notes or comments.")
+
+ +

Alternatively, you may be used to working with a INDEX and MATCH in an array formula if you’re “coalescing” data across three or more columns in a spreadsheet.

+ +

Python

+ +

Assuming the notes and comments table is in a dataframe called df, the combination of pandas functions combine_first() and fillna()

+ +
df['custom_column'] = df['notes'].combine_first(df['comments'])\
+                                 .fillna('No notes or comments.')
+
+ +

are equivalent to the Metabase coalesce expression:

+ +
coalesce([Notes], [Comments] "No notes or comments.")
+
+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/concat.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/concat.html new file mode 100644 index 000000000..d12712dd7 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/concat.html @@ -0,0 +1,3211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Concat | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Concat

+ +

concat concatenates data from two or more columns or values, and returns a string.

+ +

Syntax

+ +
concat(value1, value2, ...)
+
+ +

value1, value2 … can be columns or values. Metabase will convert non-string columns into strings before concatenating their values.

+ +

Example

+ + + + + + + + + + + + + + + + + + + + + + +
ExpressionResult
concat("Vienna", "Austria")"ViennaAustria"
concat("Vienna", " is in " ,"Austria")"Vienna is in Austria"
concat([City], " is in " ,[Country])"Vienna is in Austria"
+ +

Metabase will use unformatted values for non-string columns

+ +

When you use non-string columns in concat, Metabase will ignore any formatting that you applied to the columns when converting the column to a string.

+ +

For example, if you formatted a number to display only the first two decimal digits in the table results, the results of concat would still include additional decimal digits (if any) found in the raw results.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Formatted displayValueconcat("Result:", " ", [Value])
KittenKittenResult: Kitten
1717Result: 17
31.2531.24823945Result: 31.24823945
42%0.42Result: 0.42
January 1, 20242025-02-11 21:40:27.892Result: 31.24823945
+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with concat
String
Number
Timestamp
Boolean
JSON
+ +

Non-string types will be converted to strings. Regardless of the type of the value passed to concat, the result will be a string.

+ + + +

This section covers functions and formulas that work the same way as the Metabase concat expression, with notes on how to choose the best option for your use case.

+ + + +

SQL

+ +

In most cases (unless you’re using a NoSQL database), questions created from the notebook editor are converted into SQL queries that run against your database or data warehouse.

+ +

If our sample data is stored in a relational database:

+ +
SELECT
+    CONCAT(City, ", ", Country) AS "Location"
+FROM
+    richard_linklater_films;
+
+ +

is equivalent to the Metabase concat expression:

+ +
concat([City], ", ", [Country])
+
+ +

Spreadsheets

+ +

If our sample data is in a spreadsheet where “City” is in column A, and “Country” in column B, we can create a third column “Location” like this:

+ +
=CONCATENATE(A2, ", ", B2)
+
+ +

which is equivalent to the Metabase concat expression:

+ +
concat([City], ", ", [Country])
+
+ +

Python

+ +

Assuming the sample data is in a dataframe column called df:

+ +
df["Location"] = df["City"] + ", " + df["Country"]
+
+ +

is the same as the Metabase concat expression:

+ +
concat([City], ", ", [Country])
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/converttimezone.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/converttimezone.html new file mode 100644 index 000000000..fb71bd02e --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/converttimezone.html @@ -0,0 +1,3412 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ConvertTimezone | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

ConvertTimezone

+ +

convertTimezone shifts a timestamp into a specified time zone by adding or subtracting the right interval from the timestamp.

+ + + + + + + + + + + + + + + + + + +
SyntaxExample
convertTimezone(column, target, source)convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Eastern")
Shifts a timestamp from the source time zone to the target time zone.Returns the value 2022-12-28T09:00:00, displayed as December 28, 2022 9:00 AM
+ +

Timestamps and time zones are rather nasty to work with (it’s easy to make mistakes, and difficult to catch them), so you should only try to use convertTimezone if the interpretation of your data is sensitive to time-based cutoffs.

+ +

For example, if you’re tracking user logins over time, you probably won’t run your business differently if some logins get counted on Mondays instead of Tuesdays. However, if you’re using Metabase to do something precise, like your taxes, you (and the government) will probably care a lot more about the difference between transactions that occurred on Dec 31 vs. Jan 1.

+ +

Supported time zones

+ +

Metabase supports tz database time zones.

+ +

Parameters

+ +

column can be any of:

+ +
    +
  • The name of a timestamp column,
  • +
  • a custom expression that returns a timestamp, or
  • +
  • a string in the format "YYYY-MM-DD or "YYYY-MM-DDTHH:MM:SS".
  • +
+ +

target:

+ +
    +
  • The name of the time zone you want to assign to your column.
  • +
+ +

source:

+ +
    +
  • The name of your column’s current time zone.
  • +
  • Required for columns or expressions with the data type timestamp without time zone.
  • +
  • Optional for columns or expressions with the data type timestamp with time zone.
  • +
  • For more info, see Accepted data types.
  • +
+ +

We support tz database time zone names (such as “Canada/Eastern” instead of “EST”).

+ +

Creating custom report dates

+ +

Let’s say that you have some time series data that’s stored in one or more time zones (Source Time). You want to create custom reporting dates for a team that lives in EST.

+ + + + + + + + + + + + + + + + + + + + + + +
Source TimeTeam Report Time (EST)
December 28, 2022, 10:00:00December 28, 2022, 07:00:00
December 28, 2022, 21:00:00December 28, 2022, 19:00:00
December 27, 2022, 08:00:00December 27, 2022, 05:00:00
+ +

If Source Time is stored as a timestamp with time zone or a timestamp with offset, you only need to provide the target time zone:

+ +
convertTimezone([Source Time], 'EST')
+
+ +

If Source Time is stored as a timestamp without time zone, you must provide the source time zone (which will depend on your database time zone):

+ +
convertTimezone([Source Time], 'EST', 'UTC')
+
+ +

It’s usually a good idea to label convertTimezone columns with the name of the target time zone (or add the target time zone to the metadata of a model). We promise this will make your life easier when someone inevitably asks why the numbers don’t match.

+ +

If you’re not getting the results that you expect:

+ +
    +
  • Check if you have the right source time zone.
  • +
  • Ask your database admin about timestamp with time zone vs. timestamp without time zone (for more info, see Accepted data types).
  • +
+ +

Choosing a source time zone

+ +

When you’re doing time zone conversions, make sure you know the source time zone that you’re working with. Different columns (and even different rows) in the same table, question, or model can be in different “source” time zones.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Possible source time zoneDescriptionExample
Client time zoneTime zone where an event happened.A web analytics service might capture data in the local time zone of each person who visited your website.
Database time zoneTime zone metadata that’s been added to timestamps in your database.It’s a common database practice to store all timestamps in UTC.
No time zoneMissing time zone metadataDatabases don’t require you to store timestamps with time zone metadata.
Metabase report time zoneTime zone that Metabase uses to display timestamps.Metabase can display dates and times in PST, even if the dates and times are stored as UTC in your database.
+ +

For example, say you have a table with one row for each person who visited your website. It’s hard to tell, just from looking at December 28, 2022, 12:00 PM, whether the “raw” timestamp is:

+ +
    +
  • stored using your database’s time zone (usually UTC),
  • +
  • stored without time zone metadata (for example, if the website visitor is in HKT, then the timestamp December 28, 2022, 12:00 PM might “implicitly” use Hong Kong time),
  • +
  • displayed in your Metabase report time zone.
  • +
+ +

For more gory details, see Limitations.

+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with convertTimezone
String
Number
Timestamp
Boolean
JSON
+ +

We use “timestamp” and “datetime” to talk about any temporal data type that’s supported by Metabase.

+ +

If your timestamps are stored as strings or numbers in your database, an admin can cast them to timestamps from the Table Metadata page.

+ +

To use convertTimezone without running into errors or pesky undetectable mistakes, you should know that there are a few varieties of timestamp data types:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeDescriptionExample
timestamp with time zoneKnows about location.2022-12-28T12:00:00 AT TIME ZONE 'America/Toronto'
timestamp with offsetKnows about the time difference from UTC.2022-12-28T12:00:00-04:00
timestamp without time zoneNo time zone info.2022-12-28T12:00:00
+ +

Note that the first part of the timestamp is in UTC (same thing as GMT). The time zone or offset tells you how much time to add or subtract for a given time zone.

+ +

convertTimezone will work with all three types of timestamps, but the output of convertTimezone will always be a timestamp without time zone.

+ +

Limitations

+ +

convertTimezone is currently unavailable for the following databases:

+ +
    +
  • Amazon Athena
  • +
  • Databricks
  • +
  • Druid
  • +
  • MongoDB
  • +
  • Presto
  • +
  • SparkSQL
  • +
  • SQLite
  • +
  • Metabase Sample Database
  • +
+ +

Notes on source time zones

+ +

Metabase displays timestamps without time zone or offset information, which is why you have to be so careful about the source time zone when using convertTimezone.

+ +

The Metabase report time zone only applies to timestamp with time zone or timestamp with offset data types. For example:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Raw timestamp in your databaseData typeReport time zoneDisplayed as
2022-12-28T12:00:00 AT TIME ZONE 'CST'timestamp with time zone‘Canada/Eastern’Dec 28, 2022, 7:00 AM
2022-12-28T12:00:00-06:00timestamp with offset‘Canada/Eastern’Dec 28, 2022, 7:00 AM
2022-12-28T12:00:00timestamp without time zone‘Canada/Eastern’Dec 28, 2022, 12:00 AM
+ +

The Metabase report time zone will not apply to the output of a convertTimezone expression. For example:

+ +
convertTimezone("2022-12-28T12:00:00 AT TIME ZONE 'Canada/Central'", "Canada/Pacific", "Canada/Central")
+
+ +

will produce a raw timestamp without time zone

+ +
2022-12-28T04:00:00
+
+ +

and displayed in Metabase as

+ +
Dec 28, 2022, 4:00 AM
+
+ +

If you use convertTimezone on a timestamp without time zone, make sure to use ‘UTC’ as the source time zone, otherwise the expression will shift your timestamp by the wrong amount. For example, if our timestamp without time zone is only “implied” to be in CST, we should use ‘UTC’ as the source parameter to get the same result as above.

+ +

For example, if we choose ‘CST’ as the source time zone for a timestamp without time zone:

+ +
convertTimezone("2022-12-28T12:00:00", "Canada/Pacific", "Canada/Central")
+
+ +

we’ll get the raw timestamp without time zone

+ +
2022-12-28T10:00:00
+
+ +

displayed in Metabase as

+ +
Dec 28, 2022, 10:00 AM
+
+ + + +

This section covers functions and formulas that work the same way as the Metabase convertTimezone expression, with notes on how to choose the best option for your use case.

+ + + +

SQL

+ +

When you run a question using the query builder, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results.

+ +

If our timestamp sample data is a timestamp without time zone stored in a PostgreSQL database:

+ +
SELECT source_time::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'EST' AS team_report_time_est
+
+ +

is the same as the convertTimezone expression with a source parameter set to ‘UTC’:

+ +
convertTimezone([Source Time], "Canada/Eastern", "UTC")
+
+ +

If source_time is a timestamp with time zone or timestamp with offset (for example, in a Snowflake database), then we don’t need to specify a source time zone in SQL or in Metabase.

+ +
SELECT convert_timezone('America/Toronto', source_time) AS team_report_time_est
+
+ +

is the same as

+ +
convertTimezone([Source Time], "Canada/Eastern")
+
+ +

Remember that the time zone names depend on your database. For example, Snowflake doesn’t accept most time zone abbreviations (like EST).

+ +

Spreadsheets

+ +

If our timestamp sample data is in a spreadsheet where “Source Time” is in column A, we can change it to EST by subtracting the hours explicitly:

+ +
A1 - TIME(5, 0, 0)
+
+ +

to get the same result as

+ +
convertTimezone([Client Time], "Canada/Eastern")
+
+ +

Python

+ +

If the timestamp sample data is stored in a pandas dataframe, you could convert the Source Time column to a timestamp object with time zone first(basically making a timestamp without time zone into a timestamp with time zone), then use tz_convert to change the time zone to EST:

+ +
df['Source Time (UTC)'] = pd.to_timestamp(df['Source Time'], utc=True)
+df['Team Report Time (EST)'] = df['Source Time (UTC)'].dt.tz_convert(tz='Canada/Eastern')
+
+ +

to do the same thing as a nested convertTimezone expression

+ +
convertTimezone(convertTimezone([Source Time], "UTC"), "Canada/Eastern", "UTC")
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/countif.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/countif.html new file mode 100644 index 000000000..a25748222 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/countif.html @@ -0,0 +1,3527 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CountIf | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

CountIf

+ +

CountIf counts the total number of rows in a table that match a condition. CountIf counts every row, not just unique rows.

+ +

Syntax: CountIf(condition).

+ +

Example: in the table below, CountIf([Plan] = "Basic") would return 3.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDPlan
1Basic
2Basic
3Basic
4Business
5Premium
+ +
+

Aggregations like CountIf should be added to the query builder’s Summarize menu > Custom Expression (scroll down in the menu if needed).

+
+ +

Parameters

+ +

CountIf accepts a function or conditional statement that returns a boolean value (true or false).

+ +

Multiple conditions

+ +

We’ll use the following sample data to show you CountIf with required, optional, and mixed conditions.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDPlanActive Subscription
1Basictrue
2Basictrue
3Basicfalse
4Businessfalse
5Premiumtrue
+ +

Required conditions

+ +

To count the total number of rows in a table that match multiple required conditions, combine the conditions using the AND operator:

+ +
CountIf(([Plan] = "Basic" AND [Active Subscription] = true))
+
+ +

This expression will return 2 on the sample data above (the total number of Basic plans that have an active subscription).

+ +

Optional conditions

+ +

To count the total rows in a table that match multiple optional conditions, combine the conditions using the OR operator:

+ +
CountIf(([Plan] = "Basic" OR [Active Subscription] = true))
+
+ +

Returns 4 on the sample data: there are three Basic plans, plus one Premium plan has an active subscription.

+ +

Some required and some optional conditions

+ +

To combine required and optional conditions, group the conditions using parentheses:

+ +
CountIf(([Plan] = "Basic" OR [Plan] = "Business") AND [Active Subscription] = "false")
+
+ +

Returns 2 on the sample data: there are only two Basic or Business plans that lack an active subscription.

+ +
+

Tip: make it a habit to put parentheses around your AND and OR groups to avoid making required conditions optional (or vice versa).

+
+ +

Conditional counts by group

+ +

In general, to get a conditional count for a category or group, such as the number of inactive subscriptions per plan, you’ll:

+ +
    +
  1. Write a CountIf expression with your conditions.
  2. +
  3. Add a Group by column in the query builder.
  4. +
+ +

Using the sample data:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDPlanActive Subscription
1Basictrue
2Basictrue
3Basicfalse
4Businessfalse
5Premiumtrue
+ +

Count the total number of inactive subscriptions per plan:

+ +
CountIf([Active Subscription] = false)
+
+ +

Alternatively, if your Active Subscription column contains null (empty) values that represent inactive plans, you could use:

+ +
CountIf([Payment], [Plan] != true)
+
+ +
+

The “not equal” operator != should be written as !=.

+
+ +

To view your conditional counts by plan, set the Group by column to “Plan”.

+ + + + + + + + + + + + + + + + + + + + + + +
PlanTotal Inactive Subscriptions
Basic1
Business1
Premium0
+ +
+

Tip: when sharing your work with other people, it’s helpful to use the OR filter, even though the != filter is shorter. The inclusive OR filter makes it easier to understand which categories (e.g., plans) are included in your conditional count.

+
+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with CountIf
String
Number
Timestamp
Boolean
JSON
+ +

CountIf accepts a function or conditional statement that returns a boolean value (true or false).

+ + + +

Different ways to do the same thing, because it’s fun to try new things.

+ +

Metabase

+ + + +

Other tools

+ + + +

case

+ +

You can combine Count with case:

+ +
Count(case([Plan] = "Basic", [ID]))
+
+ +

to do the same thing as CountIf:

+ +
CountIf([Plan] = "Basic")
+
+ +

The case version lets you count a different column when the condition isn’t met. For example, if you’ve got data from different sources:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID: Source APlan: Source AID: Source BPlan: Source B
1Basic  
  Bbasic
  Cbasic
4BusinessDbusiness
5PremiumEpremium
+ +

To count the total number of Basic plans across both sources, you could create a case expression to:

+ +
    +
  • Count the rows in “ID: Source A” where “Plan: Source A = “Basic”
  • +
  • Count the rows in “ID: Source B” where “Plan: Source B = “basic”
  • +
+ +
Count(case([Plan: Source A] = "Basic", [ID: Source A],
+            case([Plan: Source B] = "basic", [ID: Source B])))
+
+ +

CumulativeCount

+ +

CountIf doesn’t do running counts. You’ll need to combine CumulativeCount with case.

+ +

If our sample data is a time series:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDPlanActive SubscriptionCreated Date
1BasictrueOctober 1, 2020
2BasictrueOctober 1, 2020
3BasicfalseOctober 1, 2020
4BusinessfalseNovember 1, 2020
5PremiumtrueNovember 1, 2020
+ +

And we want to get the running count of active plans like this:

+ + + + + + + + + + + + + + + + + + +
Created Date: MonthTotal Active Plans to Date
October 20202
November 20203
+ +

Create an aggregation from Summarize > Custom expression:

+ +
CumulativeCount(case([Active Subscription] = true, [ID]))
+
+ +

You’ll also need to set the Group by column to “Created Date: Month”.

+ +

SQL

+ +

When you run a question using the query builder, Metabase will convert your query builder settings (filters, summaries, etc.) into a SQL query, and run that query against your database to get your results.

+ +

If our sample data is stored in a PostgreSQL database, the SQL query:

+ +
SELECT COUNT(CASE WHEN plan = "Basic" THEN id END) AS total_basic_plans
+FROM accounts
+
+ +

is equivalent to the Metabase expression:

+ +
CountIf([Plan] = "Basic")
+
+ +

If you want to get conditional counts broken out by group, the SQL query:

+ +
SELECT
+    plan,
+    COUNT(CASE WHEN active_subscription = false THEN id END) AS total_inactive_subscriptions
+FROM accounts
+GROUP BY
+    plan
+
+ +

The SELECT part of the SQl query matches the Metabase expression:

+ +
CountIf([Active Subscription] = false)
+
+ +

The GROUP BY part of the SQL query matches a Metabase Group by set to the “Plan” column.

+ +

Spreadsheets

+ +

If our sample data is in a spreadsheet where “ID” is in column A, the spreadsheet formula:

+ +
=CountIf(B:B, "Basic")
+
+ +

produces the same result as the Metabase expression:

+ +
CountIf([Plan] = "Basic")
+
+ +

Python

+ +

If our sample data is in a pandas dataframe column called df, the Python code:

+ +
len(df[df['Plan'] == "Basic"])
+
+ +

uses the same logic as the Metabase expression:

+ +
CountIf([Plan] = "Basic")
+
+ +

To get a conditional count with a grouping column:

+ +
## Add your conditions
+
+    df_filtered = df[df['Active subscription'] == false]
+
+## Group by a column, and count the rows within each group
+
+    len(df_filtered.groupby('Plan'))
+
+ +

The Python code above will produce the same result as the Metabase CountIf expression (with the Group by column set to “Plan”).

+ +
CountIf([Active Subscription] = false)
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/cumulative.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/cumulative.html new file mode 100644 index 000000000..d8836865b --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/cumulative.html @@ -0,0 +1,3207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Cumulative count and sum | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Cumulative count and sum

+ +

Cumulative count computes the additive total count of rows across a breakout. Cumulative sum computes the rolling sum (also known as running total) of a column across a breakout.

+ +

Syntax

+ +

You can use the predefined “Cumulative count” and “Cumulative sum” metrics, or a custom expression:

+ +
CumulativeCount
+
+ +
CumulativeSum(column)
+
+ +

Cumulative metrics can only be used in the query builder’s Summarize step — you can’t use cumulative metrics to create a custom column or filter.

+ +

How cumulative metrics are computed

+ +

Under the hood, cumulative metrics is computed in three steps:

+ +
    +
  1. Group records using the breakout from the Group by block.
  2. +
  3. Count the rows in each group.
  4. +
  5. For each group, compute the cumulative total of the counts in all previous groups, including the current group.
  6. +
+ +

Because cumulative metrics use values from previous rows, the sort order in the breakout column matters.

+ +

For example, if you have a table with data grouped by month, Metabase will compute the cumulative count like this:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthCountCumulativeCount
July55
November45+4 = 9
March25 + 4 + 2 = 11
+ +

If the sort is changed (while values remain the same), then the cumulative count changes as well:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthCountCumulativeCount
March22
July52 + 5 = 7
November42 + 5 + 4 = 11
+ +

When you have only one breakout in the query, Metabase will sort the data by the breakout column in ascending order (using the logic that your database uses for the column’s data type). To change how Metabase accumulates the metric, you can add a Sort block by the breakout column.

+ +

Cumulative metrics with multiple breakouts

+ +

Because cumulative metrics calculate their summaries based on previous rows, Metabase needs to determine what those previous rows are. Metabase will decide how to compute and display the cumulative metric first based on whether you’re grouping by a datetime column, then by the order of other breakouts:

+ +

Queries with a datetime dimension

+ +

If you use a datetime dimension in the Group by block, Metabase will accumulate along the datetime dimension, then break out by any other fields in the Group by block (in order):

+ +

Cumulative count by category, source, and created at

+ +

If there are multiple datetime dimensions (including multiple groupings by the same datetime column), Metabase will accumulate along the the more granular dimension, regardless of their order. For example, if you’re grouping by “Created At: Month” and “Viewed At: Week”, Metabase will accumulate along “Viewed At: Week”.

+ +

Cumulative count by two datetime fields

+ +

In queries with a datetime dimension, Sort blocks for non-datetime fields won’t affect how Metabase computes the results. Sort blocks will only affect the order of breakouts in the results.

+ +

Queries without datetime dimension

+ +

If there is no datetime field in the Group by block, Metabase will accumulate along the last dimension specified in the Group By block, and break out by the other fields in their order, from left to right.

+ +

Cumulative count by two categorical dimensions

+ +

By default, Metabase will use ascending sort for the dimension used for accumulation. You can add a Sort block for the accumulation dimension to change the order, which will change both how Metabase computes the cumulative metric and, how it presents the results.

+ +

Cumulative count by two categorical dimensions with order of accumulation changed

+ +

Sorting by any field other than the last (accumulation) field only affects the order of breakouts in the results. It won’t change how Metabase computes the results.

+ + + +

Cumulative count in SQL

+ +

In SQL, you can use window functions to compute cumulative metrics. For example, to compute cumulative count of orders over months, you can use the following query:

+ +
SELECT
+  created_month,
+  SUM(count(*)) OVER (
+    ORDER BY
+      created_month ASC ROWS UNBOUNDED PRECEDING
+  ) AS "sum"
+FROM
+  (
+    SELECT
+      quantity,
+      DATE_TRUNC ('month', created_at) AS created_month
+    FROM
+      orders
+  )
+GROUP BY
+  created_month
+ORDER BY
+  created_month ASC
+
+ +

Cumulative sums in SQL

+ +

For cumulative sums, you can use:

+ +
SELECT
+  created_month,
+  SUM(SUM(quantity)) OVER (
+    ORDER BY
+      created_month ASC ROWS UNBOUNDED PRECEDING
+  ) AS "sum"
+FROM
+  (
+    SELECT
+      quantity,
+      DATE_TRUNC ('month', created_at) AS created_month
+    FROM
+      orders
+  )
+GROUP BY
+  created_month
+ORDER BY
+  created_month ASC
+
+ +

You can view the SQL generated by a query in the query builder by clicking on the View the SQL (>_) button in the top right corner.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/datetimeadd.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/datetimeadd.html new file mode 100644 index 000000000..d9ef80fca --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/datetimeadd.html @@ -0,0 +1,3293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +DatetimeAdd | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

DatetimeAdd

+ +

datetimeAdd takes a datetime value and adds some unit of time to it. This function is useful when you’re working with time series data that’s marked by a “start” and an “end”, such as sessions or subscriptions data.

+ + + + + + + + + + + + + + + + + + +
SyntaxExample
datetimeAdd(column, amount, unit)datetimeAdd("2021-03-25", 1, "month")
Takes a timestamp or date value and adds the specified number of time units to it.2021-04-25
+ +

Parameters

+ +

column can be any of:

+ +
    +
  • The name of a timestamp column,
  • +
  • a custom expression that returns a datetime, or
  • +
  • a string in the format "YYYY-MM-DD" or "YYYY-MM-DDTHH:MM:SS"(as shown in the example above).
  • +
+ +

unit can be any of:

+ +
    +
  • “year”
  • +
  • “quarter”
  • +
  • “month”
  • +
  • “day”
  • +
  • “hour”
  • +
  • “minute”
  • +
  • “second”
  • +
  • “millisecond”
  • +
+ +

amount:

+ +
    +
  • An integer. You cannot use fractional values. For example, you cannot add “half a year” (0.5).
  • +
  • May be a negative number: datetimeAdd("2021-03-25", -1, "month") will return 2021-04-25.
  • +
+ +

Calculating an end date

+ +

Let’s say you’re a coffee connoisseur, and you want to keep track of the freshness of your beans:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
CoffeeOpened OnFinish By
DAK Honey DudeOctober 31, 2022November 14, 2022
NO6 Full City EspressoNovember 7, 2022November 21, 2022
Ghost Roaster GiakanjaNovember 27, 2022December 11, 2022
+ +

Here, Finish By is a custom column with the expression:

+ +
datetimeAdd([Opened On], 14, 'day')
+
+ +

Checking if the current datetime is within an interval

+ +

Let’s say you want to check if today’s date falls between a start date and an end date. Assume “today” is December 1, 2022.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CoffeeOpened OnFinish ByStill Fresh Today
DAK Honey DudeOctober 31, 2022November 14, 2022No
NO6 Full City EspressoNovember 7, 2022November 21, 2022No
Ghost Roaster GiakanjaNovember 27, 2022December 11, 2022Yes
+ +

Finish By is a custom column with the expression:

+ +
datetimeAdd([Opened On], 14, 'day')
+
+ +

Still Fresh Today uses case to check if the current date (now) is between the dates in Opened On and Finish By:

+ +
case(between(now, [Opened On], [Finish By]), "Yes", "No")
+
+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with datetimeAdd
String
Number
Timestamp
Boolean
JSON
+ +

We use “timestamp” and “datetime” to talk about any temporal data type that’s supported by Metabase. For more info about these data types in Metabase, see Timezones.

+ +

If your timestamps are stored as strings or numbers in your database, an admin can cast them to timestamps from the Table Metadata page.

+ +

Limitations

+ +

If you’re using MongoDB, datetimeAdd will only work on versions 5 and up.

+ + + +

This section covers functions and formulas that work the same way as the Metabase datetimeAdd expression, with notes on how to choose the best option for your use case.

+ +

Metabase expressions

+ + + +

Other tools

+ + + +

datetimeSubtract

+ +

datetimeSubtract and datetimeAdd are interchangeable, since you can use a negative number for amount. It’s generally a good idea to avoid double negatives (such as subtracting a negative number).

+ +
datetimeSubtract([Opened On], -14, "day")
+
+ +

does the same thing as

+ +
datetimeAdd([Opened On], 14, "day")
+
+ +

SQL

+ +

When you run a question using the query builder, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results.

+ +

If our coffee sample data is stored in a PostgreSQL database:

+ +
SELECT opened_on + INTERVAL '14 days' AS finish_by
+FROM coffee
+
+ +

is equivalent to the Metabase datetimeAdd expression:

+ +
datetimeAdd([Opened On], 14, "day")
+
+ +

Spreadsheets

+ +

If our coffee sample data is in a spreadsheet where “Opened On” is in column A with a date format, the spreadsheet function

+ +
A:A + 14
+
+ +

produces the same result as

+ +
datetimeAdd([Opened On], 14, "day")
+
+ +

Most spreadsheet tools require use different functions for different time units (for example, you’d use a different function to add “months” to a date). datetimeAdd makes it easy for you to convert all of those functions to a single consistent syntax.

+ +

Python

+ +

Assuming the coffee sample data is in a pandas dataframe column called df, you can import the datetime module and use the timedelta function:

+ +
df['Finish By'] = df['Opened On'] + datetime.timedelta(days=14)
+
+ +

is equivalent to

+ +
datetimeAdd([Opened On], 14, "day")
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/datetimediff.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/datetimediff.html new file mode 100644 index 000000000..aad41d03a --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/datetimediff.html @@ -0,0 +1,3241 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +DatetimeDiff | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

DatetimeDiff

+ +

datetimeDiff gets the amount of time between two datetime values, using the specified unit of time. Note that the difference is calculated in whole units (see the example below).

+ + + + + + + + + + + + + + + + + + +
SyntaxExample
datetimeDiff(datetime1, datetime2, unit)datetimeDiff("2022-02-01", "2022-03-01", "month")
Gets the difference between two datetimes (datetime2 minus datetime 1) using the specified unit of time.1
+ +

Parameters

+ +

datetime1 and datetime2 can be:

+ +
    +
  • The name of a timestamp column,
  • +
  • a custom expression that returns a datetime, or
  • +
  • a string in the format "YYYY-MM-DD" or "YYYY-MM-DDTHH:MM:SS" (as shown in the example above).
  • +
+ +

unit can be any of:

+ +
    +
  • “year”
  • +
  • “quarter”
  • +
  • “month”
  • +
  • “week”
  • +
  • “day”
  • +
  • “hour”
  • +
  • “minute”
  • +
  • “second”
  • +
+ +

Calculating age

+ +

Let’s say you’re a cheesemaker, and you want to keep track of your ripening process:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CheeseAging StartAging EndMature Age (Months)
ProvoloneJanuary 19, 2022March 17, 20221
FetaJanuary 25, 2022May 3, 20223
Monterey JackJanuary 27, 2022October 11, 20228
+ +

Mature Age (Months) is a custom column with the expression:

+ +
datetimeDiff([Aging Start], [Aging End], "month")
+
+ +

To calculate the current age of a cheese in months, you use now as the second datetime parameter, like this:

+ +
datetimeDiff([Aging Start], now, "month")
+
+ +

To calculate the current age of a cheese in days, you’d use:

+ +
datetimeDiff([Aging Start], now, "day")
+
+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with datetimeDiff
String
Number
Timestamp
Boolean
JSON
+ +

We use “timestamp” and “datetime” to talk about any temporal data type that’s supported by Metabase. For more info about these data types in Metabase, see Timezones.

+ +

If your timestamps are stored as strings or numbers in your database, an admin can cast them to timestamps from the Table Metadata page.

+ +

Limitations

+ +

datetimeDiff is currently unavailable for the following databases:

+ +
    +
  • Druid
  • +
+ + + +

This section covers functions and formulas that work the same way as the Metabase datetimeDiff expression, with notes on how to choose the best option for your use case.

+ + + +

SQL

+ +

When you run a question using the query builder, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results.

+ +

If our cheese sample data is stored in a PostgreSQL database:

+ +
SELECT DATE_PART('month', AGE(aging_end, aging_start)) AS mature_age_months
+FROM cheese
+
+ +

is equivalent to the Metabase datetimeDiff expression:

+ +
datetimeDiff([Aging Start], [Aging End], "month")
+
+ +

Some databases, such as Snowflake and BigQuery, support functions like DATEDIFF or DATE_DIFF. For more info, check out our list of common SQL reference guides.

+ +

Spreadsheets

+ +

If our cheese sample data is in a spreadsheet where “Aging Start” is in column B and “Aging End” is in column C:

+ +
DATEDIF(B1, C1, "M")
+
+ +

produces the same result as

+ +
datetimeDiff([Aging Start], [Aging End], "month")
+
+ +

Yes, DATEDIF looks a bit wrong, but the spreadsheet function really is DATEDIF() with one “f”, not DATEDIFF().

+ +

Python

+ +

Assuming the cheese sample data is in a pandas dataframe column called df, you can subtract the dates directly and use numpy’s timedelta64 to convert the difference to months:

+ +
df['Mature Age (Months)'] = (df['Aging End'] - df['Aging Start']) / np.timedelta64(1, 'M')
+
+ +

is equivalent to

+ +
datetimeDiff([Aging Start], [Aging End], "month")
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/datetimesubtract.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/datetimesubtract.html new file mode 100644 index 000000000..b7439b2e9 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/datetimesubtract.html @@ -0,0 +1,3293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +DatetimeSubtract | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

DatetimeSubtract

+ +

datetimeSubtract takes a datetime value and subtracts some unit of time from it. You might want to use this function when working with time series data that’s marked by a “start” and an “end”, such as sessions or subscriptions data.

+ + + + + + + + + + + + + + + + + + +
SyntaxExample
datetimeSubtract(column, amount, unit)datetimeSubtract("2021-03-25", 1, "month")
Takes a timestamp or date value and subtracts the specified number of time units from it.2021-02-25
+ +

Parameters

+ +

column can be any of:

+ +
    +
  • The name of a timestamp column,
  • +
  • a custom expression that returns a datetime, or
  • +
  • a string in the format "YYYY-MM-DD" or "YYYY-MM-DDTHH:MM:SS" (as shown in the example above).
  • +
+ +

unit can be any of:

+ +
    +
  • “year”
  • +
  • “quarter”
  • +
  • “month”
  • +
  • “day”
  • +
  • “hour”
  • +
  • “minute”
  • +
  • “second”
  • +
  • “millisecond”
  • +
+ +

amount:

+ +
    +
  • An integer. You cannot use fractional values. For example, you cannot subtract “half a year” (0.5).
  • +
  • May be a negative number: datetimeSubtract("2021-03-25", -1, "month") will return 2021-04-25.
  • +
+ +

Calculating a start date

+ +

Let’s say you’re planning a fun night out. You know it takes 30 minutes to get from place to place, and you need to figure out what time you have to leave to get to each of your reservations:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
EventArrive ByDepart At
DrinksNovember 12, 2022 6:30 PMNovember 12, 2022 6:00 PM
DinnerNovember 12, 2022 8:00 PMNovember 12, 2022 7:30 PM
DancingNovember 13, 2022 12:00 AMNovember 12, 2022 11:30 PM
+ +

Here, Depart At is a custom column with the expression:

+ +
datetimeSubtract([Arrive By], 30, "minute")
+
+ +

Checking if the current datetime is within an interval

+ +

Say you want to check if the current datetime falls between a start date and an end date. Assume the “current” datetime is November 12, 7:45 PM.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EventArrive ByDepart AtOn My Way
DrinksNovember 12, 2022 6:30 PMNovember 12, 2022 6:00 PMNo
DinnerNovember 12, 2022 8:00 PMNovember 12, 2022 7:30 PMYes
DancingNovember 13, 2022 12:00 AMNovember 12, 2022 11:30 PMNo
+ +

Depart At is a custom column with the expression:

+ +
datetimeSubtract([Arrive By], 30, "minute")
+
+ +

On My Way uses case to check if the current datetime (now) is between the datetimes in Arrive By and Depart At:

+ +
case(between(now, [Depart At], [Arrive By]), "Yes", "No")
+
+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with datetimeSubtract
String
Number
Timestamp
Boolean
JSON
+ +

We use “timestamp” and “datetime” to talk about any temporal data type that’s supported by Metabase. For more info about these data types in Metabase, see Timezones.

+ +

If your timestamps are stored as strings or numbers in your database, an admin can cast them to timestamps from the Table Metadata page.

+ +

Limitations

+ +

If you’re using MongoDB, datetimeSubtract will only work on versions 5 and up.

+ + + +

This section covers functions and formulas that work the same way as the Metabase datetimeSubtract expression, with notes on how to choose the best option for your use case.

+ +

Metabase expressions

+ + + +

Other tools

+ + + +

datetimeAdd

+ +

datetimeSubtract and datetimeAdd are interchangeable, since you can use a negative number for amount. We could use either expression for our events example, but you should try to avoid “double negatives” (such as subtracting a negative number).

+ +
datetimeAdd([Arrive By], -30, "minute")
+
+ +

does the same thing as

+ +
datetimeSubtract([Arrive By], 30, "minute")
+
+ +

SQL

+ +

When you run a question using the query builder, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results.

+ +

If our events sample data is stored in a PostgreSQL database:

+ +
SELECT arrive_by - INTERVAL '30 minutes' AS depart_at
+FROM events
+
+ +

is equivalent to the Metabase datetimeSubtract expression:

+ +
datetimeSubtract([Arrive By], 30, "minute")
+
+ +

Spreadsheets

+ +

Assuming the events sample data is in a spreadsheet where “Arrive By” is in column A with a datetime format, the spreadsheet function

+ +
A:A - 30/(60*24)
+
+ +

produces the same result as

+ +
datetimeSubtract([Arrive By], 30, "minute")
+
+ +

Most spreadsheets require you to use different calculations for different time units (for example, you’d need to use a different calculation to subtract “days” from a date). datetimeSubtract makes it easy for you to convert all of those functions to a single consistent syntax.

+ +

Python

+ +

If our events sample data is in a pandas dataframe column called df, you can import the datetime module and use the timedelta function:

+ +
df['Depart At'] = df['Arrive By'] - datetime.timedelta(minutes=30)
+
+ +

is equivalent to

+ +
datetimeSubtract([Arrive By], 30, "minute")
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/in.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/in.html new file mode 100644 index 000000000..cd07d0c95 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/in.html @@ -0,0 +1,3116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +In | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

In

+ +

in compares values and returns true if value1 equals value2 (OR value3, etc., if specified).

+ +

Syntax

+ +
in(value1, value2, ...)
+
+ +

value1 is the column or value to check.

+ +

value2, ... is the list of columns or values to check.

+ +

Metabase will return rows where the value1 equals value2 OR value3, etc. Matches must be exact (e.g., strings are case sensitive).

+ +

For example,

+ +
in([Category], "Gadget", "Widget")
+
+

would return rows where [Category] is either Gadget or Widget.

+ +

You can choose multiple columns. For example, let’s say you wanted to find records where [Title] or [Category] fields are equal to Gadget. You could write:

+ +
in("Gadget", [Title], [Category])
+
+ + + +

SQL

+ +

in works like SQL’s in function.

+ +

So if you have the expression: in[title], "Lightweight Wool Computer", "Aerodynamic Cotton Lamp"), in SQL, it would be:

+ +
title IN ('Lightweight Wool Computer', 'Aerodynamic Cotton Lamp')
+
+ +

But under the hood, Metabase translates this IN expression to a WHERE clause that uses the OR operator:

+ +
WHERE
+  title = 'Lightweight Wool Computer'
+  OR title = 'Aerodynamic Cotton Lamp'
+
+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with in
String
Number
Timestamp
Boolean
JSON
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/isempty.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/isempty.html new file mode 100644 index 000000000..398b5f22e --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/isempty.html @@ -0,0 +1,3247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Isempty | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Isempty

+ +

isempty checks whether a value in a string column is an empty string ("") or null. Calling isempty on a non-string column would cause an error.

+ +

Syntax

+ +
isempty(text column)
+
+ +

You can use isempty in custom filters, or as the condition for conditional aggregations CountIf and SumIf. To create a custom column using isempty, you must combine isempty with another function that accepts boolean values, like case.

+ +

How Metabase handles empty strings and null values

+ +

In Metabase, columns with string data types will display blank cells for empty strings, strings of whitespace characters, or null values (if the column is nullable in your database). +The table below shows you examples of the output of isempty.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Metabase showsDatabase valueisempty(value)
 nulltrue
 "" (empty string)true
 " " (whitespace)false
kitten"kitten"false
+ +

Creating a boolean custom column

+ +

To create a custom column using isempty, you must combine isempty with another function. +For example, if you want to create a custom column that contains true when the Feedback column is empty or null, and false otherwise, you can use the case expression :

+ +
case(isempty([Feedback]), true, false)
+
+ +

Replacing empty strings with another value

+ +

You can combine isempty with the case expression to replace empty strings with something more descriptive.

+ +

For example, you can create a new custom column that will contain "No feedback" when the original [Feedback] column is empty or null, and the feedback value when [Feedback] is has a non-empty value. The custom expression to do it is:

+ +
case(isempty([Feedback]), "No feedback.", [Feedback])
+
+ + + + + + + + + + + + + + + + + + + + + + +
Feedbackcase(isempty([Feedback]), "No feedback.", [Feedback])
"""No feedback."
null"No feedback."
"I like your style.""I like your style."
+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with isempty
String
Number
Timestamp
Boolean
JSON
+ +

Limitations

+ +
    +
  • To create a custom column you must combine isempty with another expression that accepts boolean arguments (i.e., true or false).
  • +
  • isempty only accepts one value at a time. If you need to deal with empty strings from multiple columns, you’ll need to use multiple isempty expressions with the case expression.
  • +
+ + + +

This section covers functions and formulas that can be used interchangeably with the Metabase isempty expression, with notes on how to choose the best option for your use case.

+ + + +

All examples below use the table from the Replacing empty strings example:

+ + + + + + + + + + + + + + + + + + + + + + +
Feedbackcase(isempty([Feedback]), "No feedback.", [Feedback])
"""No feedback."
null"No feedback."
"I like your style.""I like your style."
+ +

SQL

+ +

In most cases (unless you’re using a NoSQL database), questions created from the query builder are converted into SQL queries that run against your database or data warehouse.

+ +
CASE WHEN (Feedback = "" OR Feedback IS NULL) THEN "No feedback"
+     ELSE Feedback END
+
+ +

is equivalent to the Metabase isempty expression:

+ +
case(isempty([Feedback]), "No feedback.", [Feedback])
+
+ +

Spreadsheets

+ +

If our sample feedback column is in a spreadsheet where “Feedback” is in column A, then the formula

+ +
=IF(A2 = "", "Unknown feedback.", A2)
+
+ +

is equivalent to the Metabase isempty expression:

+ +
case(isempty([Feedback]), "No feedback.", [Feedback])
+
+ +

Python

+ +

Assuming the sample feedback column is in a dataframe column called df["Feedback"]:

+ +
df["Custom Column"] = np.where((df["Feedback"] == "") | (df["Feedback"].isnull()), "No feedback.", df["Feedback"])
+
+ +

is equivalent to the Metabase isempty expression:

+ +
case(isempty([Feedback]), "No feedback.", [Feedback])
+
+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/isnull.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/isnull.html new file mode 100644 index 000000000..1b52a2835 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/isnull.html @@ -0,0 +1,3255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Isnull | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Isnull

+ +

isnull checks if a value is a null, a special kind of placeholder that’s used by a database when something is missing or unknown.

+ +

Syntax

+ +
isnull(text column)
+
+ +

You can use isnull in custom filters, or as the condition for conditional aggregations CountIf and SumIf. To create a custom column using isnull, you must combine isnull with another function that accepts boolean values, like case.

+ +

How Metabase handles nulls

+ +

In Metabase tables, nulls are displayed as blank cells. Additionally, for string columns, empty strings and strings containing only whitespace characters will be displayed as blank as well.

+ +

The table below shows you examples of the output of isnull.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Metabase showsDatabase valueisnull(value)
 nulltrue
 "" (empty string)false*
 " " (whitespace)false
kitten"kitten"false
+ +

*In Oracle and Vertica databases, empty strings are treated as nulls instead.

+ +

Creating a boolean custom column

+ +

To create a custom column using isnull, you must combine isnull with another function. +For example, if you want to create a custom column that contains true when the Discount column is null, and false otherwise, you can use the case expression :

+ +
case(isnull([Discount]), true, false)
+
+ +

Replacing null values with another value

+ +

Combine isnull with the case expression to replace missing information with something more descriptive:

+ +

For example, you can create a new custom column that will contain "Unknown feedback" when the original [Feedback] column is null, and the actual feedback value when [Feedback] is has a value. The custom expression to do it is:

+ +
case(isnull([Feedback]), "Unknown feedback.", [Feedback])
+
+ + + + + + + + + + + + + + + + + + + + + + +
Feedbackcase(isnull([Feedback]), "Unknown feedback.", [Feedback])
null"Unknown feedback."
""""
"I like your style.""I like your style."
+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with isnull
String
Number
Timestamp
Boolean
JSON
+ +

Limitations

+ +
    +
  • In Metabase, you must combine isnull with another expression that accepts boolean arguments (i.e., true or false).
  • +
  • isnull only accepts one value at a time. If you need to deal with blank cells across multiple columns, see the coalesce expression.
  • +
  • If isnull doesn’t seem to do anything to your blank cells, you might have empty strings. Try the isempty expression instead.
  • +
+ + + +

This section covers functions and formulas that can be used interchangeably with the Metabase isnull expression, with notes on how to choose the best option for your use case.

+ + + +

All examples below use the table from the Replacing null values example:

+ + + + + + + + + + + + + + + + + + + + + + +
Feedbackcase(isnull([Feedback]), "Unknown feedback.", [Feedback])
null"Unknown feedback."
""""
"I like your style.""I like your style."
+ +

SQL

+ +

In most cases (unless you’re using a NoSQL database), questions created from the query builder are converted into SQL queries that run against your database or data warehouse.

+ +
CASE WHEN Feedback IS NULL THEN "Unknown feedback",
+     ELSE Feedback END
+
+ +

is equivalent to the Metabase isnull expression:

+ +
case(isnull([Feedback]), "Unknown feedback.", [Feedback])
+
+ +

Spreadsheets

+ +

Spreadsheet #N/As are the equivalent of database nulls (placeholders for “unknown” or “missing” information).

+ +

Assuming our sample feedback column is in a spreadsheet where “Feedback” is in column A, then the formula

+ +
=IF(ISNA(A2), "Unknown feedback.", A2)
+
+ +

is equivalent to the Metabase isnull expression:

+ +
case(isnull([Feedback]), "Unknown feedback.", [Feedback])
+
+ +

Python

+ +

Numpy and pandas use NaNs or NAs instead of nulls.

+ +

Assuming our sample feedback column is in a dataframe column called df["Feedback"]:

+ +
df["Custom Column"] = np.where(df["Feedback"].isnull(), "Unknown feedback.", df["Feedback"])
+
+ +

is equivalent to the Metabase isnull expression:

+ +
case(isnull([Feedback]), "Unknown feedback.", [Feedback])
+
+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/now.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/now.html new file mode 100644 index 000000000..6d1ab06ed --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/now.html @@ -0,0 +1,3188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Now | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Now

+ +

now returns the current datetime using your Metabase report timezone.

+ +

Creating conditional logic using the current date or time

+ +

Let’s say you have some project data, and you want to add a status column for each task. We’ll assume today’s date and time is November 22, 2022, 12:00:00.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TaskStartDeadlineStatus
DraftNovember 1, 2022, 12:00:00November 30, 2022, 12:00:00In progress
ReviewNovember 15, 2022, 12:00:00November 19, 2022, 12:00:00Needs extension
EditNovember 22, 2022, 12:00:00November 22, 2022, 12:00:00DUE RIGHT NOW!
+ +

To mark a task in progress, you’d use the expression:

+ +
now >= [Start] AND now < [Deadline]
+
+ +

To check if you need to ask for an extension:

+ +
now >= [Start] AND now >= [Deadline]
+
+ +

If you’re looking for an adrenaline rush (and you have real-time data), you can flag the tasks that are due right this second:

+ +
now = [Deadline]
+
+ +

To set up the Status column that combines all three situations above, you’d wrap everything in a case expression:

+ +
case(now >= [Start] AND now < [Deadline], "In progress",
+     now >= [Start] AND now >= [Deadline], "Needs extension",
+     now = [Deadline], "DUE RIGHT NOW!")
+
+ +

Data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeReturned by now
String
Number
Timestamp
Boolean
JSON
+ +

now returns a timestamp with time zone if time zones are supported by your database, otherwise now returns a timestamp without time zone.

+ +

For more info about the way these data types behave in Metabase, see Timezones.

+ +

Limitations

+ +

now might not actually be now (in your local time) if you don’t live in the same timezone as your Metabase report time zone.

+ +

If you need to compare now to a column in a different time zone, use convertTimezone to shift both columns into the same time zone. For example:

+ +
convertTimezone(now, 'UTC', <report timezone>) >= convertTimezone([Deadline], 'UTC', <source time zone>)
+
+ + + +

Different ways to do the same thing, because while you’d love to use custom expressions more, now’s just not the time.

+ + + +

SQL

+ +

When you run a question using the query builder, Metabase will convert your query builder settings (filters, summaries, etc.) into a SQL query, and run that query against your database to get your results.

+ +

By default, now uses your Metabase’s report time zone. If your admin hasn’t set a report time zone, now will use your database’s time zone.

+ +

Say you’re using a Postgres database. If your Metabase report time zone is set to EST, you’ll get now in EST:

+ +
SELECT CURRENT_TIMESTAMP AT TIME ZONE 'EST'
+
+ +

If you don’t have a report time zone, you’ll get now in the Postgres database’s time zone (typically UTC):

+ +
SELECT CURRENT_TIME
+
+ +

Spreadsheets

+ +

The spreadsheet function NOW() gets the current date and time in your operating system’s time zone (the time that’s on your computer or mobile device).

+ +

Python

+ +

You can use pd.Timestamp.now() using the pandas module. This will give you a Timestamp object with the current date and time in your operating system’s time zone.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/offset.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/offset.html new file mode 100644 index 000000000..fd102c029 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/offset.html @@ -0,0 +1,3212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Offset | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Offset

+ +
+

⚠️ The Offset function is currently unavailable for MySQL/MariaDB, MongoDB, and Druid.

+
+ +

The Offset function returns the value of an expression in a different row. Offset can only be used in the query builder’s Summarize step (you cannot use Offset to create a custom column).

+ +

Syntax: Offset(expression, rowOffset)

+ +

The expression is the value to get from a different row.

+ +

The rowOffset is the number relative to the current row. For example, -1 for the previous row, or 1 for the next row.

+ +

Example: Offset(Sum([Total]), -1) would get the value of Sum([Total]) from the previous row.

+ +

The order of the breakouts matter

+ +

Because Offset refers to other rows, the order of the breakouts matters (the breakouts are the groups in the “Group By” section in the Summarization step). Metabase will sort by the first group, then partition by any additional breakouts. For example, if you want to see the counts of orders by product category over time, and the counts by product category for the previous period, you should first group by Created At, then by the product category.

+ +

Offset doesn’t account for missing data

+ +

Offset can only reference the rows you have, which means it can produce correct but unexpected results. For example, let’s say you want to compare each day’s count to the previous day.

+ +

Take the following table, where the Previous column is created by the expression Offset(Count, -1):

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DateCountPrevious
1-Oct-226 
2-Oct-2236
4-Oct-2223
+ +

The value in the Previous column for October 4th is 3, which is the value of the previous row. While correct based on the data, the previous row is October 2nd; there’s no data for the previous day, October 3rd. If you want to use offset to compare previous days (or weeks, or whatever), you need to make sure that your data includes a row for each data point you want to compare. In this case, your data would need to include a row for each day, including days where the count was zero. If you’re missing dates in your data, you could join a calendar table to your data to make sure that each day has a row in your data.

+ +

Data types

+ +

The Offset function returns whatever value is in the offset row.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeReturned by Offset
String
Number
Timestamp
Boolean
JSON
+ +

Example year-over-year (YoY) time series comparison using Offset

+ +

In the Sample database, you can use Offset to compare the count of orders year over year (YoY).

+ +

First, summarize by Sum of Total. Then summarize that summation again, this time using Offset to grab the previous row’s value.

+ +
Offset(Sum([Total]), -1)
+
+ +

Then group the results by Created At by year:

+ +

Comparing year over year

+ +

Which yields:

+ +

Year over year order sum of order totals

+ +

With these offsets (the Sums in the “Previous period” column), we can then create custom columns to calculate things like the difference between yearly Sums:

+ +
[Sum of total] - [Previous period]
+
+ +

And the percentage change year to year:

+ +
[Difference] / [Previous period] * 100
+
+ +

Difference and percentage change

+ +

Example rolling average using Offset

+ +

You can use a custom expression with Offset to calculate rolling averages.

+ +

For example, let’s say you want to calculate the rolling average sum of order totals over the past three months. You could create a custom expression to calculate these rolling averages:

+ +
(Sum([Total]) + Offset(Sum([Total]), -1) + Offset(Sum([Total]), -2)) / 3
+
+ +

The above expression adds up this period’s total, plus the totals for the previous two periods (offset by -1 and -2), and then divides by three to get the average across those periods.

+ +

Rolling average

+ + + +

SQL

+ +

The Offset function compares with SQL’s LAG and LEAD window functions.

+ +

For example, if you’re trying to create a line chart with two series to compare a) this month’s order counts with b) the previous month’s order counts, you’d count the orders for this month, then use an offset expression to count the previous month’s orders, like so:

+ +
Offset(count, -1)
+
+ +

Under the hood, Metabase will translate that Offset expression into a LAG window function, like in this query:

+ +
SELECT
+  "source"."CREATED_AT" AS "CREATED_AT",
+  COUNT(*) AS "count",
+  LAG(COUNT(*), 1) OVER (
+
+ORDER BY
+      "source"."CREATED_AT" ASC
+  ) AS "Order count previous period"
+FROM
+  (
+    SELECT
+      DATE_TRUNC('month', "PUBLIC"."ORDERS"."CREATED_AT") AS "CREATED_AT"
+    FROM
+      "PUBLIC"."ORDERS"
+  ) AS "source"
+GROUP BY
+  "source"."CREATED_AT"
+ORDER BY
+  "source"."CREATED_AT" ASC
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/regexextract.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/regexextract.html new file mode 100644 index 000000000..87b33c4e2 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/regexextract.html @@ -0,0 +1,3233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Regexextract | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Regexextract

+ +
+

⚠️ regexextract is unavailable for MongoDB, SQLite, and SQL Server. For Druid, regexextract is only available for the Druid-JDBC driver.

+
+ +

regexextract uses regular expressions (regex) to get a specific part of your text.

+ +

regexextract is ideal for text that has little to no structure, like URLs or freeform survey responses. If you’re working with strings in predictable formats like SKU numbers, IDs, or other types of codes, check out the simpler substring expression instead.

+ +

Use regexextract to create custom columns with shorter, more readable labels for things like:

+ +
    +
  • filter dropdown menus,
  • +
  • chart labels, or
  • +
  • embedding parameters.
  • +
+ + + + + + + + + + + + + + + + + + +
SyntaxExample
regexextract(text, regular_expression)regexextract("regexextract", "ex(.*)")
Gets a specific part of your text using a regular expression.“extract”
+ +

Searching and cleaning text

+ +

Let’s say that you have web data with a lot of different URLs, and you want to map each URL to a shorter, more readable campaign name.

+ + + + + + + + + + + + + + + + + + + + + + +
URLCampaign Name
https://www.metabase.com/docs/?utm_campaign=alicealice
https://www.metabase.com/learn/?utm_campaign=neoneo
https://www.metabase.com/glossary/?utm_campaign=candycandy
+ +

You can create a custom column Campaign Name with the expression:

+ +
regexextract([URL], "^[^?#]+\?utm_campaign=(.*)")
+
+ +

Here, the regex pattern ^[^?#]+\? matches all valid URL strings. You can replace utm_campaign= with whatever query parameter you like. At the end of the regex pattern, the capturing group (.*) gets all of the characters that appear after the query parameter utm_campaign=.

+ +

Now, you can use Campaign Name in places where you need clean labels, such as filter dropdown menus, charts, and embedding parameters.

+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with regexextract
String
Number
Timestamp
Boolean
JSON
+ +

Limitations

+ +

regexextract is unavailable for MongoDB, SQLite, and SQL Server. For Druid, regexextract is only available for the Druid-JDBC driver.

+ +

Regex can be a dark art. You have been warned.

+ + + +

This section covers functions and formulas that work the same way as the Metabase regexextract expression, with notes on how to choose the best option for your use case.

+ +

Metabase expressions

+ + + +

Other tools

+ + + +

Substring

+ +

Use substring when you want to search text that has a consistent format (the same number of characters, and the same relative order of those characters).

+ +

For example, you wouldn’t be able to use substring to get the query parameter from the URL sample data, because the URL paths and the parameter names both have variable lengths.

+ +

But if you wanted to pull out everything after https://www. and before .com, you could do that with either:

+ +
substring([URL], 13, 8)
+
+ +

or

+ +
regexextract([URL], "^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/.\n]+)")
+
+ +

SQL

+ +

When you run a question using the notebook editor, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results.

+ +

If our sample data is stored in a PostgreSQL database:

+ +
SELECT
+    url,
+    SUBSTRING(url, '^[^?#]+\?utm_campaign=(.*)') AS campaign_name
+FROM follow_the_white_rabbit
+
+ +

is equivalent to the Metabase regexextract expression:

+ +
regexextract([URL], "^[^?#]+\?utm_campaign=(.*)")
+
+ +

Spreadsheets

+ +

If our sample data is in a spreadsheet where “URL” is in column A, the spreadsheet function

+ +
regexextract(A2, "^[^?#]+\?utm_campaign=(.*)")
+
+ +

uses pretty much the same syntax as the Metabase expression:

+ +
regexextract([URL], "^[^?#]+\?utm_campaign=(.*)")
+
+ +

Python

+ +

Assuming the sample data is in a dataframe column called df,

+ +
df['Campaign Name'] = df['URL'].str.extract(r'^[^?#]+\?utm_campaign=(.*)')
+
+ +

does the same thing as the Metabase regexextract expression:

+ +
regexextract([URL], "^[^?#]+\?utm_campaign=(.*)")
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/substring.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/substring.html new file mode 100644 index 000000000..19285adfd --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/substring.html @@ -0,0 +1,3256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Substring | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Substring

+ +

substring extracts part of some text. This function is useful for cleaning up text (or any value with a string data type) that has a consistent format.

+ +

For example, substring should work well on strings like SKU numbers, ISO codes, and standardized email addresses.

+ + + + + + + + + + + + + + + + + + +
SyntaxExample
substring(text, position, length)substring("user_id@email.com", 1, 7)
Extracts part of the text given a starting point (position) and a length (number of characters).“user_id”
+ +

Parameters

+ +
    +
  • The first character in your string is at position 1.
  • +
  • The length of your substring should always be a positive number.
  • +
+ +

Getting a substring from the left

+ + + + + + + + + + + + + + + + + + + + + + +
Mission IDAgent
19951113006006
20061114007007
19640917008008
+ +

Agent is a custom column with the expression:

+ +
substring([Mission ID], 9, 3)
+
+ +

Getting a substring from the right

+ +

Instead of using a number for the position, you’ll use the formula

+ +
1 + length([column]) - position_from_right
+
+ +

where position_from_right is the number of characters you want to count from right to left.

+ + + + + + + + + + + + + + + + + + + + + + +
Mission IDAgent
19951113006006
20061114007007
19640917008008
+ +

Here, Agent is a custom column with the expression:

+ +
substring([Mission ID], (1 + length([Mission ID]) - 3), 3)
+
+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with substring
String
Number
Timestamp
Boolean
JSON
+ +

Limitations

+ +

substring extracts text by counting a fixed number of characters. If you need to extract text based on some more complicated logic, try regexextract.

+ +

And if you only need to clean up extra whitespace around your text, you can use the trim, ltrim, or rtrim expressions instead.

+ + + +

This section covers functions and formulas that work the same way as the Metabase substring expression, with notes on how to choose the best option for your use case.

+ +

Metabase expressions

+ + + +

Other tools

+ + + +

Regexextract

+ +

Use regexextract if you need to extract text based on more specific rules. For example, you could get the agent ID with a regex pattern that finds the last occurrence of “00” (and everything after it):

+ +
regexextract([Mission ID], ".+(00.+)$")
+
+ +

should return the same result as

+ +
substring([Mission ID], 9, 3)
+
+ +

SQL

+ +

When you run a question using the notebook editor, Metabase will convert your graphical query settings (filters, summaries, etc.) into a query, and run that query against your database to get your results.

+ +

If our sample data is stored in a PostgreSQL database:

+ +
SELECT
+    mission_id,
+    SUBSTRING(mission_id, 9, 3) AS agent
+FROM
+    this_message_will_self_destruct;
+
+ +

is equivalent to the Metabase substring expression:

+ +
substring([Mission ID], 9, 3)
+
+ +

Spreadsheets

+ +

If our sample data is in a spreadsheet where “Mission ID” is in column A,

+ +
=mid(A2,9,3)
+
+ +

is the same as the Metabase substring expression:

+ +
substring([Mission ID], 9, 3)
+
+ +

Python

+ +

Assuming the sample data is in a dataframe column called df,

+ +
df['Agent'] = df['Mission ID'].str.slice(8, 11)
+
+ +

does the same thing as the Metabase substring expression:

+ +
substring([Mission ID], 9, 3)
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/sumif.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/sumif.html new file mode 100644 index 000000000..ba3c04c8b --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/sumif.html @@ -0,0 +1,3446 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SumIf | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

SumIf

+ +

SumIf adds up the values in a column based on a condition.

+ +

Syntax: SumIf(column, condition).

+ +

Example: in the table below, SumIf([Payment], [Plan] = "Basic") would return 200.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PaymentPlan
100Basic
100Basic
200Business
200Business
400Premium
+ +
+

Aggregation formulas like sumif should be added to the query builder’s Summarize menu > Custom Expression (scroll down in the menu if needed).

+
+ +

Parameters

+ +
    +
  • column can be the name of a numeric column, or a function that returns a numeric column.
  • +
  • condition is a function or conditional statement that returns a boolean value (true or false), like the conditional statement [Payment] > 100.
  • +
+ +

Multiple conditions

+ +

We’ll use the following sample data to show you SumIf with required, optional, and mixed conditions.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PaymentPlanDate Received
100BasicOctober 1, 2020
100BasicOctober 1, 2020
200BusinessOctober 1, 2020
200BusinessNovember 1, 2020
400PremiumNovember 1, 2020
+ +

Required conditions

+ +

To sum a column based on multiple required conditions, combine the conditions using the AND operator:

+ +
SumIf([Payment], ([Plan] = "Basic" AND month([Date Received]) = 10))
+
+ +

This expression would return 200 on the sample data above: the sum of all of the payments received for Basic Plans in October.

+ +

Optional conditions

+ +

To sum a column with multiple optional conditions, combine the conditions using the OR operator:

+ +
SumIf([Payment], ([Plan] = "Basic" OR [Plan] = "Business"))
+
+ +

Returns 600 on the sample data.

+ +

Some required and some optional conditions

+ +

To combine required and optional conditions, group the conditions using parentheses:

+ +
SumIf([Payment], ([Plan] = "Basic" OR [Plan] = "Business") AND month([Date Received]) = 10)
+
+ +

Returns 400 on the sample data.

+ +
+

Tip: make it a habit to put parentheses around your AND and OR groups to avoid making required conditions optional (or vice versa).

+
+ +

Conditional subtotals by group

+ +

To get a conditional subtotal for a category or group, such as the total payments per plan, you’ll:

+ +
    +
  1. Write a sumif formula with your conditions.
  2. +
  3. Add a Group by column in the query builder.
  4. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PaymentPlanDate Received
100BasicOctober 1, 2020
100BasicOctober 1, 2020
200BusinessOctober 1, 2020
200BusinessNovember 1, 2020
400PremiumNovember 1, 2020
+ +

To sum payments for the Business and Premium plans:

+ +
SumIf([Payment], [Plan] = "Business" OR [Plan] = "Premium")
+
+ +

Or, sum payments for all plans that aren’t “Basic”:

+ +
SumIf([Payment], [Plan] != "Basic")
+
+ +
+

The “not equal” operator != should be written as !=.

+
+ +

To view those payments by month, set the Group by column to “Date Received: Month”.

+ + + + + + + + + + + + + + + + + + +
Date Received: MonthTotal Payments for Business and Premium Plans
October200
November600
+ +
+

Tip: when sharing your work with other people, it’s helpful to use the OR filter, even though the != filter is shorter. The inclusive OR filter makes it easier to understand which categories (e.g., plans) are included in the sum.

+
+ +

Accepted data types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data typeWorks with SumIf
String
Number
Timestamp
Boolean
JSON
+ +

See parameters.

+ + + +

Different ways to do the same thing, because CSV files still make up 40% of the world’s data.

+ +

Metabase

+ + + +

Other tools

+ + + +

case

+ +

You can combine Sum and case:

+ +
Sum(case([Plan] = "Basic", [Payment]))
+
+ +

to do the same thing as SumIf:

+ +
SumIf([Payment], [Plan] = "Basic")
+
+ +

The case version lets you sum a different column when the condition isn’t met. For example, you could create a column called “Revenue” that:

+ +
    +
  • sums the “Payments” column when “Plan = Basic”, and
  • +
  • sums the “Contract” column otherwise.
  • +
+ +
sum(case([Plan] = "Basic", [Payment], [Contract]))
+
+ +

CumulativeSum

+ +

SumIf doesn’t do running totals. You’ll need to combine the CumulativeSum aggregation with the case formula.

+ +

For example, to get the running total of payments for the Business and Premium plans by month (using our payment sample data):

+ + + + + + + + + + + + + + + + + + +
Date Received: MonthTotal Payments for Business and Premium Plans
October200
November800
+ +

Create an aggregation from Summarize > Custom expression:

+ +
CumulativeSum(case(([Plan] = "Basic" OR [Plan] = "Premium"), [Payment], 0))
+
+ +

Don’t forget to set the Group by column to “Date Received: Month”.

+ +

SQL

+ +

When you run a question using the query builder, Metabase will convert your query builder settings (filters, summaries, etc.) into a SQL query, and run that query against your database to get your results.

+ +

If our payment sample data is stored in a PostgreSQL database, the SQL query:

+ +
SELECT
+    SUM(CASE WHEN plan = "Basic" THEN payment ELSE 0 END) AS total_payments_basic
+FROM invoices
+
+ +

is equivalent to the Metabase expression:

+ +
SumIf([Payment], [Plan] = "Basic")
+
+ +

To add multiple conditions with a grouping column, use the SQL query:

+ +
SELECT
+    DATE_TRUNC("month", date_received)                       AS date_received_month,
+    SUM(CASE WHEN plan = "Business" THEN payment ELSE 0 END) AS total_payments_business_or_premium
+FROM invoices
+GROUP BY
+    DATE_TRUNC("month", date_received)
+
+ +

The SELECT part of the SQl query matches the Metabase SumIf expression:

+ +
SumIf([Payment], [Plan] = "Business" OR [Plan] = "Premium")
+
+ +

The GROUP BY part of the SQL query maps to a Metabase Group by column set to “Date Received: Month”.

+ +

Spreadsheets

+ +

If our payment sample data is in a spreadsheet where “Payment” is in column A and “Date Received” is in column B, the spreadsheet formula:

+ +
=SUMIF(B:B, "Basic", A:A)
+
+ +

produces the same result as the Metabase expression:

+ +
SumIf([Payment], [Plan] = "Basic")
+
+ +

To add additional conditions, you’ll need to switch to a spreadsheet array formula.

+ +

Python

+ +

If our payment sample data is in a pandas dataframe column called df, the Python code:

+ +
df.loc[df['Plan'] == "Basic", 'Payment'].sum()
+
+ +

is equivalent to the Metabase expression:

+ +
SumIf([Payment], [Plan] = "Basic")
+
+ +

To add multiple conditions with a grouping column:

+ +
import datetime as dt
+
+## Optional: convert the column to a datetime object
+
+    df['Date Received'] = pd.to_datetime(df['Date Received'])
+
+## Extract the month and year
+
+    df['Date Received: Month'] = df['Date Received'].dt.to_period('M')
+
+## Add your conditions
+
+    df_filtered = df[(df['Plan'] == 'Business') | (df['Plan'] == 'Premium')]
+
+## Sum and group by
+
+    df_filtered.groupby('Date Received: Month')['Payment'].sum()
+
+ +

These steps will produce the same result as the Metabase SumIf expression (with the Group by column set to “Date Received: Month”).

+ +
SumIf([Payment], [Plan] = "Business" OR [Plan] = "Premium")
+
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/expressions/week.html b/_site/docs/doc-update-detection/questions/query-builder/expressions/week.html new file mode 100644 index 000000000..36e332f96 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/expressions/week.html @@ -0,0 +1,3167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Week of year | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Week of year

+ +

Weeks of the year are numbered from 1 to 52, 53, or 54 (depending on how the first week of the year is determined). Metabase supports multiple algorithms for determining the first week of the year.

+ +

In the query builder, you can group summaries by week of year, or extract the week of year from a date column using a custom expression.

+ +

Grouping summaries by Week of year is useful when making period-over-period comparisons - for example, when comparing a metric from the first week this year to the metric from the first week in the previous year.

+ +

Summarize by Week of year in the query builder

+ +

You can choose to group a metric by week of year in the query builder.

+ +
    +
  1. In the Summarize section, click on Pick a column to group by and select a date field:
  2. +
  3. Click on the dropdown with date granularity (for example, “by month”) to the right of the field name;
  4. +
  5. In the popup with date granularity options, click More… to see additional options, and select Week of year.
  6. +
+ +

The result will be summarized by week number (as opposed to week dates, like when you select “by week” option):

+ +

Summarize by week of year

+ +

How Metabase numbers weeks of the year

+ +

By default, when you group by Week of year in the query builder, Metabase will find the first Sunday of the year and call that week “week 1”. Any day before the first Sunday is considered to be part of the last week of the previous year (week 52 or 53).

+ +

Using a different first week of the year

+ +

Even if your instance has a different first day of the week set in localization settings, the query builder’s default week of year grouping will always use Sunday as the start of the week.

+ +

The way to use your instance’s localization settings is to use the week function in a custom expression with the "Instance" mode, like so: week([Created At], "Instance") (see below).

+ +

The week custom expression provides three alternative algorithms for computing first week of the year. To use an alternative algorithm for summarizing, you can create a custom column that extracts the week number from a date column using the week expression, then group by that custom column.

+ +

week custom expression

+ +

The week custom expression extracts the week of the year as an integer.

+ +

Syntax:

+ +
week(column, mode)
+
+ +

Examples:

+ +
week([Created At])
+week([Created At], "US")
+week([Created At], "Instance")
+
+ +

Where:

+ +
    +
  • column is the date column you want to extract the week number from.
  • +
  • mode is optional and specifies the algorithm to use to determine the first week of the year. It can be one of the following: +
      +
    • "ISO" (default): the first week of the year is the week containing the first Thursday of the year. Weeks start on Monday. This is the ISO 8601 standard.
    • +
    • "US": The first week of the year starts on January 1. Weeks start on Sundays. In most years, the first week will be a partial week.
    • +
    • "Instance": The first week of the year starts on January 1. Weeks start on the day of the week specified in localization settings. In most years, the first week will be a partial week.
    • +
    +
  • +
+ +

Note that none of the three currently available modes match the first week algorithm used in summarizing by week of the year in the query builder.

+ +

Comparing how different algorithms calculate the first and last weeks

+ +
    +
  • +

    In the query builder when using Group by Week of year:

    + +

    How the week numbers are calculated for Group by Week of year

    +
  • +
  • +

    week(column) or week(column, "ISO"):

    + +

    How the week numbers are calculated by ISO

    +
  • +
  • +

    week(column, "US"):

    + +

    How the week numbers are calculated by US method

    +
  • +
  • +

    week(column, "Instance") if the instance’s first day of the week is Monday:

    + +

    How the week numbers are calculated by Instance method

    +
  • +
+ +

SQL

+ +

Different SQL databases have different approaches and functions for extracting week of the year. Some engines offer multiple functions for extracting week of the year and multiple algorithms for computing week of year using SQL. Refer to the documentation for your database.

+ +

Here’s an incomplete list of example functions:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DatabaseExampleFirst week algorithm
PostgresEXTRACT(WEEK FROM TIMESTAMP created_at)ISO algorithm
MySQLWEEKOFYEAR("2017-06-15")The first day of the week is Monday and the first week of the year has more than 3 days. Alternative functions exist.
BigQueryEXTRACT(WEEK FROM DATE ticreated_at)Weeks numbered from 0. Dates prior to the first Sunday of the year are in week 0. Alternative functions exist.
RedshiftDATE_PART(week, TIMESTAMP created_at)ISO algorithm
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/filters.html b/_site/docs/doc-update-detection/questions/query-builder/filters.html new file mode 100644 index 000000000..947ff1a39 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/filters.html @@ -0,0 +1,3096 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Filtering | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Filtering

+ +

Filtering just means narrowing things down based on certain criteria. You’re probably already familiar with filtering when looking for something online, like when shopping. Maybe you only want to see olive-colored pants, or books where the author’s last name is “Borges,” or pictures of people wearing olive-colored pants reading Jorge Luis Borges.

+ +

Filtering

+ +

When you add a filter step, you can select one or more columns to filter on. Depending on the data type of the column you pick, you’ll get different filter types, like a calendar for date columns.

+ +

You can add subsequent filter steps after each summarize step. This lets you do things like summarize by the count of rows per month, and then add a filter on the count column to only include rows where the count is greater than 100. (This is basically like a SQL HAVING clause.)

+ +

Once you’re happy with your filter, click Add filter, and visualize your results. Your data will be updated with the filter applied.

+ +

If you want to edit your filter, just click the little purple filter at the top of the screen. If you click on the X, you’ll remove your filter. You can add as many filters as you need.

+ +

Filter types

+ +

Depending on the data type of the column, Metabase will present different filtering options.

+ +
    +
  • Numeric columns let you add filters to only include rows in your table where this number is between two specific values, or is greater or less than a specific value, or is exactly equal to something.
  • +
  • Text or category columns let you specify that you only want to include data where this column is or isn’t a specific option, whether it contains, starts with, or ends with a substring, or whether the row is empty or not.
  • +
  • Date columns give you a lot of options to filter by specific date ranges, relative date ranges, and more.
  • +
  • Structured data columns, typically JSON or XML, can only be filtered by “Is empty” or “Not empty”. Some databases, however, support JSON unfolding, which allows you to split up JSON data into separate columns, which you can then filter on.
  • +
  • Latitude and longitude columns will have the same options as numeric columns, but also a special “Inside” filter type that will let you filter on both latitude and longitude simultaneously.
  • +
+ +

Filter multiple columns

+ +

When viewing a table or chart, clicking on the Filter will bring up the filter modal.

+ +

Bulk filter modal

+ +

Here you can add multiple filters to your question in one go (which can save you a lot of loading time). Filter options will differ depending on the field type. Any tables linked by foreign keys will be displayed in the left tab of the modal. You can also filter your summaries.

+ +

When you’re done adding filters, hit Apply filters to rerun the query and update its results. To remove all the filters you’ve applied, click on Clear all filters in the bottom left of the filter modal. Any filters you apply here will show up in the editor, and vice versa.

+ +

Filtering by date

+ +

One important thing to understand when filtering on a date column is the difference between specific and relative dates:

+ +
    +
  • Specific dates are things like November 1, 2010, or June 3 – July 12, 2017; they always refer to the same date(s).
  • +
  • Relative dates are things like “the previous 30 days,” or “the current week;” as time passes, the dates these options refer to change. Relative dates are a useful way to set up a filter on a question so that it stays up-to-date by showing you, for example, how many people visited your website in the last 7 days. You can also click on the to specify a Starting from option, which lets you offset the relative date range. For example, you could set the range as the “Previous 7 days, starting from 2 days ago”.
  • +
+ +

Filter with custom expressions

+ +

Filter expression

+ +

If you have a more complex filter you’re trying to express, you can pick Custom Expression from the add filter menu to create a filter expression. You can use comparison operators like greater than, >, or less than ,<, as well as spreadsheet-like functions. For example, [Subtotal] > 100 OR median([Age]) < 40.

+ +

Learn more about writing expressions or skip right to the list of expressions.

+ +

Filtering by a segment

+ +

If your Metabase administrators have created special named filters for the table you’re viewing, they’ll appear at the top of the filter dropdown in purple text with a star next to them. These are called Segments, and they’re shortcuts to a combination of filters that are commonly used in your organization. They might be called things like “Active Users,” or “Most Popular Products.”

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/introduction.html b/_site/docs/doc-update-detection/questions/query-builder/introduction.html new file mode 100644 index 000000000..153883f0e --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/introduction.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/query-builder/join.html b/_site/docs/doc-update-detection/questions/query-builder/join.html new file mode 100644 index 000000000..4b11c3203 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/join.html @@ -0,0 +1,3099 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Joining data | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Joining data

+ +

Joining

+ +

You can join data to combine your current data with another table, or even with a saved question.

+ +

After you click on the Join Data button to add a join step, you’ll need to pick the data (from the same database) that you want to join. You can only pick tables and saved questions that are from the same database as your starting data.

+ +

Picking the data to join

+ +

Next, you’ll need to pick the columns you want to join on. This means you pick a column from the first table, and a column from the second table, and the join will stitch rows together where the value from the first column is equal to the value in the second column. A very common example is to join on an ID column in each table, so if you happened to pick a table to join on where there is a foreign key relationship between the tables, Metabase will automatically pick those corresponding ID columns for you. At the end of your join step, there’s a Columns button you can click to choose which columns you want to include from the joined data.

+ +

By default, Metabase will do a left outer join, but you can click on the Venn diagram icon to select a different type of join. Not all databases support all types of joins, so Metabase will only display the options supported by the database you’re using.

+ +

Here are the basic types of joins:

+ +
    +
  • Left outer join: select all records from Table A, along with records from Table B that meet the join condition, if any.
  • +
  • Right outer join: select all records from Table B, along with records from Table A that meet the join condition, if any.
  • +
  • Inner join: only select the records from Table A and B where the join condition is met.
  • +
  • Full outer join: select all records from both tables, whether or not the join condition is met.
  • +
+ +

A left outer join example: If Table A is Orders and Table B is Customers, and assuming you do a join where the customer_id column in Orders is equal to the ID column in Customers, when you do a left outer join your results will be a full list of all your orders, and each order row will also display the columns of the customer who placed that order. Since a single customer can place many orders, a given customer’s information might be repeated many times for different order rows. If there isn’t a corresponding customer for a given order, the order’s information will be shown, but the customer columns will just be blank for that row.

+ +

Multiple stages of joins

+ +

In many cases you might have tables A, B, and C, where A and B have a connection, and B and C have a connection, but A and C don’t. If you want to join A to B to C, all you have to do is add multiple join steps. Click on Join Data, join table A to table B, then click the Join Data step below that completed join block to add a second join step, and join the results of your last join to table C.

+ +

An A to B to C join

+ +

Joining on multiple conditions

+ +

Your joins can also include multiple conditions to refine your results. Metabase will combine multiple conditions using the AND operator.

+ +

Joining tables on multiple columns

+ +

Joining with different operators

+ +

You can join tables on comparison conditions like:

+ +
    +
  • = (equals)
  • +
  • (not equals)
  • +
  • > (greater than)
  • +
  • (greater than or equal to)
  • +
  • < (less than)
  • +
  • (less than or equal to)
  • +
+ +

Join operators

+ +

Further reading

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/query-builder/summarizing-and-grouping.html b/_site/docs/doc-update-detection/questions/query-builder/summarizing-and-grouping.html new file mode 100644 index 000000000..d15ce1bdd --- /dev/null +++ b/_site/docs/doc-update-detection/questions/query-builder/summarizing-and-grouping.html @@ -0,0 +1,3115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Summarizing and grouping | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Summarizing and grouping

+ +

Summarizing

+ +

When we have a question like “how many people downloaded our app each day last week?”, we’re asking for a summary of the data. A summary is usually made up of two parts: one or more numbers we care about (called a “metric” in data-speak), and how we want to see that number grouped or broken out. To answer that example question of “How many people downloaded our app each day last week?”

+ +
    +
  • The metric would be the count of people who downloaded the app (the count of rows).
  • +
  • We want that metric to be grouped by “each day.”
  • +
  • And we want to filter the rows for “last week.”
  • +
+ +

There are two common ways you’ll tend to summarize your data:

+ +
    +
  • Counting the number of rows in your table
  • +
  • Getting the sum or average of a numeric column
  • +
+ +

And a lot of the time, you’ll then group that metric by:

+ +
    +
  • Time
  • +
  • Place
  • +
  • Category
  • +
+ +

Summary metrics

+ +

Adding a summarize step lets you choose how to aggregate the data from the previous step. You can pick one or more metrics, and optionally group those metrics by one or more dimensions (columns). When picking your metrics you can choose from basic functions like sum, average, and count; or you can pick a common metric defined by an admin; or you can create a custom expression by writing a formula.

+ +

Common metrics include:

+ +
    +
  • Count of rows: the total of number of rows in the table, after any filters have been applied. If you’re looking at your Orders table and want to know how many orders were placed with a price greater than $40, you’d filter by “Price greater than 40,” and then select Count of rows, because you want Metabase to count how many orders matched your filter.
  • +
  • Sum of …: the sum of all the values in a specific column.
  • +
  • Average of …: the average of all the values in a single column.
  • +
  • Number of distinct values of…: the number of unique values in all the cells of a single column. This is useful when trying to find out things like how many different types of products were sold last month (not how many were sold in total).
  • +
  • Cumulative sum of…: This gives you a running total for a specific column. In order for this metric to be useful you’ll need to group it by a date column to see it across time.
  • +
  • Cumulative count of rows: This gives you a running total of the number of rows in the table over time. Just like Cumulative sum of…, you’ll need to group this by a date column in order for it to be useful.
  • +
  • Standard deviation of …: A number which expresses how much the values of a column vary, plus or minus, from the average value of that column.
  • +
  • Minimum of …: The minimum value present in the selected field.
  • +
  • Maximum of …: The maximum value present in the selected field.
  • +
+ +

If you summarize and add a grouping you can then summarize again. You can also add steps to filter and/or join in between. For example, your first summarization step could be to get the count of orders per month, and you could then add a second summarization step to get the average monthly order total by selecting the Average of… your count column.

+ +

Multiple summarize steps

+ +

You can also add metrics and groupings on the results page in a sidebar: the top of the sidebar where you pick the number (“metric”) you want to see, and the part below is where you pick how to group that number (or how to “break it out”).

+ +

If your admins have created any named metrics that are specific to your company or organization, they will be in this dropdown under the Common Metrics section. These might be things like your company’s official way of calculating revenue.

+ +

Grouping your metrics

+ +

Depending on the grouping column you select, Metabase will show you what it thinks is the best default visualization or chart for this summary. So if you select a date column, you’ll see a line chart like this (you can click the green Summarize button to view the summarize sidebar).

+ +

Grouping by a date column

+ +

When you click on a different grouping column than the one you currently have selected, the grouping will switch to use that column instead. But if you want to add an additional grouping, just click the plus (+) icon on the right side of the column. To remove a grouping, click on the X icon.

+ +

Multiple groupings

+ +

Some grouping columns will give you the option of choosing how big or small to make the groupings:

+ +
    +
  • For datetime columns, you can click on the words by month to change the grouping to day, week, hour, quarter, year, etc. You’ll also be able to add multiple breakouts by the same datetime column with different time granularities (for example, group by week and day of the week). For information on grouping by week of year, see Week of year.
  • +
  • +

    For numeric columns like age, Metabase will automatically “bin” the results, so you’ll see your metric grouped in age brackets, like 0–10, 11–20, 21–30, etc. Just like with dates, you can click on the current binning option to change it to a specific number of bins. Currently, you can’t choose your own ranges for bins.

    + +

    Multiple groupings

    + +

    If you select a fixed number of bins, Metabase will break the range of the data into that number of equal size intervals. Some intervals might end up having no data, and Metabase will not display them.

    +
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/sharing/alerts.html b/_site/docs/doc-update-detection/questions/sharing/alerts.html new file mode 100644 index 000000000..b23407084 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/alerts.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/exporting-results.html b/_site/docs/doc-update-detection/questions/sharing/exporting-results.html new file mode 100644 index 000000000..45cef4ab2 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/exporting-results.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/combo-chart.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/combo-chart.html new file mode 100644 index 000000000..f89056387 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/combo-chart.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/detail.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/detail.html new file mode 100644 index 000000000..d5c10df8c --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/detail.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/funnel.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/funnel.html new file mode 100644 index 000000000..a50dd1bcf --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/funnel.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/gauge.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/gauge.html new file mode 100644 index 000000000..695660a3c --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/gauge.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/maps.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/maps.html new file mode 100644 index 000000000..7c811402e --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/maps.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/numbers.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/numbers.html new file mode 100644 index 000000000..149c1eeb6 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/numbers.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/pie-or-donut-chart.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/pie-or-donut-chart.html new file mode 100644 index 000000000..7177fe498 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/pie-or-donut-chart.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/pivot-table.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/pivot-table.html new file mode 100644 index 000000000..bd0208c63 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/pivot-table.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/progress-bar.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/progress-bar.html new file mode 100644 index 000000000..f3c454238 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/progress-bar.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/sankey.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/sankey.html new file mode 100644 index 000000000..80102f4fd --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/sankey.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/scatterplot-or-bubble-chart.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/scatterplot-or-bubble-chart.html new file mode 100644 index 000000000..e1082aae4 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/scatterplot-or-bubble-chart.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/table.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/table.html new file mode 100644 index 000000000..6ea7031ed --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/table.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/tooltips.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/tooltips.html new file mode 100644 index 000000000..ec923710c --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/tooltips.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/trend.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/trend.html new file mode 100644 index 000000000..29bb7b1ca --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/trend.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizations/waterfall-chart.html b/_site/docs/doc-update-detection/questions/sharing/visualizations/waterfall-chart.html new file mode 100644 index 000000000..362e525e1 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizations/waterfall-chart.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/sharing/visualizing-results.html b/_site/docs/doc-update-detection/questions/sharing/visualizing-results.html new file mode 100644 index 000000000..c75a27feb --- /dev/null +++ b/_site/docs/doc-update-detection/questions/sharing/visualizing-results.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/questions/start.html b/_site/docs/doc-update-detection/questions/start.html new file mode 100644 index 000000000..6891b7b96 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/start.html @@ -0,0 +1,3101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Questions overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Questions overview

+ +

Questions are queries plus their visualization. You can ask questions using Metabase’s graphical query builder, or create a native/SQL query.

+ +

Question introduction

+ +

Questions are the basic building blocks of Metabase.

+ +

Query builder

+ +

The query editor

+ +

An introduction to Metabase’s graphical query builder.

+ +

Custom expressions

+ +

Custom expressions, like spreadsheet formulas, are tools you can use in the graphical query builder to ask more complicated questions.

+ +

List of expressions

+ +

A list of the aggregations and functions available in the graphical query builder.

+ +

Joining data

+ +

You can join data to combine your current data with another table, or even with a saved question.

+ +

Native query editor

+ +

Also known as the SQL editor (we say native because you can also query databases that don’t use SQL, like MongoDB).

+ +

Introduction to the native query editor

+ +

Write native code (like SQL) to query your data source.

+ +

SQL templates

+ +

Pass parameters into variables in your SQL templates.

+ +

Snippets

+ +

Reuse and share bits of SQL.

+ +

Sharing results

+ +

There are many different ways to share the results of questions. To share the results of a dashboard, see Dashboard subscriptions.

+ +

Visualizing results

+ +

Choose from a variety of visualization types.

+ +

Alerts

+ +

Get results via email or Slack, either on a schedule, or only when something interesting happens.

+ +

Exporting

+ +

The different ways you can export the results of questions and dashboards.

+ +

Tooltips

+ +

Customize tooltips on bar, line, and area charts.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/combo-chart.html b/_site/docs/doc-update-detection/questions/visualizations/combo-chart.html new file mode 100644 index 000000000..0d5a8131b --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/combo-chart.html @@ -0,0 +1,3055 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Combo charts | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Combo charts

+ +

Combo charts let you combine bars and lines (or areas) on the same chart.

+ +

Line + bar

+ +

Metabase will pick one of your series to display as a line, and another to display as a bar by default. Open up the visualization settings to change which series are lines, bars, or areas, as well as to change per-series settings like colors.

+ +

To use a Combo chart you’ll either need to have two or more metrics selected in the Summarize By section of your question, with one or two grouping columns, like this:

+ +

Data for Line + Bar chart

+ +

Or you’ll need a question with a single metric and two grouping columns, like this:

+ +

Data for Line + Bar chart

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/detail.html b/_site/docs/doc-update-detection/questions/visualizations/detail.html new file mode 100644 index 000000000..f2e985f98 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/detail.html @@ -0,0 +1,3061 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Detail | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Detail

+ +

The Detail visualization shows a single result record (row) in an easy-to-read, two-column display.

+ +

Detail of a record in the account table

+ +

You can cycle through records using the arrow buttons.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/funnel.html b/_site/docs/doc-update-detection/questions/visualizations/funnel.html new file mode 100644 index 000000000..7c1cbf2e2 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/funnel.html @@ -0,0 +1,3142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Funnel charts | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Funnel charts

+ +

Funnel charts visualize how a value is broken out by a series of steps, and the percent change between steps.

+ +

Funnel

+ +

Funnels are commonly used in e-commerce or sales to visualize how many customers are present within each step of a checkout flow or sales cycle. Funnels only make sense if the steps are sequential, with the metric dropping from one step to the next.

+ +

Data shape for a funnel chart

+ +

To create a funnel in Metabase, you’ll need to have a table with at least two columns: one column that contains the funnel’s steps, and another column contains the metric you’re interested in, like the number of customers at this step.

+ +

Here’s the data shape used to create the chart above:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StageOpportunities
Leads3901
Qualification3714
Prospecting3231
Proposal2972
Negotiation1588
Closed737
+ +

If you have more columns in your query results, you can select which columns should be used for the funnel steps and the metric in the data settings.

+ +

By default, Metabase will present steps in the same order as they appear in the query result, but you can reorder or hide the steps in the data settings.

+ +

Build a query for a funnel chart

+ +

To create a query with a result that has the shape required for a funnel chart, you’ll probably need to summarize your data.

+ +

If your (original, unaggregated) data already contains a field with the the step for every data point, you can build a simple query with a breakout by steps:

+ +

A query in the query builder used to build a funnel chart

+ +

If data for the different steps of the funnel comes from different tables, or if you need to use different filters or aggregation rules for each step, you can create separate questions for each step, and then combine them with a SQL query.

+ +

For example: you could create three separate query builder questions, each returning the counts for Leads, Qualification, and Proposal stage. Then you’d write a SQL query that references those questions and uses UNION to return results in the right shape to build a funnel chart.

+ +
-- example of a query that retrieves results of questions and combines them with UNION
+
+SELECT 'Leads' as step, * from 
+UNION
+SELECT 'Qualified' as step, * from 
+UNION
+SELECT 'Prospects' as step, * from 
+
+
+ +

Data for the funnel coming from a SQL union

+ +

How to read a funnel chart

+ +

Funnel charts show the value of the metric for each step, and how the metric compares to the value at the first step. The first step’s metric is displayed to the left of the chart.

+ +

Funnel chart with a tooltip

+ +

So for example,”76.19\%, 2,972” under a step means that the value of the metric at this step is 2,972, which is 76.19\% of the value of the first step (equal to 3,901).

+ +

To see percentage comparison with the previous step (instead of the first), hover over the step and read the tooltip.

+ +

Funnel chart settings

+ +

To open chart settings, click on the Gear icon in the bottom left.

+ +

Funnel chart settings

+ +

If you have more than two columns in your query results, you can select which columns should be used for the funnel steps and the measure in the Data tab.

+ +

You can reorder funnel steps by dragging and dropping, or hide a step by clicking on the Eye icon on the step card.

+ +

To edit the formatting of the metric, click on Three dots next to the metric. The formatting will only apply to the metric itself, but not to the percentage values that compare each step’s metric to the first step (which currently you can’t format).

+ +

Limitations and alternatives

+ +

Currently, you can’t change the color or orientation of the funnel, or add breakouts. Consider using a bar or row chart for more flexible visualization options.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/gauge.html b/_site/docs/doc-update-detection/questions/visualizations/gauge.html new file mode 100644 index 000000000..f55cf89a0 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/gauge.html @@ -0,0 +1,3130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Gauge chart | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Gauge chart

+ +

Ah, gauges: you either love ‘em or you hate ‘em. …Or you feel “meh” about them, I guess. Whatever the case, gauges allow you to show a single number in the context of a set of colored ranges that you can specify.

+ +

Gauge

+ +

When to use a gauge chart

+ +

A gauge chart is useful when you want to show progress or status across different categories. +They’re helpful for performance metrics, risk assessments, or any metric that has distinct thresholds.

+ +

How to create a gauge chart

+ +

To build a gauge chart, you’ll need:

+ +
    +
  • +

    A query that returns a single number:

    + + + + + + + + + + + + +
    Sum of Quantity
    4910
    + +

    You can also use a query that returns several metrics in a single row:

    + + + + + + + + + + + + + + + + +
    Sum of QuantityAverage QuantityMax Quantity
    491017.32173
    + +

    In this case, the gauge chart will use the metric in the first column (“Sum of quantity”). To change the metric, go to the editor and drag the metric you want to the first position in the Summarize block.

    +
  • +
  • +

    One or more ranges for the metric, for example “Low”, “Medium”, “High”. Currently, Metabase only supports defining static ranges (you can’t set range boundaries based on another query).

    +
  • +
+ +

Gauge chart

+ +

Gauge chart settings

+ +

You can set the ranges, their colors, and optional labels in chart settings.

+ +

To open the chart setting, click on the Visualization icon at the bottom left of the screen.

+ +

Format options will apply to both the result of the query and the range boundaries:

+ +

Gauge format options

+ +

In particular, the gauge chart will apply the “Multiply by a number” option to the range boundaries. So if you want to show a range from 2000 to 4000 on the chart, you can set “Multiply by a number: 1000”, then set the underlying range to be from 2 to 4.

+ +

Selecting “Style: Percent” in format options will only change how Metabase formats the results. For example, 17 will be formatted as 1700%. If you instead want to display the query result as a percentage of the total range of the chart, you’ll need to calculate that percentage in your query. Another example: to display the count of orders as a percentage of 20, use custom expressions to return “Count of orders divided by 20”, and format the result as a percentage.

+ +

Limitations and alternatives

+ +
    +
  • +

    If you want to show progress of a metric within a single range, consider using the progress bar instead.

    +
  • +
  • +

    Metabase doesn’t support setting alerts for when a metric moves from one region of the gauge chart to another. Consider using a progress bar to create an alert when your metric reaches a certain value.

    +
  • +
  • +

    Gauge charts don’t support breakouts. Depending on your use case, consider using a bar chart with a goal line.

    +
  • +
  • +

    Gauge chart ranges can’t be set based on results of another query.

    +
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/line-bar-and-area-charts.html b/_site/docs/doc-update-detection/questions/visualizations/line-bar-and-area-charts.html new file mode 100644 index 000000000..697bc0cdb --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/line-bar-and-area-charts.html @@ -0,0 +1,3223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Line charts, bar charts, and area charts | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Line charts, bar charts, and area charts

+ +

They’re pretty useful.

+ +

Line charts

+ +

Line charts are best for displaying the trend of a number over time, especially when you have lots of x-axis values. For more, check out our Guide to line charts and Time series analysis tutorials.

+ +

Trend lines

+ +

Bar charts

+ +

Bar chart

+ +

If you’re trying to group a number by a column that has a lot of possible values, like a Vendor or Product Title field, try visualizing it as a row chart. Metabase will show you the bars in descending order of size, with a final bar at the bottom for items that didn’t fit.

+ +

Row chart

+ +

If you have a bar chart like Count of Users by Age, where the x-axis is a number, you’ll get a special kind of chart called a histogram, where each bar represents a range of values (called a “bin”). Note that Metabase will automatically bin your results any time you use a number as a grouping, even if you aren’t viewing a bar chart. Questions that use latitude and longitude will also get binned automatically.

+ +

Combo line and bar charts

+ +

See Combo charts.

+ +

Histograms

+ +

Histogram

+ +

By default, Metabase will automatically choose a good way to bin your results. But you can change how many bins your result has, or turn the binning off entirely, by clicking on the area to the right of the column you’re grouping by:

+ +

Binning options

+ +

Area charts

+ +

Area charts are useful when comparing the proportions of two metrics over time. Both bar and area charts can be stacked.

+ +

Stacked area chart

+ +

Settings for line, bar, and area charts

+ +

These three charting types have very similar options, which are broken up into the following tabs. You can access these chart settings by clicking the gear icon in the lower left of the chart.

+ + + +

Data settings

+ +

Here you can configure settings for the how the data is displayed.

+ +

For each series on the chart, you can:

+ +
    +
  • Whether to show or hide the series.
  • +
  • Determine how to display the series: as a line, bar, or area chart.
  • +
  • Determine the order Metabase displays the series in the chart’s legend.
  • +
+ +

Line chart and Area chart options

+ +

Line chart options

+ +
    +
  • Line color
  • +
  • Line shape
  • +
  • Line style
  • +
  • Line size: Small, Medium, or Large
  • +
  • Whether to show docs on the lines (the dots represent the actual data points plotted on the chart)
  • +
  • Whether to show values for the series. This option is only available if you’ve toggled on Show value on data points.
  • +
  • How to replace missing values: Zero, Nothing (just a break in the line), or Linear interpolated
  • +
+ +

You can also rearrange series (which determines their order in the chart’s legend).

+ +

Bar chart options

+ +

For bar charts, you can configure:

+ +
    +
  • Bar color
  • +
  • Y-axis position (which side of the chart to display the y-axis labels)
  • +
+ +

Display settings

+ +

Here you set things like:

+ + + +

Goal lines

+ +

Goal line on chart

+ +

Goal lines can be used in conjunction with alerts to send an email or a Slack message when your metric cross this line.

+ +

Trend lines

+ +

Trend lines are another useful option for line, area, bar, and scatter charts. If you have a question where you’re grouping by a time field, open up the visualization settings and turn the Show trend line toggle on to display a trend line. Metabase will choose the best type of line to fit to the trend of your series. Trend lines will even work if you have multiple metrics selected in your summary. But trend lines won’t work if you have any groupings beyond the one time field.

+ +

Trend lines

+ +

Stacked bar chart

+ +

If you have multiple series, you can stack them on bar chart.

+ +

Stacked bar chart

+ +

As well as stack them as a percentage:

+ +

Stacked bar chart 100%

+ +

Values on data points

+ +

You can show some values (Metabase will pick some values to make the chart more legible), all values, or no values.

+ +

If you toggle on values on data points, you can toggle values for individual series on the Data tab of the chart’s settings. For example, if you have four series, and only want to display values for one of the series.

+ +

Autoformatting

+ +

For displaying numbers on the chart, Metabase can truncate the numbers to make the chart more legible. For example, Metabase will truncate 42,000 to 42K.

+ +

Axes settings

+ +

Here you’ll find additional settings for configuring your x and y axes (as in axis, not battle axe).

+ +

X-axis

+ +
    +
  • Show label (the label for the axis).
  • +
  • Rename the axis
  • +
  • Show line and marks
  • +
  • Scale: Timeseries or Ordinal.
  • +
+ +

Y-axis

+ +
    +
  • Show label (the label for the axis).
  • +
  • Rename the axis
  • +
  • Split y-axis when necessary
  • +
  • Auto y-axis range. When not toggled on, you can set the y-axis range (it’s min and max values).
  • +
  • Scale: Linear, power, or log.
  • +
  • Show lines and marks
  • +
  • Unpin from zero. Allows you to “Zoom in” on charts with values well above zero. Here’s an example (note the y-axis starts at 20,000): +y-axis unpinned from zero
  • +
+ +

Chart legend

+ +

For charts with multiple series or breakouts, chart legend displays the label and color of each series.

+ +

Legend

+ +

You can change the color and label for each series and reorder them in data settings.

+ +

You can use the legend to:

+ +
    +
  • Highlight a series, by hovering over the name of the series in the legend.
  • +
  • Hide the series, by clicking on the color circle for the series.
  • +
+ +

To permanently hide the series from the chart, use the data settings.

+ +
    +
  • Drill down to individual records for aggregated series, by clicking on the series name.
  • +
+ +

Currently, you can’t hide the legend or change its position on the chart.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/map.html b/_site/docs/doc-update-detection/questions/visualizations/map.html new file mode 100644 index 000000000..c5bd1716f --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/map.html @@ -0,0 +1,3304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Maps | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Maps

+ +

Metabase has three types of map visualization:

+ +
    +
  • Pin map for putting individual data points on a map using longitude and latitude coordinates;
  • +
  • Grid map for distributing a large number of points over a specified area.
  • +
  • Region map for data broken out by regions, like countries or states. Metabase comes with two built-in maps, but you can upload your own custom regions.
  • +
+ +

When you select the Map visualization setting, Metabase will automatically try and pick the best kind of map to use based on the table or result set, as long as the columns with the geographical data have the right metadata.

+ +

Map types

+ +
+ +
+ + +
+
+ +

Pin map

+ +

Pin maps display pins for individual data points on the map. They work best for displaying unaggregated geographical data.

+ +

Pin map data shape

+ +

To build a pin map, you need a query that returns a result that has latitude and longitude columns. Metabase will put one pin on the map for each row in your table, based on the latitude and longitude fields. Other data in the rows will be shown in the tooltip, and won’t otherwise affect the placement or shape of pins.

+ +

Pin map data shape +Pin map with a tooltip

+ +

Note that the tooltips will only be displayed when the map is sufficiently zoomed in using Draw box to filter.

+ +

Create a pin map

+ +

To create a pin map:

+ +
    +
  1. Build a query with latitude and longitude columns for each data point (either in the query builder or using SQL);
  2. +
  3. Select Visualization, and pick Map;
  4. +
  5. +

    If your query results have columns whose field type is set to latitude/longitude in table metadata, Metabase should build a pin map automatically.

    + +

    Otherwise, click on the Gear icon to go to visualization settings, choose Map type: Pin map, and pick columns that contain latitude and longitude coordinates.

    +
  6. +
+ +

Pin maps display 2000 pins by default

+ +

By default, pin maps will display 2000 pins even if there are more rows in your query results (this limit is the same for every chart displaying unaggregated data in Metabase). You can use the environment variable MB_UNAGGREGATED_QUERY_ROW_LIMIT to increase the number of data points rendered on charts based on unaggregated queries, but keep in mind that this setting will affect all charts—not just the pin maps—and it might significantly slow down your Metabase and your browser.

+ +

If you need to display a large number of geographical data points, consider using a grid map to display the distribution instead.

+ +

Grid map

+ +

Grid map is an aggregated version of the pin map — like a heatmap for the distribution of pins. Grid map breaks the the map into a grid based on latitude/longitude, and then colors each grid cell based on how many data points fall in it.

+ +

Grid map

+ +

Grid map data shape

+ +

To create a grid map, you need to have a query returning a metric summarized by binned latitude/longitude coordinates.

+ +

Example of data for grid map

+ +

If you’re writing a query in the query builder, you can choose how to bin latitude/longitude in the Group by block. If you’re writing a query in SQL, you’ll need to add binning logic yourself.

+ +

Binned latitude and longitude in the query builder

+ +

Create a grid map

+ +

To create a grid map:

+ +
    +
  1. Build a query with summary by binned latitude and longitude columns (either in the query builder or using SQL);
  2. +
  3. Select Visualization, and pick Map;
  4. +
  5. +

    If your query results have columns whose field type is set to latitude/longitude in table metadata, Metabase should build a grid map automatically.

    + +

    Otherwise, click on the Gear icon to go to visualization settings, choose Map type: grid map, and pick columns that contain latitude and longitude coordinates.

    +
  6. +
  7. If your query contains several metrics, you can pick the one you want to display in visualization settings.
  8. +
+ +

Region maps

+ +

Region maps display a distribution of aggregated data broken out by regions, like count of users by country.

+ +

Metabase comes with two built-in regions: world map with countries, and the Unites States map with states. Admins can add custom regions in Admin setting.

+ +

Three types of region maps

+ +

You can disable the default regions by setting the environment variable MB_DEFAULT_MAPS_ENABLED.

+ +

Region map data shape

+ +

To build a region map, you need a query (either a question built with the query builder, or a native query) with at least two columns: the column with the region name and the column with the metric that you want to display by region.

+ +

Region map query example

+ +

The region name in the query results must be an exact case-sensitive match to the region name: two-letter country code for world maps, two-letter state code or state name for the United States map, or the region identifier in the custom region.

+ +

To build a region map, you must have a column with a region name in your query results, even if your query results also have latitude/longitude coordinates. Metabase can’t infer regions from latitude/longitude coordinates, and doesn’t check whether the coordinates of a datapoint are consistent with the region for that data point.

+ +

Create a region map

+ +

To create a region map:

+ +
    +
  1. Build a query with summary by region name (either in the query builder or using SQL).
  2. +
  3. Select Visualization, and pick Map;
  4. +
  5. Choose Map type: region;
  6. +
  7. Pick the region map: world map (built-in), United States (built-in), or
  8. +
  9. Pick the column with the region name in Region field
  10. +
  11. If your query contains several metrics, you can pick the one you want to display in Metric field.
  12. +
+ +

You can change the base color used for the region map, but you can’t currently use custom color gradients (for example, red to green), or change how Metabase bins the metric.

+ +

World Map

+ +

To visualize your results in the format of a map of the world broken out by country, your result must contain a column with two-letter ISO country codes, like “US” or “BR”, for example:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Country codeMetric
US36
BR25
IN62
RO78
+ +

The country codes in the query results must match the two-letter codes exactly: if the country codes are lowercase or contain extra spaces, Metabase won’t recognize them.

+ +

If your query result has columns with semantic type “Country”, Metabase should build a world map automatically. Otherwise, you can choose which columns to use as the country name in the Region field visualization setting.

+ +

You can connect the country column in the world region map to a “Location” type dashboard filter.

+ +

United States map

+ +

Creating a map of the United States from your data requires your results to contain a column that contains names of states or two-letter state codes, for example “NM” or “New Mexico”, for example:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
StateMetric
California45
New York56
Texas34
Illinois67
+ +

If your query result has columns with semantic type “State”, Metabase should build a US map automatically. Otherwise, you can choose which columns to use as the country name in the visualization settings.

+ +

You can connect the state column in the US region map to a “Location” type dashboard filter.

+ +

Custom regions

+ +

Admins can add more regions - like Brazil states or NYC neighborhoods - by adding custom GeoJSON maps in Admin settings. Once custom maps have been added, you’ll be able to select them when building a region map in map settings.

+ +

Select a custom region

+ +

Your query results must contain a column with values that match the region identifier property in the custom map setting (not the region display name).

+ +

If you want to connect the region column in a custom region map to a dashboard filter, you’ll need to use a “Text or Category” - not “Location” - dashboard filter type.

+ +

Working with maps

+ +

Drill-through

+ +
    +
  • Pin map: If the pin is linked to other tables, or there’s too much information to fit in the tooltip, clicking on the pin will take you to a details page that displays a list of fields, as well as a list of connected tables.
  • +
  • Grid map: If you click on a grid cell, you’ll get an option to zoom in further into a cell.
  • +
  • World region map and US states region maps: If your unaggregated data also contains latitude/longitude coordinates for each data point (in addition to the region name), then you’ll get an option to zoom into a specific region, which will create a grid map of data points in that region binned by latitude/longitude. This only applies to the built-in region maps, not custom region maps.
  • +
+ +

Save as default view

+ +

On pin and grid maps, the map resets to the default view every time the page is refreshed. To control what is displayed when someone opens a map (e.g. center around a specific point, with a specific level of zoom), adjusted your map orientation. This will be the new default view that the map returns to after a page refresh.

+ +

Draw box to filter

+ +

On pin and grid maps, filter boxes allow you to zoom in or filter data by a specific area.

+ +

You can click Draw box to filter and mouse over the map. To outline a section of the map, hold your mouse down and drag across the map to create a transparent blue box. Once you’ve outlined your target area, release your mouse, and your map will update to filter for data in the selected area. If you’ve set a default view, the view will remain stationary. If no default view is set, the view will zoom in on the selected area.

+ +

Drawing a box will add filters to your query.

+ +

Customizing map tiles

+ +

Admins can customize the background tiles that are used for pin and grid maps, see Changing the Map tile server.

+ +

Default and satellite tiles

+ +

Currently, Metabase uses a single tile server per instance. You can’t specify different tiles for different maps.

+ +

Limitations

+ +
    +
  • +

    Currently, you can’t customize the following visualization settings on maps:

    + +
      +
    • The color or pins on a pin map;
    • +
    • The color of bins on the grid map;
    • +
    • The number of size of bins for region maps.
    • +
    +
  • +
  • You can’t combine different types of maps. For example, you can’t put pins on a region map.
  • +
  • You need to use category (not location) dashboard filter types when connecting custom region maps to dashboard filters.
  • +
  • You can’t specify different background tiles for different maps.
  • +
+ +

When NOT to use a map to visualize geographic data

+ +

If the relative locations of regions on the map aren’t the main focus of your visualization, consider using a bar or row chart instead. For example, sales by state are often better represented as a row or bar chart rather than a region map.

+ +

Bar chart as alternative to map

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/numbers.html b/_site/docs/doc-update-detection/questions/visualizations/numbers.html new file mode 100644 index 000000000..4c9d929f3 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/numbers.html @@ -0,0 +1,3051 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Numbers | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Numbers

+ +

The Numbers option is for displaying a single number, nice and big. The options for numbers include:

+ +

Number

+ +
    +
  • Adding character prefixes or suffixes to it (so you can do things like put a currency symbol in front or a percent at the end),
  • +
  • Setting the number of decimal places you want to include, and
  • +
  • Multiplying your result by a number (like if you want to multiply a decimal by 100 to make it look like a percent). If you want to divide by a number, then just multiply it by a decimal (e.g, if your result is 100, but you want it to display as 1, simply multiply it by 0.01).
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/pie-or-donut-chart.html b/_site/docs/doc-update-detection/questions/visualizations/pie-or-donut-chart.html new file mode 100644 index 000000000..8a5ee99e1 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/pie-or-donut-chart.html @@ -0,0 +1,3206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Pie and sunburst charts | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Pie and sunburst charts

+ +

A pie chart can be used when breaking out a metric by a single dimension. In Metabase, pies are donuts. A sunburst chart is a multi-dimensional pie chart with multiple breakouts.

+ +

Pie and sunburst charts

+ +

When to use a pie or sunburst chart

+ +

Pie charts can be used to visualize a metric as part of a whole. Sunburst charts can be used to visualize hierarchical or nested data, or display multiple levels of categorization.

+ +

Pie and sunburst charts work best when when the number of possible breakout values is small, like accounts by plan. These charts should only be used to visualize metrics that add up to 100% (like count or sum of total).

+ +

Pie charts should be used to communicate a general sense of the relative sizes of breakouts. If precise comparison is important so people can see the exact differences between values, or you have more than a few breakouts (like customers per country), it’s usually better to use a bar or row chart.

+ +

How to create a pie or sunburst chart

+ +

Pie and sunburst charts display a single metric across one or more breakouts. Both pie/donut charts and sunburst charts are available in the “Pie chart” option in the visualization sidebar.

+ +

For a simple pie chart, you’ll need a query with a single breakout and metric, for example:

+ + + + + + + + + + + + + + + + + + + + + + +
TypeSum of Quantity
Cat23
Bird14
Dog35
+ +

If your query has multiple metrics, you’ll be able to choose the metric for the chart in chart settings.

+ +

Plain pie

+ +

For a sunburst (multi-dimensional pie) chart, you’ll need a query with up to three breakouts and a numerical metric. Here’s an example of a query result with two breakouts, Type and Subtype:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeSubtypeSum of Quantity
CatSiamese4
CatPersian12
CatBengal7
BirdCrow5
BirdParrot9
DogCorgi10
DogPoodle13
DogBulldog7
DogHusky5
+ +

You can choose which breakouts to assign to the inner, middle, or outer rings of the sunburst chart in chart “Data” settings. If your query has multiple metrics, you’ll also be able to choose which metric to display. Here’s the sunburst chart for the example table above:

+ +

Sunburst with two levels

+ +

You don’t need to include the percentages in your query. Metabase will automatically compute the percentage of the total for each value of the metric (for example, Metabase will compute that 23 Cats make up 31.9% of all pets).

+ +

Pie and sunburst chart settings

+ +

To open the chart options, click on the gear icon at the bottom left of the screen. This will open a settings sidebar with Data and Display tabs.

+ +

Data settings

+ +

You can rename, reorder, or remove slices from the inner ring of a sunburst or pie chart. To reorder the pie slices, drag the cards with the slice names. To rename the slices, click on three dots next to the series name and enter a new name.

+ +

To change the color of the pie slices, click on the color circle next to the slice’s name. In sunburst charts, you can only change the color of the slices in the inner ring (the slices in the outer rings inherit the colors of their parent slices).

+ +

If your query has multiple metrics (columns), you can pick the column that should be depicted on the chart in the Measure dropdown.

+ +

To format the total displayed in the middle of the chart, click on the three dots next to the metric name in the Measure setting. The measure format options — including the “number of decimal places” option — will only apply to the total, and not to the percentage values or labels. To configure the display of the percentage values and labels, go to the display settings tab.

+ +

format sunburst

+ +

Display settings

+ +

You can configure whether to show:

+ +
    +
  • The legend next to the chart.
  • +
  • The total in the center of the chart. The format of the total can be changed in the data settings.
  • +
  • +

    The labels for the pie slices. The labels for the inner ring slices can be changed in the data settings.

    + +

    For sunburst charts with multiple breakouts, only the inner ring breakout will be displayed in the legend. By default, “Show labels” will be turned on. If you turn off “Show labels”, the only way to distinguish slices on a sunburst chart will be to hover over them.

    +
  • +
  • +

    The percentage values for the slices. If you choose to display percentages In the legend, but then toggle off Show legend, the percentage values won’t show up on the chart.

    + +

    You can always see percentage values for any slice by hovering over the slice.

    +
  • +
+ +

To change the number of decimal places in the percentage values, use the Number of decimal places setting in the Display tab. If you want to change the number of decimal places for the total in the center of the chart, go to data settings.

+ +

Settings showcase

+ +

To make the chart more legible, you can group slices smaller than a certain percentage into one slice by adjusting Minimum slice percentage. You’ll be able to see the categories and values in the Other slice by hovering over it:

+ +

Other slice

+ +

Currently, you can’t change the color or label of the Other slice.

+ +

Limitations and alternatives

+ +

Consider using a bar or row chart (or a stacked bar chart) or a pivot table instead of a pie or sunburst chart in the following cases:

+ +
    +
  • Your data has more than three breakouts
  • +
  • Your metrics don’t add up to 100% (for example, average rating - prefer a gauge chart in that case)
  • +
  • You have a lot of categories in each breakout
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/pivot-table.html b/_site/docs/doc-update-detection/questions/visualizations/pivot-table.html new file mode 100644 index 000000000..c30ca44d5 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/pivot-table.html @@ -0,0 +1,3078 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Pivot tables | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Pivot tables

+ +

Pivot tables allow you swap rows and columns, group data, and include subtotals in your table. You can group one or more metrics by one or more dimensions.

+ +

Pivot tables are not currently available for the following databases in Metabase:

+ +
    +
  • Druid
  • +
  • MongoDB
  • +
+ +

Pivot tables work for simple and custom questions with summarized data for all other officially supported databases. They don’t work for questions that lack aggregate data, and they don’t work for questions written in SQL, as Metabase would need to modify your SQL code in order to calculate subtotals. If you really need to use SQL, the workaround here is to create your question in two steps: first do all the complex things you need to do in SQL, save the results as a question, then use that saved SQL question as the starting point for a new GUI question which summarizes that data.

+ +

In the settings for the Pivot Table visualization, you can assign fields to one of three “buckets”:

+ +
    +
  • Fields to use for the table rows
  • +
  • Fields to use for the table columns
  • +
  • Fields to use for the table values
  • +
+ +

Let’s say we ask the following question in the notebook editor:

+ +

Pivot table notebook

+ +

From the Orders table, we’ve summarized by the count of orders and the average order total, and grouped by User → State, Product → Category, and Created At binned by year. Here’s our question visualized as a pivot table:

+ +

Pivot table options

+ +

We’ve assigned the fields User → State and Created At to table rows, and assigned the Product -> Category field to generate our columns: Doohickey, Gadget, and so on. We can drag and drop dimensions between the row and column buckets, and add aggregations to the table values bucket. For example, if we assign a field to the columns bucket, Metabase will pivot that field and render each unique value of that field as a column heading.

+ +

You can put multiple fields in the “rows” and “columns” buckets, but note that the order of the fields changes how Metabase displays the table: each additional field will nest within the previous field.

+ +

Where it makes sense, Metabase will automatically include subtotals for grouped rows. For example, as in the image above, because we’ve grouped our rows first by State, then by Created At, Metabase will list each year for each State, and aggregate the metric(s) for that subgroup. For orders placed in Wisconsin, Metabase would sum the count of orders for each category, and find the average annual order total in each product category in Wisconsin.

+ +

To collapse a group on a pivot table, you can click on the minus (–) button next to the group’s heading (or the plus (+) button to expand it). When you save a pivot table, Metabase will remember which groups were expanded and which were collapsed.

+ +

For more, check out How to create a pivot table to summarize your data.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/progress-bar.html b/_site/docs/doc-update-detection/questions/visualizations/progress-bar.html new file mode 100644 index 000000000..e331cfa4c --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/progress-bar.html @@ -0,0 +1,3121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Progress bars | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Progress bars

+ +

Progress bars are for comparing a single number to a goal value that you set.

+ +

Progress bar

+ +

When to use a progress bar

+ +

Progress bars are useful when you want to show the movement of a metric toward a goal, like assessing performance of a KPI, or tracking the percentage of of completion on a project.

+ +

Progress bars give you an option to set up an alert whenever the result of a question reaches the goal set in the progress bar settings. See Progress bar alerts.

+ +

How to create a progress bar

+ +

To create a progress bar you’ll need:

+ +
    +
  • +

    A query that returns a single number, like “Sum of order quantity”. Progress bar doesn’t work with breakouts.

    + +

    You can also use a query that returns several metrics in a single row:

    + + + + + + + + + + + + + + + + +
    Sum of QuantityAverage QuantityMax Quantity
    491017.32173
    +
  • +
+ +

In this case, the progress bar chart will use the metric in the first column (“Sum of quantity”). To change the metric, go to the editor and drag the metric you want to the first position in the Summarize block.

+ +
    +
  • +

    A goal value. The goal value should be a positive number. Currently, Metabase only supports setting a static goal (you can’t set a goal based on another query).

    + +

    The goal is set in the chart options.

    +
  • +
+ +

Progress bar KPI

+ +

Progress bar options

+ +

To open the chart options, click on the gear icon at the bottom left of the screen.

+ +

Format options will apply to both the result of the query and the goal value:

+ +

Progress bar with format applied

+ +

Selecting “Style: Percent” in format options will only change how the result of the query is formatted: for example, 17 will be formatted as 1700%. If you instead want to display the query result as a percentage of the goal, you’ll need to calculate that percentage in your query. For example, to display the count of orders as a percentage of the goal of 20, use custom expressions to return “Count of orders divided by 20”, and format the result as a percentage.

+ +

Limitations and alternatives

+ +
    +
  • +

    Progress bars assume that your objective is to increase a metric. If the objective is to decrease or reduce a metric, consider using the gauge chart.

    +
  • +
  • +

    Progress bars don’t support breakouts. If you’d like to display progress of a metric towards a goal across a breakout, consider using a bar or line chart with a goal line.

    +
  • +
+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/sankey.html b/_site/docs/doc-update-detection/questions/visualizations/sankey.html new file mode 100644 index 000000000..13e15e497 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/sankey.html @@ -0,0 +1,3194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Sankey charts | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Sankey charts

+ +

Sankey charts show how data flows through multi-dimensional steps. They’re useful for showing which elements, called nodes, contribute to the overall flow.

+ +

Left-aligned sankey chart

+ +

Sankey data shape

+ +

To create a Sankey chart, you’ll need at least three columns in your results:

+ +
    +
  • Source column: specifies a node in the Sannkey flow.
  • +
  • Target column: specifies a receiving node.
  • +
  • Count column: value that determines the thickness of the target node.
  • +
+ +

If you had raw page views where each row had a source page (like the title of a referrer page) and a target page (like the title for the current page view), you could summarize by count and group by the source, then the target.

+ +

Sankey summarize count and group by source and target

+ +

Here’s the data shape used to create the chart above.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source pageTarget pageTotal Visitors
EntryHomepage584
HomepageProduct Page2,700
Product PageAdd to Cart572
Add to CartCheckout2,490
CheckoutPurchase1,756
HomepageSearch2,427
SearchProduct Page2,027
Product PageAdd to Cart2,203
Add to CartCheckout1,475
SearchProduct Page1,563
CheckoutPurchase1,041
HomepageExit810
Product PageCheckout815
CheckoutPurchase2,217
HomepageExit1,020
+ +

See data options.

+ +

Circular dependencies won’t work

+ +

If some of your sources point to targets that point back to the same sources, Metabase won’t be able to create a Sankey chart.

+ +

Sankey data options

+ +

To select which columns Metabase should use as the source, target, and values for the Sankey chart, click on the settings icon in the bottom right to view the Data tab.

+ +

Sankey data options

+ +

Your data can include more than three columns, but each row must include the required three columns: source, target, and a value to scale the size of the target node.

+ +

Sankey display options

+ +

You can change a charts alignment, edge labels, and edge colors.

+ +

Alignment

+ +

You can select left, right, or justified alignment for the Sankey chart. Alignment determines how the chart should display the end nodes (a.k.a. leaf nodes or terminal nodes).

+ +

The chart in the section above is left-aligned. The end nodes, Exit and Purchase, are aligned to the left.

+ +

For right alignment, the end nodes, Exit and Purchase, move to the chart’s right:

+ +

Right-aligned sankey chart

+ +

In this case, justified alignment looks the same, as the end nodes move to take up the whole chart.

+ +

Edge labels

+ +

Whether an edge (a.k.a. link or arrow) displays its value. Options for displaying labels include auto, compact, or full formatting.

+ +

Edge color

+ +

Sankey gray edges

+ +

Options for edge colors include:

+ +
    +
  • Gray: All edges are gray. Nodes retain their color.
  • +
  • Source: The source node determines the edge colors. The source node is the node to the left of an edge.
  • +
  • Target: The target node determines the edge colors. The target node is the node to the right of an edge.
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/scatterplot-or-bubble-chart.html b/_site/docs/doc-update-detection/questions/visualizations/scatterplot-or-bubble-chart.html new file mode 100644 index 000000000..6e42952e8 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/scatterplot-or-bubble-chart.html @@ -0,0 +1,3049 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Scatterplots and bubble charts | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Scatterplots and bubble charts

+ +

Scatterplots are useful for visualizing the correlation between two variables, like comparing the age of your users vs. how many dollars they’ve spent on your products. To use a scatterplot, you’ll need to ask a question that results in two numeric columns, like Count of Orders grouped by Customer Age. Alternatively, you can use a table and select the two numeric fields you want to use in the chart options.

+ +

If you have a third numeric field, you can also create a bubble chart. Select the Scatter visualization, then open up the chart settings and select a field in the bubble size dropdown. This field will be used to determine the size of each bubble on your chart. For example, you could use a field that contains the total dollar amount for each x-y pair — i.e. larger bubbles for larger total dollar amounts spent on orders.

+ +

Scatterplots and bubble charts also have similar chart options as line, bar, and area charts, including the option to display trend or goal lines.

+ +

Scatter

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/table.html b/_site/docs/doc-update-detection/questions/visualizations/table.html new file mode 100644 index 000000000..ab200af1c --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/table.html @@ -0,0 +1,3346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Tables | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Tables

+ +

The Table option is good for looking at tabular data (duh), or for lists of things like users or orders. The visualization options for tables allow you to add, hide, or rearrange fields in the table you’re looking at, as well as modify their formatting. Check out Everything you can do with the table visualization.

+ +

Rearranging, adding, and removing columns

+ +

Open up the settings for your table visualization and you’ll see the Columns tab, which displays all the columns currently being shown in the table. To hide a column, click the eye icon.

+ +

To manage these columns, including columns from linked tables, just click add or remove columns. Check the boxes next to the columns you want to show in the visible section, or uncheck to hide them.

+ +

When viewing tables, you can click on the gear icon in the bottom left to bring up the columns picker. Click Add or remove columns to search for and pick columns, including columns from related tables.

+ +

Adding or removing columns

+ +

Admins (and people in groups with access to table metadata) can hide columns across your entire Metabase by marking them as hidden in the table metadata settings.

+ +
+

Hiding columns should not be used to secure sensitive information. Hiding columns in table visualization settings only affects the visibility of the columns in the visualization, not in the query results. Even people with view-only permissions to the question will be able to change the visualization settings and unhide columns. To exclude a column from the results of a specific query, uncheck the column in the “Data” block of the query builder.

+
+ +

To rearrange the order of the columns, simply click and drag any of the columns in the sidebar. You can also click on a column’s heading in the table and drag the column to another position in the table.

+ +

Add row numbers to a table

+ +

To number the rows of a table, click on the gear icon in bottom left to bring up the table formatting sidebar. In the Columns tab, and toggle on Show row index. Metabase will add a column to the left of the table displaying a number for each row.

+ +

Add row numbers to a table

+ +

Resize columns

+ +

To change the width of a column, you can click and drag the edges of the column’s header.

+ +

Column heading options for filtering and summarizing

+ +

Click on a column heading and Metabase will present quick options for filtering and summarizing the data. The options for the column depend on the column’s data type (ID, Text, Number, Date).

+ +

Filter by this column

+ +

You can enter a value and filter the column value:

+ +

Text filters:

+ +
    +
  • Is / Is not
  • +
  • Contains / Does not contain
  • +
  • Starts with / Ends with
  • +
  • Is empty / Not empty
  • +
+ +

Number filters:

+ +
    +
  • Between
  • +
  • Greater than / Less than
  • +
  • Greater than or equal to / Less than or equal to
  • +
  • Equal to / Not equal to
  • +
  • Is empty / Not empty
  • +
+ +

Distribution

+ +

Clicking on Distribution will summarize the data by counting the rows and grouping the counts by the values in the column.

+ +

Distinct values

+ +

Get a count of unique values.

+ +

Combine columns

+ +

You can combine one or more text columns. For example, a first name column with a last name column.

+ +

You can tell Metabase how to combine the columns by specifying a separator, like a space, or comma, or the word “Danger”.

+ +

Extract day, month…

+ +

From a datetime, you can grab:

+ +
    +
  • Hour of day: 0, 1, 2…
  • +
  • Day of month: 0, 1, 2…
  • +
  • Day of week: Monday, Tuesday…
  • +
  • Month of year: Jan, Feb…
  • +
  • Quarter of year: Q1, Q2…
  • +
  • Year: 2024, 2025…
  • +
+ +

Extract domain, subdomain, host, or path

+ +

Grab the domain or host from a URL or email. So if you have https://www.example.com/path/to/page#heading-on-page:

+ +
    +
  • Host: example.com
  • +
  • Domain: example
  • +
  • Subdomain: www
  • +
  • Path: /path/to/page
  • +
+ +
+

Extracting parts of a URL or email is unavailable for MongoDB, SQLite, and SQL Server. For Druid, extracting domain and host is only available for the Druid-JDBC driver.

+
+ +

Sum over time

+ +

Add up all the values and group by a time period, generally by month.

+ +

Column formatting options

+ +

To format the display of any column in a table, click on the column heading and choose the Formatting option (you can also get there by clicking on the gear on any column when in the Columns tab of the visualization settings).

+ +

Column formatting

+ +

The options you see will differ depending on the type of column you’re viewing:

+ +

Text formatting options

+ +

Title

+ +

You can rename the column.

+ +

Align text

+ +

You can display the text on the left, right, or in the middle (i.e., centered) of the column.

+ +

Wrap text

+ +

You can toggle text wrapping, which is useful for columns with long text values like comments.

+ +

Display as

+ +

You can display a column as:

+ +
    +
  • Text
  • +
  • Link
  • +
  • Email link
  • +
  • Image
  • +
  • Automatic (Metabase guesses based on the values).
  • +
+ + + +

If you select link, you can also change the text displayed, and use parameters for both the link text and the link’s URL.

+ +

For example, you could create a dynamic URL using a parameter from another column in the results:

+ +
 https://www.example.com/{{category}} 
+
+ +

In the above example, Metabase would take the value for the category column for that row (in this case widget), and insert it into the URL:

+ +
https://www.example.com/widget
+
+ +

Display URL as an image

+ +

If you select image, and the text is a link to an image asset, Metabase will display the image in the table cell.

+ +

Date formatting options

+ +

Date formatting options include the same options as Text formatting, as well as:

+ +

Align date

+ +

You can display the date on the left, right, or in the middle (i.e., centered) of the column.

+ +

Date style

+ +

Styles include:

+ +
    +
  • April 1, 2024
  • +
  • 1 April 2024
  • +
  • Monday, April 1, 2024
  • +
  • 4/1/2024
  • +
  • 1/4/2024
  • +
  • 2024/4/1
  • +
+ +

Abbreviate days and months

+ +

If you select a date style that includes words, this toggle will abbreviate them. For example:

+ +
    +
  • Unabbreviated: Monday, April 1, 2024
  • +
  • Abbreviated: Mon, Apr 1, 2024
  • +
+ +

Show the time

+ +

This option determines whether Metabase includes the time along with the date.

+ +
    +
  • Off
  • +
  • HH:MM
  • +
  • HH:MM:SS
  • +
  • HH:MM:SS:MS
  • +
+ +

Time style

+ +

You can choose either 12-hour clock style, or 24-hour clock style.

+ +
    +
  • 5:24 PM (12-hour clock)
  • +
  • 17:24 (24-hour clock)
  • +
+ +

Number formatting options

+ +

Show a mini bar chart

+ +

This option displays a small horizontal bar next to each number in this column to show its size relative to the other values in the column.

+ +

Style

+ +

Number styles include:

+ +
    +
  • Number
  • +
  • Percent
  • +
  • Scientific
  • +
  • Currency
  • +
+ +

Separator style

+ +

Gives you various options for how commas and periods are used to separate the number.

+ +
    +
  • 100,000.00
  • +
  • 100 000,00
  • +
  • 100.000,00
  • +
  • 100000.00
  • +
  • 100’000.00
  • +
+ +

Number of decimal places

+ +

Forces the number to be displayed with exactly this many decimal places.

+ +

Multiply by a number

+ +

Multiplies each number in this column by whatever you type here. Just don’t type an emoji here; there is a nontrivial chance that it will manifest a temporal vortex.

+ +

Add a prefix/suffix

+ +

Lets you put a symbol, word, or whatever before or after each cell’s value.

+ +

Currency formatting options

+ +

Currency columns have all the same options as numbers, plus the following:

+ +

Unit of Currency

+ +

Lets you change the unit of currency from whatever the system default is.

+ +

Currency label style

+ +

Allows you to switch between displaying the currency label as:

+ +
    +
  • a symbol (like $)
  • +
  • a code (like USD)
  • +
  • the full name of the currency (like “US dollars”)
  • +
+ +

Where to display the unit of currency

+ +

Lets you toggle between showing the currency label in the column heading or in every cell in the column.

+ +

Conditional table formatting

+ +

Sometimes it’s helpful to highlight certain rows or columns in your tables when they meet a specific condition. You can set up conditional formatting rules by going to the visualization settings while looking at any table, then clicking on the Conditional Formatting tab.

+ +

Conditional formatting

+ +

When you add a new rule, you’ll first need to pick which column(s) should be affected. Your columns can be formatted in one of two ways:

+ +
    +
  • Single color. Pick single color if you want to highlight cells in the column if they’re greater, less than, or equal to a specific number, or if they match or contain a certain word or phrase. You can optionally highlight the whole row of a cell that matches the condition you pick so that it’s easier to spot as you scroll down your table.
  • +
  • Color range. Choose color range if you want to tint all the cells in the column from smallest to largest or vice versa. This option is only available for numeric columns.
  • +
+ +

You can set as many rules on a table as you want, and change the order in which those rules are applied. If two or more rules disagree with each other, the rule that’s on the top of your list of rules will win. You can click and drag your rules to reorder them, and click on a rule to edit it.

+ +

Table pagination on dashboard cards

+ +

When you add a table to dashboard, the table will be scrollable by default. You can paginate the rows by:

+ +
    +
  1. Clicking on the Pencil icon to edit the dashboard.
  2. +
  3. Hovering over the dashcard containing the table, and clicking the Visualization icon.
  4. +
  5. In the Columns tab, toggle on Paginate results.
  6. +
+ +

Paginate table results on dashboard card

+ +

Pivoted tables

+ +
+

This auto-pivoting is distinct from the pivot table visualization.

+
+ +

If your table is a result that contains one numeric column and two grouping columns, Metabase will also automatically “pivot” your table, like in the example below. Pivoting takes one of your columns and rotates it 90 degrees (“pivots” it) so that each of its values becomes a column heading. If you open up the visualization settings by clicking the gear icon, you can choose which column to pivot in case Metabase got it wrong; or you can also turn the pivoting behavior off entirely.

+ +

Pivot table

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/tooltips.html b/_site/docs/doc-update-detection/questions/visualizations/tooltips.html new file mode 100644 index 000000000..6b2a55363 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/tooltips.html @@ -0,0 +1,3065 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Tooltips | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Tooltips

+ +

When you hover over a data point on a chart in Metabase, you’ll see a tooltip about that data.

+ +

Tooltip

+ +

Customizing tooltips with multiple metrics

+ +

On line, bar, and area charts, you can display the values from multiple metrics either on the chart, or in the tooltips that Metabase adds to the data points on hover.

+ +

For example, if you have a question with two metrics (i.e., two summarizations - they don’t have to be Metabase metrics), like this question that has both the count and average of subtotal:

+ +

Question with multiple summarizations

+ +

You can display the summarizations like so, with both the count and average on the chart.

+ +

Count and average

+ +

Or you could display one of the metrics on the chart, and include the other metric(s) in the tooltip. To do this, remove one of the metrics from the chart by going to the Data tab in the visualization settings and clicking the X on the metric(s) you want to remove.

+ +

Removing a metric will give you the option to add it as an additional metric to the tooltip. In the visualization settings, click on the Display tab, and add Additional tooltip metrics. Only metrics included in the summarization step of the question are available to add to the tooltip.

+ +

Add additional tooltip metrics from the display tab. Only available when your chart has multiple multiple metrics

+ +

Here we’ve kept the count on the chart, but now when you hover over a bar on the chart, the tooltip also includes the relevant average.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/trend.html b/_site/docs/doc-update-detection/questions/visualizations/trend.html new file mode 100644 index 000000000..e9e0e5760 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/trend.html @@ -0,0 +1,3072 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Trend | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Trend

+ +

Trend settings

+ +

The Trend visualization is great for displaying how a single number compares with:

+ +
    +
  • Previous time period(s).
  • +
  • Custom values, like a target or goal.
  • +
  • Values from another column.
  • +
+ +

To use this visualization, you’ll need to have a single number grouped by a Time field, like the Count of Orders by Created At.

+ +

By default, the Trend chart will display the value of the number during the most recent period, as well as how much the number has increased or decreased compared to its value in the previous period. The period is determined by your group-by field; if you’re grouping by Day, the Trend will show you the most recent day compared to the day before that.

+ +

By default, Trends will display increases as green (i.e., “good”) and decreases as red (“bad”). If your number is something where an increase is bad and a decrease is good (such as Bounce Rate, or Costs), you can reverse this behavior in the visualization settings.

+ +

Adding comparisons

+ +

Add comparison to a trend chart

+ +

To add a comparison, click on the gear icon in the lower left (next to Visualization). In the Data tab in the left sidebar, click Add comparison. You can select from:

+ +
    +
  • Previous time period
  • +
  • Previous value. If there is no previous value, Metabase will ignore the value so the chart doesn’t show a comparison with a null value.
  • +
  • Custom value.
  • +
  • Value from another column. Metabase will only show this option if your results contain multiple columns with aggregate values in your results (e.g., if you have two Summarize columns).
  • +
+ +

You can add up to three comparisons.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/visualizing-results.html b/_site/docs/doc-update-detection/questions/visualizations/visualizing-results.html new file mode 100644 index 000000000..e99e03455 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/visualizing-results.html @@ -0,0 +1,3212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Visualization overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Visualization overview

+ +

While tables are useful for looking up information or finding specific numbers, it’s usually easier to see trends and make sense of data using charts.

+ +

Visualize query results

+ +

The query builder will automatically select an appropriate chart to visual your results. With native queries, however, you’ll need to manually select a chart type.

+

Visualizing questions in the query builder

+ +

To visualize results of a question built in the query builder, click on the Visualize button under the last query builder step. Metabase will select a chart type most appropriate for your data, but you can change the visualization type. You can also toggle between the visualization and the table of results.

+ +

You can switch between the visualization view and the query builder using the Visualization/Editor button in the top right.

+ +

Switch to editor

+ +

Visualizing native questions

+ +

To visualize results of a native query, click on the Visualization button in the bottom of the screen and select a visualization type.

+ +

Visualize a native query

+ +

As long as the shape of the native query results is appropriate for the chart type - for example, a metric grouped by a date column for a trend chart - you’ll be able to use to use all chart types, except pivot tables. Pivot tables are currently unavailable for native queries.

+ +

Change visualization type

+ +

To change how the answer to your question is displayed, click on the Visualization button in the bottom-left of the screen to open the visualization sidebar.

+ +

Visualization options

+ +

If a particular visualization doesn’t really make sense for your answer, that option will appear in the “Other charts” section. You can still select one of these other charts, though you might need to fiddle with the chart options to make the chart work with your data.

+ +

Not sure which visualization type to use? Check out Which chart should you use?

+ +

Visualization options

+ +

Options for a chart

+ +

Each visualization type has its own advanced options. To change the settings for a specific chart, for example a row chart, click on the Gear button in the bottom left.

+ +

Area charts

+ +

Area charts are useful when comparing the proportions of two metrics over time. Both bar and area charts can be stacked.

+ +

Stacked area chart

+ +

Bar charts

+ +

Bar charts are great for displaying a number grouped by a category (e.g., the number of users you have by country).

+ +

Bar chart

+ +

Combo charts

+ +

Combo charts let you combine bars and lines (or areas) on the same chart.

+ +

Line + bar

+ +

Detail

+ +

The Detail visualization shows a single result record (row) in an easy-to-read, two-column display.

+ +

Detail of a record in the account table

+ +

Funnel charts

+ +

Funnels are commonly used in e-commerce or sales to visualize how many customers are present within each step of a checkout flow or sales cycle. At their most general, funnels show you values broken out by steps, and the percent decrease between each successive step.

+ +

Funnel

+ +

Gauges

+ +

Gauges allow you to show a single number in the context of a set of colored ranges that you can specify.

+ +

Gauge

+ +

Line charts

+ +

Line charts are best for displaying the trend of a number over time, especially when you have lots of x-axis values. For more, check out our Guide to line charts and Time series analysis tutorials.

+ +

Trend lines

+ +

Maps

+ +

When you select the Map visualization, Metabase will automatically try and pick the best kind of map to use based on the table or result set.

+ +

Region map

+ +

Numbers

+ +

The Numbers option is for displaying a single number, nice and big.

+ +

Number

+ +

Pie, donut, and sunburst charts

+ +

A pie chart or donut chart can be used when breaking out a metric by a single dimension, especially when the number of possible breakouts is small, like accounts by plan.

+ +

A sunburst chart is a pie chart with more than one ring to show the data broken out by additional dimensions.

+ +

Donut

+ +

Pivot tables

+ +

Pivot tables allow you swap rows and columns, group data, and include subtotals in your table. You can group one or more metrics by one or more dimensions.

+ +

Pivot table options

+ +

Progress bars

+ +

Progress bars are for comparing a single number to a goal value that you set.

+ +

Progress bar

+ +

Row charts

+ +

Row charts are good for visualizing data grouped by a column that has a lot of possible values, like a Vendor or Product Title field.

+ +

Row chart

+ +

Tables

+ +

The Table option is good for looking at tabular data (duh), or for lists of things like users or orders.

+ +

Conditional formatting

+ + + +

The Trend visualization is great for displaying how a single number has changed between two time periods.

+ +

Trend settings

+ +

Histograms

+ +

If you have a bar chart like Count of Users by Age, where the x-axis is a number, you’ll get a special kind of bar chart called a histogram where each bar represents a range of values (called a “bin”).

+ +

Histogram

+ +

Sankey charts

+ +

Sankey charts show how data flows through multi-dimensional steps.

+ +

Left-aligned sankey chart

+ +

Waterfall charts

+ +

Waterfall charts are a kind of bar chart useful for visualizing results that contain both positive and negative values.

+ +

Waterfall chart

+ +

Scatterplots and bubble charts

+ +

Scatterplots are useful for visualizing the correlation between two variables, like comparing the age of your people using your app vs. how many dollars they’ve spent on your products.

+ +

Scatter

+ +

Styling and formatting data in charts

+ +

Chart formatting options

+ +

You can access formatting options for the columns used in a chart. Just open the visualization settings by clicking on the Gear icon in bottom left.

+ +

Options differ depending on the chart, and can include settings for the chart’s data, its display, and its axes.

+ +

See also Formatting defaults.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/questions/visualizations/waterfall-chart.html b/_site/docs/doc-update-detection/questions/visualizations/waterfall-chart.html new file mode 100644 index 000000000..11c096768 --- /dev/null +++ b/_site/docs/doc-update-detection/questions/visualizations/waterfall-chart.html @@ -0,0 +1,3049 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Waterfall charts | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Waterfall charts

+ +

Waterfall charts are a kind of bar chart useful for visualizing results that contain both positive and negative values. Each bar on a waterfall chart shows either an increase or decrease, with a final bar on the right of the chart that represents the total value.

+ +

Waterfall chart

+ +

In the example above, the waterfall chart displays “Profit” for each “Product:” apples, bananas, oranges, peaches, and mangos. From left to right, each bar indicates the change in total. The products with green bars indicate positive values (they made a profit). Peaches, however, lost money, indicated by a red bar, which signals a negative value. The bar at the end shows the total profit of all products combined. You can show values on each bar, and change the colors for increases and decreases.

+ +

For waterfall charts, you’ll want a query that is a single metric grouped by a single dimension: by time or category.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/setting-up-metabase.html b/_site/docs/doc-update-detection/setting-up-metabase.html new file mode 100644 index 000000000..da8f3ac10 --- /dev/null +++ b/_site/docs/doc-update-detection/setting-up-metabase.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/bigquery-drive.html b/_site/docs/doc-update-detection/troubleshooting-guide/bigquery-drive.html new file mode 100644 index 000000000..1bd73a5ba --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/bigquery-drive.html @@ -0,0 +1,3058 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting BigQuery and Google Drive connections in Metabase | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting BigQuery and Google Drive connections in Metabase

+ +

This page explains how to connect a BigQuery data source, including one that uses a file stored in Google Drive, like a Google Sheet (GSheets).

+ +

403 Forbidden POST error

+ +

If you encounter an error that looks like this:

+ +
403 Forbidden POST https://www.googleapis.com/bigquery/v2/projects/PROJECT-NAME/queries { "code" : 403, "errors" : [ { "domain" : "global", "message" : "Access Denied: BigQuery BigQuery: Permission denied while getting Drive credentials.", "reason" : "accessDenied" } ], "message" : "Access Denied: BigQuery BigQuery: Permission denied while getting Drive credentials.", "status" : "PERMISSION_DENIED" }
+
+ +

You may have forgotten to share your Google Drive source with the service account email. Once that’s been fixed, that error should disappear and you’ll be able to view and query your data source.

+ +

Further reading

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/bugs.html b/_site/docs/doc-update-detection/troubleshooting-guide/bugs.html new file mode 100644 index 000000000..876d8dbc4 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/bugs.html @@ -0,0 +1,3057 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reporting a bug | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Reporting a bug

+ +

If you come across something that looks like a bug, please start by searching our Github issues to see if it has already been reported. If it has, please let us know you’re experiencing the same issue by reacting with a thumbs up emoji or adding a comment to provide additional information.

+ +

If the bug has not yet been reported, go ahead and open a bug report. The following information will help us reproduce your issue:

+ +
    +
  1. Metabase server logs
  2. +
  3. Javascript console logs
  4. +
  5. Whether it can be reproduced on the sample database
  6. +
  7. Your Metabase version
  8. +
  9. Where Metabase is running (Docker image, Linux/Ubuntu, etc.)
  10. +
  11. Which database you are using
  12. +
  13. What browser version you are using
  14. +
  15. Screenshots (if relevant)
  16. +
+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/cant-log-in.html b/_site/docs/doc-update-detection/troubleshooting-guide/cant-log-in.html new file mode 100644 index 000000000..c862bb547 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/cant-log-in.html @@ -0,0 +1,3086 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +People can't log in to Metabase | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

People can’t log in to Metabase

+ +

Reset password

+ +

To reset a password for your Metabase instance, see:

+ + + +

To reset password for your Metabase Store account, contact support.

+ +

No access to Metabase login page

+ +

If you’re not a Metabase admin, you’ll have to tag them for help here.

+ +
    +
  1. Check that you have the correct site URL from Settings > Admin settings > General.
  2. +
  3. Check if the account is deactivated.
  4. +
+ +

No access to Metabase Cloud account

+ +

The admin password for store.metabase.com (where you can find payment and subscription info) is not necessarily the same as the password for your Metabase instance (where you log in to look at data).

+ +

If you’ve forgotten your Metabase Cloud admin password, you can contact support to reset the password.

+ + + + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/cant-see-tables.html b/_site/docs/doc-update-detection/troubleshooting-guide/cant-see-tables.html new file mode 100644 index 000000000..b6a83c525 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/cant-see-tables.html @@ -0,0 +1,3155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +I can't see my tables | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

I can’t see my tables

+ +

You’ve connected Metabase to a database, but:

+ +
    +
  • you don’t see the tables in the Table Metadata section of the Admin Panel,
  • +
  • the tables don’t appear in the Data Browser,
  • +
  • the tables don’t show up as possible data sources when you create a query using the Query Builder, or
  • +
  • you can no longer see tables that you used to be able to see.
  • +
+ +

Check for browser issues

+ +
    +
  1. Clear your browser cache.
  2. +
  3. Check if a browser extension or plugin is interfering with Metabase: +
      +
    • Disable all extensions and plugins,
    • +
    • Open Metabase in an incognito browser session, or
    • +
    • Open Metabase in a different browser.
    • +
    +
  4. +
+ +

Explanation

+ +

Sometimes your browser will show an old cached list of tables. Browser extensions can also prevent pages from loading correctly.

+ +

Test the database connection

+ +
    +
  1. Go to the Metabase SQL editor.
  2. +
  3. Test the connection to your database by running: +
    SELECT 1
    +
    +
  4. +
+ +

If you get an error, see Troubleshooting database connections.

+ +

Explanation

+ +

Something may have changed on the database side (if you were previously connected). For example, you may have connected to a test database while doing an evaluation but are now in a production environment.

+ +

Check table access

+ +

To make sure that your table is actually queryable by Metabase:

+ +
    +
  1. Go to the Metabase SQL editor.
  2. +
  3. Look for your table: +
    SELECT *
    +FROM your_table
    +
    +
  4. +
+ +

If there’s a problem with your table name or database permissions, you’ll get an error message like:

+ + + +

For less common errors, try searching or asking the Metabase community.

+ +

Explanation

+ +

Something might have changed on database side: your table could’ve been renamed or dropped, or the permissions revoked.

+ +

Metabase permissions

+ +

If there are only a few people who can’t view tables, see A user group has the wrong access to a table or schema.

+ +

Explanation

+ +

Metabase uses a group-based permission model: people belong to groups, and admins can set permissions to hide tables from groups.

+ +

Check if the table is hidden

+ +
    +
  1. Go to Admin > Table Metadata and choose the database where your table is.
  2. +
  3. Check that Visibility of your table is not set to Hidden.
  4. +
+ +

Explanation

+ +

If an Admin sets the table visibility to Hidden, you will be able to use SQL to query the table but will not be able to see it in Browse > Databases or as a data source in the Query Builder.

+ +

MongoDB

+ +

MongoDB lets you “successfully connect” to any collection name, even if the collection doesn’t exist. If you don’t see a MongoDB collection in Metabase, make sure that:

+ +
    +
  • you have the correct collection name, and
  • +
  • the collection is non-empty.
  • +
+ + + + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/cant-send-email.html b/_site/docs/doc-update-detection/troubleshooting-guide/cant-send-email.html new file mode 100644 index 000000000..6bcc6250b --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/cant-send-email.html @@ -0,0 +1,3089 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Metabase isn't sending email | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Metabase isn’t sending email

+ +

You have told Metabase to send email notifications, but:

+ +
    +
  • the notifications aren’t arriving.
  • +
+ +

Before any other troubleshooting, try sending a test email to isolate the problem.

+ +

Can you successfully send a test email?

+ +

Root cause: The host, port, email address, or password may have been set up incorrectly, or the email server’s host and port have been set up incorrectly.

+ +

Steps to take:

+ +
    +
  1. Navigate to the Admin Panel and click Email in the left sidebar.
  2. +
  3. Confirm that your host, port, email address, and password are entered correctly. If they are, click Save changes. If your changes have successfully saved, you’ll see an option to Send test email.
  4. +
  5. Click Send test email. The test email will go the address associated with your Metabase account.
  6. +
  7. Verify that the email is delivered to your account.
  8. +
  9. If the message is not sent or an error message is displayed in Metabase, try to use the same account credentials in another email program and see if they work. See the logs for more detailed error by navigating to Troubleshooting and click Logs in the left sidebar.
  10. +
+ +

Is the mail server actually sending the message?

+ +

Root cause: Some email delivery services have very specific rules regarding valid “from” addresses, or have test modes that restrict delivery.

+ +

Steps to take:

+ +
    +
  1. Check that your delivery service allows you to send email to the domain you’re trying to get email sent to. (Exactly how to do this depends on the delivery service you’re connecting to.)
  2. +
  3. Make sure you’ve whitelisted the “from” address that you’re using for Metabase.
  4. +
  5. Check the mail server’s logs for any error messages.
  6. +
  7. If you have access to your email delivery service’s outbound queue or a dashboard, check that for errors as well.
  8. +
+ +

Is the mail being sent but not arriving?

+ +

Root cause: The message is being sent correctly, but isn’t being received (at least, not where you expect it to be).

+ +

Steps to take:

+ +
    +
  1. Check whether email sent to other accounts is arriving, e.g., are colleagues receiving their notifications?
  2. +
  3. If so, check your spam folder, any forwarding rules you have set up, etc.
  4. +
  5. Check whether you’re using the same email provider as the people who are receiving their messages. If not, the problem might be with deliverability rules—look into signing your emails with DomainKeys Identified Mail (DKIM).
  6. +
+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/cant-view-or-edit.html b/_site/docs/doc-update-detection/troubleshooting-guide/cant-view-or-edit.html new file mode 100644 index 000000000..e8a806e3e --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/cant-view-or-edit.html @@ -0,0 +1,3094 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Can't view or edit | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Can’t view or edit

+ +
    +
  1. Clear your browser cache.
  2. +
  3. Check if a browser extension or plugin is interfering with Metabase: +
      +
    • Disable all extensions and plugins,
    • +
    • Open the link in an incognito browser session, or
    • +
    • Open the link in a different browser.
    • +
    +
  4. +
  5. If you aren’t the creator of the question, dashboard, or model, check if you have permissions to the collection where the item is saved.
  6. +
  7. Check the Trash.
  8. +
+ +

Can’t view cards on a dashboard

+ +
    +
  1. Check the collections where each question (or card) on the dashboard is saved.
  2. +
  3. If a saved question is in a collection that you don’t have access to, you’ll need to ask someone with edit access to the collection to: +
      +
    • Grant you permission to the collection.
    • +
    • Or, to move the saved question to a collection that you have permissions to.
    • +
    +
  4. +
  5. If the steps above don’t solve your problem, ask your Metabase admin if you have permission to the database that’s used by the question.
  6. +
+ +

Explanation

+ +

Moving a dashboard to a different collection doesn’t move the dashboard’s questions into that collection.

+ +

If the saved questions are stored in a restricted collection (such as someone’s personal folder), then other groups won’t be able to view those cards.

+ +

Someone with edit permissions (your Metabase admin is probably a safe bet) will need to move those questions into a collection that you have permissions to.

+ + + + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/create-har-file.html b/_site/docs/doc-update-detection/troubleshooting-guide/create-har-file.html new file mode 100644 index 000000000..d3aa02ab0 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/create-har-file.html @@ -0,0 +1,3129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Creating a HAR file for troubleshooting | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Creating a HAR file for troubleshooting

+ +

HAR (short for HTTP Archive) files record network requests generated by your browser. HAR files can be helpful when troubleshooting issues with Metabase performance.

+ +
+

HAR files can contain sensitive information that you submit during the recording, like passwords and API keys. Before sharing the HAR file with anyone, review the file contents in a text editor.

+
+ +

To create the HAR file, follow the instructions for your web browser:

+ + + +

Create a HAR file in Chrome

+ +
    +
  1. +

    Open Chrome Developer tools. +You can right-click anywhere on the page and select “Inspect”.

    +
  2. +
  3. +

    In Developer tools, switch to the Network tab. +The network log recording should start automatically.

    +
  4. +
  5. +

    With the Network tab open and recording in progress, repeat the steps to reproduce the issue.

    +
  6. +
  7. +

    Once you’re finished reproducing the issue, right-click anywhere in the table of network calls and select Save all as HAR with content.

    +
  8. +
+ +

Create a HAR file in Edge

+ +
    +
  1. +

    Open Edge Developer tools. You can right-click anywhere on the page and select “Inspect”.

    +
  2. +
  3. +

    In Developer tools, switch to the Network tab (look for the Wi-Fi icon). The network log recording should start automatically.

    +
  4. +
  5. +

    With the Network tab open and recording in progress, repeat the steps to reproduce the issue.

    +
  6. +
  7. +

    Once you’re finished reproducing the issue, right-click anywhere in the table and select Save all as HAR with content

    +
  8. +
+ +

Create a HAR file in Firefox

+ +
    +
  1. +

    Open Firefox Developer tools. You can right-click anywhere on the page and select “Inspect”.

    +
  2. +
  3. +

    In Developer tools, switch to the Network tab.

    +
  4. +
  5. +

    With the Network tab open and recording in progress, repeat the steps to reproduce the issue.

    +
  6. +
  7. +

    Once you’re finished reproducing the issue, right-click anywhere in the table of network calls and select Save All As HAR.

    +
  8. +
+ +

Create a HAR file in Safari

+ +
    +
  1. +

    If you haven’t yet, enable the Develop menu by going to Safari > Settings > Advanced, and select Show features for web developers.

    +
  2. +
  3. +

    Open the Safari developer tools by going to Develop > Show Web Inspector.

    +
  4. +
  5. +

    In Developer tools, switch to the Network tab. The network log recording should start automatically.

    +
  6. +
  7. +

    With the Network tab open and recording in progress, repeat the steps to reproduce the issue.

    +
  8. +
  9. +

    Once you’re finished reproducing the issue, click on Export in the top right of the Network tab.

    +
  10. +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/data-permissions.html b/_site/docs/doc-update-detection/troubleshooting-guide/data-permissions.html new file mode 100644 index 000000000..a83f180d8 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/data-permissions.html @@ -0,0 +1,3185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting data permissions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting data permissions

+ +

If a person has the wrong level of access to the data that’s returned by a question or query, you’ll need to troubleshoot different levels of data permissions, starting from the most granular.

+ +

Row and column permissions

+ + + +

Native query (SQL) permissions

+ + + +

Table or schema permissions

+ + + +

A user group can’t access the SQL editor

+ +
    +
  1. Ensure scripts are loading by disabling browser extensions and refreshing the browser.
  2. +
  3. Go to Admin > Permissions and select the relevant group.
  4. +
  5. Find the database that you want to grant SQL access to.
  6. +
  7. From the View data dropdown.elect Can view.
  8. +
  9. From the Create queries dropdown, select Query builder and native.
  10. +
  11. Check if the access problem is fixed.
  12. +
+ +

For more information about the different types of database permissions, check out the section on data access in our permissions documentation.

+ +

A user group has the wrong access to a table or schema

+ +
    +
  1. Go to Admin > People and check if the person is in more than one group with conflicting permissions.
  2. +
  3. If the person is in multiple groups: +
      +
    • Remove the person from the group with wider permissions, or
    • +
    • Go to Admin > Permissions and change the Data access permission type.
    • +
    +
  4. +
  5. Check if the access problem is fixed.
  6. +
+ +

Explanation

+ +

If a person is a member of multiple groups, Metabase will grant the most permissive level of access across all the groups in which they’re a member.

+ +

For example, if a person is a member of two groups — one which grants [View data] access of “Can view” to a database or table and another that grants “Blocked” access to that database — that person will be able to view the data.

+ +

Remember that everyone is a member of the All Users group. We recommend you revoke permissions from the All Users group, and create new groups to selectively apply permissions to your data sources.

+ +

A user group can view collections that contain restricted data

+ +
+
+ + + + + + + +

This feature is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +
    +
  1. Go to Admin > Permissions and select the user group.
  2. +
  3. Select the database or table that you want to restrict.
  4. +
  5. Set View data permissions to Blocked and click Save.
  6. +
  7. Check if the access problem is fixed.
  8. +
+ +

Explanation

+ +

If you’ve granted a group View data access of “Can view” to a database or table, people can view saved questions and dashboards that draw on that database, as long as those questions and dashboards are stored in a collection that they have access to.

+ +

The Blocked data permission is available on Pro and Enterprise versions of Metabase. If you block a group’s access to a database, members of that group will not be able to see any data from this database, regardless of their collection permissions.

+ +

Getting a “permission denied” error message

+ +

If you get an error message that says something like “permission denied to <your table>”, you’ll need to check if the Metabase application has the correct permissions to query your database.

+ +
    +
  1. Go to the SQL editor and run a basic query against the table or schema in question: +
    SELECT 1
    +FROM <your table>;
    +
    +
  2. +
  3. Get the credentials that Metabase uses to connect to your database. If you’re not sure what those credentials are, ask your database admin.
  4. +
  5. Using a different application (like your CLI or database IDE), connect to your database using the same credentials your Metabase uses to connect to that database, and run the query from step 1.
  6. +
  7. If you cannot access the table or schema in both step 1 and 3, ask your database admin to: +
      +
    • Grant database privileges to the role that Metabase is using to connect, or
    • +
    • Provide a set of database credentials with the correct permissions.
    • +
    +
  8. +
  9. Check if the access problem is fixed.
  10. +
+ +

Explanation

+ +

Your database has its own set of permissions that are configured for each person (or application) that logs in.

+ +

Database permissions apply at the level of your database connection, before your data and collection permissions are applied in Metabase.

+ +

This means that settings configured on the database side can prevent Metabase from connecting to certain schemas or tables, regardless of what you’ve set up on the Metabase side.

+ +

Checking someone’s access to a table or schema

+ +
    +
  1. Open an incognito browser window.
  2. +
  3. Log in to Metabase as the person in question.
  4. +
  5. Run a question, dashboard, or native query to confirm that the person can see the data they’re supposed to.
  6. +
+ +

Do you have a different problem?

+ + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/datawarehouse.html b/_site/docs/doc-update-detection/troubleshooting-guide/datawarehouse.html new file mode 100644 index 000000000..625e39a14 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/datawarehouse.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/db-connection.html b/_site/docs/doc-update-detection/troubleshooting-guide/db-connection.html new file mode 100644 index 000000000..70498faff --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/db-connection.html @@ -0,0 +1,3192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting database connections | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting database connections

+ +

If you can’t connect to your database, you’ll need to figure out if the problem is happening with Metabase or your database server.

+ +

If your database connection is successful, but the tables aren’t showing up in the Data Browser, go to Troubleshooting missing tables.

+ +

Troubleshooting connections to Metabase

+ +
    +
  1. +

    Go to Admin > Databases and select your database to confirm that your connection hasn’t been changed or deleted.

    + +
      +
    • +

      If Metabase hasn’t started syncing with your database, click Sync database schema.

      +
    • +
    • +

      If Metabase is taking a long time to sync, go to Troubleshooting syncs and scans.

      +
    • +
    +
  2. +
  3. +

    Go to Admin > Troubleshooting > Logs to check if Metabase failed to sync due to an error.

    + + +
  4. +
+ +

If you don’t have access to the Metabase Admin panel, you’ll need to ask the person who set up your Metabase.

+ +

Troubleshooting connections to the database server

+ +
    +
  1. +

    Check that the data warehouse server is running.

    +
  2. +
  3. +

    Check if you can connect to the data warehouse from another client using the machine that you’re running Metabase on.

    + + +
  4. +
  5. +

    Make sure that Metabase is using a role with the necessary privileges to connect to your data warehouse. See Granting database privileges.

    +
  6. +
+ +

The steps above will help you detect whether the problem is occurring outside of Metabase. To fix problems with your database server, you’ll need to refer to the docs for your database or cloud service. Remember to test your database connection after you make changes.

+ +

If you don’t have access to the data warehouse server, you’ll need to ask the person who manages your database or data warehouse.

+ +

Troubleshooting BigQuery and Google Drive connections

+ +

See Troubleshooting BigQuery and Google Drive connections

+ +

Common database connection errors

+ +

Your question took too long

+ +

If you see this error message in the Metabase interface, go to Troubleshooting timeouts.

+ +

Connections cannot be acquired from the underlying database

+ +

If you see this error messages in the logs (Admin > Troubleshooting > Logs):

+ +
    +
  1. Go to Admin > Databases and select your database.
  2. +
  3. Go to Advanced options > Additional JDBC connection string options and add trustServerCertificate=true.
  4. +
  5. Click Save.
  6. +
+ +

The version of Metabase you’re using to connect to your data warehouse must support your database’s version. For example, Metabase versions older than 46 lack support for Microsoft SQL Server 2022.

+ +

Testing a database connection

+ +

As you work through the troubleshooting steps in this guide, you can check if each component is working as expected:

+ + + +

Checking the server status

+ +

If you’re using a hosted database service, go to the console and verify its status.

+ +

If you have direct access to a command-line interface, log in and make sure that your database is running and accepting queries.

+ +

Checking your server access

+ +

To verify that your Metabase’s IP address can access the database server:

+ +
    +
  1. +

    Use the netcat command nc (or your operating system’s equivalent) to check if you can connect to the host on a given port. Note that different databases use different ports by default.

    +
  2. +
  3. +

    If you’re running Metabase Cloud, check that you’ve whitelisted our IP addresses.

    +
  4. +
  5. +

    Check that your database credentials are correct.

    +
  6. +
+ +

Example commands

+ +

To verify the port used in a default PostgreSQL configuration (which listens on port 5432):

+ +
nc -v your-db-host 5432
+
+ +

To verify your credentials for a PostgreSQL database (you’ll see an error if the database name or the user/password are incorrect):

+ +
psql -h HOSTNAME -p PORT -d DATABASENAME -U DATABASEUSER
+
+ +

Testing the connection status

+ +
    +
  1. Go to the Metabase SQL editor.
  2. +
  3. Test the connection to your database by running: +
    SELECT 1
    +
    +
  4. +
+ + + + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/db-performance.html b/_site/docs/doc-update-detection/troubleshooting-guide/db-performance.html new file mode 100644 index 000000000..016ab6458 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/db-performance.html @@ -0,0 +1,3144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting database performance | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting database performance

+ +

This guide deals with databases or data warehouses that are connected to Metabase as data sources.

+ +

To fix problems with your Metabase application database, check out these troubleshooting guides:

+ + + +

Identifying bottlenecks

+ +
    +
  1. Optional: use Metabase’s Usage analytics to look at your Metabase usage stats.*
  2. +
  3. Go to your database’s server logs and check whether: +
      +
    • Your tables are growing in size,
    • +
    • More people are using Metabase to access your database,
    • +
    • People are accessing your database more often, or
    • +
    • A script or application (other than Metabase) is accessing the database frequently.
    • +
    +
  4. +
  5. If specific tables are being queried a lot, try Optimizing your table schemas.
  6. +
  7. Run a question from Metabase, then run the same query directly against your database. +
      +
    • If the queries take about the same time, your data or usage might be outgrowing your database. You can give your database more resources, or consider upgrading your hardware.
    • +
    • If the query in Metabase takes longer than a direct query against your database, you might need to adjust the deployment of your Metabase app. Check out some options in Metabase at scale.
    • +
    +
  8. +
  9. If a script or third-party application is hitting your database with a lot of queries at a time: +
      +
    • Stop your script or application, and clear any queued queries.
    • +
    • Recommended: add a timeout to your script, schedule the script or application to run during off-hours, or replicate your database (and point your tools there instead).
    • +
    +
  10. +
+ +

* Available on Pro and Enterprise plans.

+ +

Resetting a database connection

+ +
    +
  1. Go to Settings > Admin settings > Databases > your database.
  2. +
  3. Click Save changes (without making changes) to reset Metabase’s connections to your database.
  4. +
  5. Alternatively: kill the connection(s) directly from your database.
  6. +
+ +

Explanation

+ +

“Turn it off, and on again” by disconnecting and reconnecting your database—an easy sanity check that can save you a lot of time.

+ +

In general, Metabase will try to close hanging connections to your database after 10 minutes, and then again after 20 minutes. But if your database doesn’t respond, you may need to close the connection to Metabase from the database side.

+ +

Clearing queued queries

+ +
    +
  1. Stop the process (e.g., a script, or a dashboard with too many cards that’s launching a lot of queries at once.
  2. +
  3. Go to your database server and stop all queries (from Metabase) that are in progress.
  4. +
  5. Optional: Increase the number of connections to your database.
  6. +
+ +

Explanation

+ +

If someone or something creates 100 queries at the same time, this stampede of queries will take up all of the available connections between Metabase and your database, preventing any new queries from running. If other people continue running questions and dashboards while the first 100 queries are still in progress, the queue will grow at a faster rate than your database can keep up with.

+ +

Managing resource-intensive queries

+ +
    +
  1. Reschedule or disable Metabase syncs and scans.
  2. +
+ +

Explanation

+ +

By default, Metabase makes regular sync and scan queries against your database to keep your tables up to date, get fresh values for filter dropdowns, and make helpful suggestions. If you’ve got a very large database, you can choose to trigger these queries manually instead of on a schedule.

+ +

Questions that use number, date, or timestamp columns

+ +
    +
  1. Update your database schema so that the columns are typed correctly.
  2. +
  3. Sync the updated columns to bring the changes into Metabase.
  4. +
+ +

Explanation

+ +

If a question uses data stored as the wrong data type in your database (most common with number, date, or timestamp values stored as strings), Metabase will generate a query that asks your database to convert the values on the fly. Typing your columns correctly at the schema level will help your database avoid that extra step to return results faster in Metabase.

+ + + + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/diagnostic-info.html b/_site/docs/doc-update-detection/troubleshooting-guide/diagnostic-info.html new file mode 100644 index 000000000..1eb9b9d98 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/diagnostic-info.html @@ -0,0 +1,3077 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Diagnostic information for troubleshooting | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Diagnostic information for troubleshooting

+ +

To download diagnostic information, hit Cmd + F1 on Macs, Ctrl + F1 on PCs. Hit Cmd/Ctrl + K to bring up the command palette, search for “Diagnostic”, and select “Open diagnostic error modal”

+ +

Select the info you want to include in the diagnostic JSON file. Options include:

+ +
    +
  • Item definition (like information about a dashboard)
  • +
  • Browser error messages
  • +
  • All server error messages
  • +
  • All server logs
  • +
  • Server logs from the current user only
  • +
  • Metabase instance version information
  • +
+ +

What data Metabase captures depends on the page you’re on when you request diagnostic information.

+ +
+

Review the downloaded file before sharing it, as the diagnostic info may contain sensitive data.

+
+ +

Metabase server and console logs

+ +

Metabase will log errors, both on the server and in the browser console, depending on where the error occurs, which can help you track down an issue. Administrators will have access to the server logs, and everyone with a browser can open the developer tools to see the console logs.

+ +

Accessing the Metabase server logs: You can look for the logs that Metabase leaves on the server’s file system (or wherever else you collect logs). If you’re logged into Metabase with an Admin account, you can also access the logs by going to the top right of the screen and clicking on the gear icon > Admin settings > Troubleshooting > Logs. Check out How to read the server logs

+ +

Checking for Javascript console errors: Metabase will send debugging information and errors to your browser’s developer console. To open the developer console, follow the instructions for your web browser:

+ + + +

Creating a HAR file: HAR files record network requests generated by your browser. HAR files can be helpful when troubleshooting issues with Metabase performance. Check out Creating HAR files for troubleshooting.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/docker.html b/_site/docs/doc-update-detection/troubleshooting-guide/docker.html new file mode 100644 index 000000000..21314fd24 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/docker.html @@ -0,0 +1,3179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting Metabase on Docker | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting Metabase on Docker

+ +

Docker simplifies many aspects of running Metabase, but there are some pitfalls to keep in mind. If you have trouble with Metabase under Docker, try going through the troubleshooting process below, then look below for details about the specific issue you’ve found.

+ +
    +
  1. Is the container running?
  2. +
  3. Is the server running inside the container?
  4. +
  5. Is Metabase using the correct application database?
  6. +
  7. Can you connect to the Docker host on the Metabase port?
  8. +
  9. Can you connect to the container from the Docker host?
  10. +
  11. Can you connect to the server from within the container?
  12. +
+ +

You may find these commands useful along the way. To get to the shell in the Metabase container:

+ +
docker exec -ti CONTAINER_NAME bash
+
+ +

And to get the logs for the Metabase container:

+ +
docker logs -f CONTAINER_NAME
+
+ +

Metabase container exits without starting the server

+ +

How to detect this: Run docker ps to see if the Metabase container is currently running. If it is, move on to the next step.

+ +

If docker ps does not show the running container, then list the stopped containers by running:

+ +
docker ps -a | grep metabase/metabase
+
+ +

Look for the container that exited most recently and make a note of the container ID. Look at that container’s logs with:

+ +
Docker logs CONTAINER_ID
+
+ +

Metabase container is running but the server is not

+ +

How to detect this: Run docker ps to make sure the container is running. The server should be logging to the Docker container logs. Check this by running:

+ +
docker logs CONTAINER_NAME
+
+ +

You should see a line like this at the beginning:

+ +
05-10 18:11:32 INFO metabase.util :: Loading Metabase...
+
+ +

Further down, you should eventually see a line like:

+ +
05-10 18:12:30 INFO metabase.core :: Metabase Initialization COMPLETE
+
+ +

If you see the lines below:

+ +
05-15 19:07:11 INFO metabase.core :: Metabase Shutting Down ...
+05-15 19:07:11 INFO metabase.core :: Metabase Shutdown COMPLETE
+
+ +

then Metabase has shut itself down.

+ +

How to fix this: Check the Docker container logs for errors about connecting to the application database. Watch the logs to see if Metabase is still being started; the command:

+ +
Docker logs -f CONTAINER_ID
+
+ +

will let you see the logs as they are printed.

+ +

If the container is being terminated before it finished starting, the problem could be a health check timeout in the orchestration service used to start the container, such as Docker Cloud.

+ +

If the container is not being terminated from the outside, but is failing to start anyway, this problem is probably not specific to Docker. If you’re using a Metabase-supplied image, please open a GitHub issue.

+ +

Not connecting to a remote application database

+ +

How to detect this: If this is a new Metabase instance, then the database you specified via the environment variables will be empty. If this is an existing Metabase instance with incorrect environment parameters, the server will create a new H2 embedded database to use for application data and you’ll see lines similar to these in the log:

+ +
05-10 18:11:40 INFO metabase.core :: Setting up and migrating Metabase DB. Please sit tight, this may take a minute...
+05-10 18:11:40 INFO metabase.db :: Verifying h2 Database Connection ...
+
+05-10 18:11:40 INFO metabase.db :: Verify Database Connection ...  ✅
+
+ +

How to fix this: Check that you are passing environments to Docker correctly. You can list the environment variables for a container with this command:

+ +
docker inspect some-postgres -f '{{ .Config.Env }}'
+
+ +

The Metabase server isn’t able to connect to a MySQL or PostgreSQL database

+ +

How to detect this: The logs for the Docker container return an error message after the “Verifying Database Connection” line.

+ +

How to fix this: Try to connect using the mysql or psql command with the connection string parameters you are passing in via the environment variables. If you can’t connect to the database, the problem is due to either the credentials or connectivity. To verify that the credentials are correct, log in with those credentials from another machine and then try to make the same connection from the host running the Docker container.

+ +

One easy way to run this is to use Docker to start a container that has the appropriate client for your database. For Postgres this would look like:

+ +
docker run --name postgres-client --rm -ti --entrypoint /bin/bash postgres
+
+ +

From within that container, try connecting to the database host using the client command in the container such as psql. If you are able to connect from another container on the same host, then try making that connection from within the Metabase Docker container itself:

+ +
docker exec -ti container-name bash
+
+ +

You can also try to connect to the database host using the nc command and check if the connection can be opened:

+ +
nc -v your-db-host 5432
+
+ +

These steps will help you determine whether this the problem is with the network or with authentication.

+ +

The Metabase application database is not being persisted

+ +

How to detect this: This is occurring if you are getting the Setup screen every time you start the application. The most common cause is not giving the Docker container a persistent filesystem mount to put the application database in.

+ +

How to fix this: Make sure you are giving the container a persistent volume.

+ +

The internal port isn’t being remapped correctly

+ +

How to detect this: Run docker ps and look at the port mapping, then run curl http://localhost:port-number-here/api/health. This should return a JSON response that looks like:

+ +
{"status":"ok"}
+
+ +

How to fix this: Make sure to include -p 3000:3000 or similar port remapping in the docker run command you use to start the Metabase container image.

+ +

Metabase can’t write or read to/from a file or directory

+ +

How to detect this: A message in the logs will clearly indicate an IOError or “Permission denied” from Java, or errors from SQLite containing org.sqlite.core.NativeDB._open_utf8.

+ +

How to fix this: Ensure that the user who is running Metabase has permission to read and write to the file or directory:

+ +
    +
  • If you are running Metabase as a JAR file in your local machine or server, check the user who is running the Java process.
  • +
  • If you’re running Metabase from the Docker container, make sure you’re using the /metabase.db directory.
  • +
+ +

If you’re running Metabase from the JAR in any Unix-like operating system, you can see which user is running Metabase by opening a terminal and typing ps -uA | grep metabase.

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/error-message.html b/_site/docs/doc-update-detection/troubleshooting-guide/error-message.html new file mode 100644 index 000000000..617b34a53 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/error-message.html @@ -0,0 +1,3073 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting error messages | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting error messages

+ +

An error message can help you find the right troubleshooting guide. The exact wording depends on your database and Metabase version, so try to look for the closest match.

+ +

SQL editor

+ +

See if your error details contain any of:

+ + + +

For example, this SQL error tells you that the function DATEFROMPARTS does not work on a BigQuery database:

+ +

Sample SQL error message

+ +

Questions and dashboards

+ + + +

Are you still stuck?

+ +

If you can’t find your error on this page:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/filters.html b/_site/docs/doc-update-detection/troubleshooting-guide/filters.html new file mode 100644 index 000000000..9469a3ba1 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/filters.html @@ -0,0 +1,3180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting filters | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting filters

+ +

It’s always a good idea to start with a quick sanity check:

+ +
    +
  1. Clear your browser cache.
  2. +
  3. Refresh the page.
  4. +
  5. Open your question or dashboard in an incognito window.
  6. +
+ +

Dashboard filters

+ +

If a dashboard filter is giving you no results or the wrong results:

+ +
    +
  1. Click the pencil icon to go into edit mode.
  2. +
  3. Click the gear icon beside your filter widget.
  4. +
  5. Make sure you’ve selected a column for your filter under Column to filter on.
  6. +
  7. If you can’t find the right Column to filter on, or you’re getting “No Results” when you apply the filter: +
      +
    • Exit edit mode and click on a dashboard card to go to the original question.
    • +
    • Follow the troubleshooting steps under Question filters.
    • +
    +
  8. +
+ +

Question filters

+ +

If a question filter is giving you no results or the wrong results:

+ +
    +
  1. Make sure the question includes the column you want to filter on.
  2. +
  3. Check that the column actually contains the value(s) you’re filtering on. You can do this by: +
      +
    • sorting number or date columns,
    • +
    • creating a “contains” filter for string columns, or
    • +
    • asking your database admin.
    • +
    +
  4. +
  5. Ask your Metabase admin to help you check if: + +
  6. +
+ +

Special cases

+ +

If you’re having trouble filtering on a:

+ + + +

Explanation

+ +

When we first set up a filter, we need to link the filter to a column. If we make the wrong assumptions about a column’s values or data type, the filter won’t work at all. If a column changes on the database side, the filter might suddenly stop working.

+ +

For example, let’s say we want to create a filter named “Select Product ID” linked to a column named Product ID. The filter won’t work if any of these things happen:

+ +
    +
  • Our question doesn’t include the Product ID column.
  • +
  • We type the number 4 into the “Select Product ID” filter, when the Product ID column only contains the values 1, 2, and 3.
  • +
  • Product ID is renamed to something else in the database or Table Metadata page.
  • +
  • Product ID is deleted from the database, or hidden in the Table Metadata page.
  • +
  • Product ID is a custom column that’s not working as expected.
  • +
  • We don’t have data permissions to access the Product ID column.
  • +
  • We made “Select Product ID” a numerical filter, but Product ID is a string column (see the section below).
  • +
+ +

Time, ID, and number filters

+ +

To debug dashboard and question filters that involve timestamps, UUIDs, or numeric data:

+ +
    +
  1. Find the data type of the column that you want to filter on. You can find this info from: + +
  2. +
  3. Cast the column to a data type that matches the desired filter type. You can: + +
  4. +
+ +

If you’re not a Metabase admin, you might have to ask your admin to help you with some of these steps.

+ +

Explanation

+ +

Metabase needs to know the data type of a column in order to present you with a curated selection of filter types. Sometimes these columns are mistyped—if a column stores your numbers as strings, Metabase will only show you text or category filters (with options like “is”, “is not”) instead of number filters (with options like “greater than”, “less than”).

+ +

Timestamps, in particular, are the root of all evil, so please be patient with your Metabase admin (or yourself!) when trying to get the data type right.

+ +

Field filters in BigQuery and Oracle

+ +

If you are getting an error when using field filters with BigQuery or Oracle, make sure you use the correct syntax for the FROM clause. See Field filters in BigQuery and Oracle.

+ +

Missing or incorrect filter values

+ +

If your filter dropdown menu displays the wrong values for a column:

+ +
    +
  1. Go to Admin settings > Table Metadata.
  2. +
  3. Find your database, table, and column.
  4. +
  5. Click the gear icon at the right of a column’s settings box.
  6. +
  7. Scroll to Cached field values.
  8. +
  9. Optional: click Discard cached field values.
  10. +
  11. Click Re-scan this field.
  12. +
+ +

Explanation

+ +

Metabase scans get the values for your filter dropdown menus by querying and caching the first 1,000 distinct records from a table. You might see outdated filter values if your tables are getting updated more frequently compared to your scan schedule.

+ + + + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/images/sample-error-sql.png b/_site/docs/doc-update-detection/troubleshooting-guide/images/sample-error-sql.png new file mode 100644 index 000000000..b53abf95d Binary files /dev/null and b/_site/docs/doc-update-detection/troubleshooting-guide/images/sample-error-sql.png differ diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/index.html b/_site/docs/doc-update-detection/troubleshooting-guide/index.html new file mode 100644 index 000000000..e1d7fc576 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/index.html @@ -0,0 +1,3138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting guides | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting guides

+ +

Problems, their causes, how to detect them, and how to fix them.

+ +

Getting diagnostic info

+ + + +

Installation

+ + + +

Authentication

+ + + +

Permissions

+ + + +

Databases

+ + + +

Questions and dashboards

+ + + +

Models

+ + + +

Email and alerts

+ + + +

Error messages

+ + + +

Think you found a bug?

+ + + +

Feature requests

+ +

See Requesting new features.

+ +

Metabase tutorials

+ +

For tutorials that walk you through how to use Metabase features, check out Learn Metabase.

+ +

Metabase forum

+ +

To see if someone else has run into a similar issue, check out our forum on Discourse.

+ +

Upgrading Metabase

+ +

Metabase adds new features and squashes bugs with each release. Upgrading to the latest and greatest may resolve your issue. If you’re using Metabase Cloud, we’ll handle the upgrades for you. To see what’s new, check out the release notes.

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/known-issues.html b/_site/docs/doc-update-detection/troubleshooting-guide/known-issues.html new file mode 100644 index 000000000..9d27a7649 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/known-issues.html @@ -0,0 +1,3107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +How to find a known bug or limitation | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

How to find a known bug or limitation

+ +

If you can’t find or solve your problem using the troubleshooting guides, you may be running into an issue that we’re still working on.

+ +

How to find a known bug

+ +

If your work in Metabase is crashing, missing, or not being saved, you might have found a bug.

+ +
    +
  1. +

    Go to the Metabase Github issues page.

    +
  2. +
  3. +

    Click on the Label dropdown and select Type: Bug.

    + +
    +

    If you’re encountering problems after your Metabase version was recently upgraded, you can add the label .Regression.

    +
    +
  4. +
  5. +

    Choose least one value in the Label dropdown that matches the feature you’re having trouble with.

    + +
    +

    Add additional keywords to the search bar above the list of results. Hit Enter/Return to run the search.

    +
    + +
    +

    Click Sort and select the thumbs up emoji (👍) to view the most commonly encountered bugs.

    +
    +
  6. +
  7. +

    If you find an existing bug that matches your problem, add a thumbs up emoji to help the team prioritize it.

    +
  8. +
  9. +

    If you can’t find your problem, and you’re sure that it’s not a product limitation, you can create a new bug report.

    +
  10. +
+ +

How to find a known product limitation

+ +

If the functionality you’re looking for simply doesn’t exist (i.e., it hasn’t suddenly gone missing), you might be running into a product limitation.

+ +
    +
  1. +

    Go to the Metabase Github issues page.

    +
  2. +
  3. +

    Click on the Label dropdown and select Type: New Feature.

    +
  4. +
  5. +

    Choose at least one value in the Label dropdown that matches the feature you’re looking for.

    + +
    +

    Add additional keywords to the search bar above the list of results. Hit Enter/Return to run the search.

    +
    + +
    +

    Click Sort and select the thumbs up emoji (👍) to view the most highly requested features.

    +
    +
  6. +
  7. +

    If you find a feature request that matches what you want to do, add a thumbs up emoji to help the team prioritize it.

    +
  8. +
  9. +

    If a feature request doesn’t exist, and your issue isn’t caused by a known bug, you can submit a new feature request.

    +
  10. +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/ldap.html b/_site/docs/doc-update-detection/troubleshooting-guide/ldap.html new file mode 100644 index 000000000..1e08ee460 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/ldap.html @@ -0,0 +1,3124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting LDAP | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting LDAP

+ +

Metabase can use LDAP for authentication. This article explains how to set it up, and the guide below will help you troubleshoot if anything goes wrong. If your problem isn’t specific to LDAP, go to our troubleshooting guide for logging in.

+ +

LDAP sample configuration

+ +

You can test Metabase with LDAP by using this docker-compose definition:

+ +
version: "3.7"
+services:
+  metabase-ldap:
+    image: metabase/metabase:latest
+    container_name: metabase-ldap
+    hostname: metabase-ldap
+    volumes:
+      - /dev/urandom:/dev/random:ro
+    ports:
+      - 3000:3000
+    networks:
+      - metanet1
+    environment:
+      - "MB_LDAP_BIND_DN=cn=admin,dc=example,dc=org"
+      - "MB_LDAP_ENABLED=true"
+      - "MB_LDAP_GROUP_BASE=cn=readers"
+      - "MB_LDAP_HOST=openldap"
+      - "MB_LDAP_PASSWORD=adminpassword"
+      - "MB_LDAP_PORT=1389"
+      - "MB_LDAP_USER_BASE=ou=users,dc=example,dc=org"
+      - "MB_LDAP_ATTRIBUTE_EMAIL=uid"
+      # We are using the same field for email and first name, just for this example to work without modifications to the LDAP objects
+      - "MB_LDAP_ATTRIBUTE_FIRSTNAME=uid"
+      - "MB_LDAP_ATTRIBUTE_LASTNAME=sn"
+  openldap:
+    image: bitnami/openldap:2.4.57
+    hostname: openldap
+    container_name: openldap
+    ports:
+      - 1389:1389
+    environment:
+      - LDAP_ADMIN_USERNAME=admin
+      - LDAP_ADMIN_PASSWORD=adminpassword
+      - LDAP_USERS=user01@metabase.com,user02@metabase.com
+      - LDAP_PASSWORDS=password1!,password2!
+      - LDAP_PORT_NUMBER=1389
+      - LDAP_ROOT=dc=example,dc=org
+      - LDAP_USER_DC=users
+      - LDAP_GROUP=readers
+    networks:
+      - metanet1
+networks:
+  metanet1:
+    driver: bridge
+
+ +

If you don’t pass environment variables to Metabase and you want to configure the environment manually, you can go to the Admin Panel, selectin “Settings”, select “Authentication”, and then select “LDAP Configuration” and enter the following values:

+ +
    +
  • USERNAME OR DN: cn=admin,dc=example,dc=org
  • +
  • PASSWORD: adminpassword
  • +
  • USER SEARCH BASE: ou=users,dc=example,dc=org
  • +
  • USER FILTER: (&(objectClass=inetOrgPerson)(|(uid={login})))
  • +
  • GROUP SEARCH BASE: cn=readers
  • +
+ +

For the USER FILTER, you can leave the default value, which will look for the user ID in both the uid or email field.

+ + + +

If you run into an issue, check that you can login to your LDAP directory and issue queries using software like Apache Directory Studio. It will let you see the whole LDAP tree and view the logs of your LDAP application to see queries run.

+ +

Current limitations

+ +
    +
  • When using Metabase Enterprise with a MySQL database and LDAP enabled, make sure that you disable synchronization of binary fields from your LDAP directory by using the MB_LDAP_SYNC_USER_ATTRIBUTES_BLACKLIST environment variable. If you do not, you may hit the 60K field size limitation of the text field in MySQL, which will prevent you from creating users or those users from logging in.
  • +
+ +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/linked-filters.html b/_site/docs/doc-update-detection/troubleshooting-guide/linked-filters.html new file mode 100644 index 000000000..c97e02cb2 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/linked-filters.html @@ -0,0 +1,3123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +My linked filters don't work | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

My linked filters don’t work

+ +

You have created a linked filter so that (for example) if a dashboard contains both a “State” and a “City” filter, the “City” filter only shows cities in the state selected by the “State” filter. However:

+ +
    +
  • your cards are showing “No result” when you apply the linked filter,
  • +
  • your linked filter seems to have no effect, or
  • +
  • your linked filter widget does not display a dropdown of filtered values.
  • +
+ +

If you are having problems with a regular filter widget, please see this guide. In order to fix problems with linked filters, you need a clear understanding of how they work:

+ +

Does a connected dashboard card use a SQL variable?

+ +

Root cause: Native/SQL questions must have a field filter variable in order to be linked. Regular SQL variables won’t work.

+ +

Steps to take:

+ +
    +
  1. Update the card’s query to change the regular variable to a field filter variable.
  2. +
+ +

See Limitations of linking filters.

+ +

Do you understand the directionality of linked filters?

+ +

Root cause: Linked filters are one of the more complex features of Metabase, and many problems stems from misunderstanding their operation.

+ +

Steps to take: Check that you understand the points below, and that your linked filter is set up with them in mind.

+ +
    +
  1. +

    A filter isn’t part of a specific question. Instead, a filter is added to a dashboard and its value is used to fill in variables in questions.

    +
  2. +
  3. +

    In order for Metabase to display a dropdown list of possible filter values, it must know that the column corresponds to a category. This happens automatically if the question is created from tables via the Notebook Editor, since Metabase has knowledge about the table and columns from synchronization.

    +
  4. +
  5. +

    If the question that contains the variable is written in SQL, on the other hand, the author of the question must have selected “Field Filter”. Also, the field referenced must be set as a category in the Table Metadata in order for Metabase to show a dropdown list of values.

    +
  6. +
+ +

Are the filters linked in the correct direction?

+ +

Root cause: The most common cause is that the filters have been linked in the wrong direction. If you want the values shown by Filter B to be restricted by the setting of Filter A, you have to change the settings for Filter B, not Filter A—i.e., the downstream filter has the setting, not the upstream filter.

+ +

Steps to take:

+ +
    +
  1. Remove the existing linkage and create a new one in the opposite direction.
  2. +
+ +

Do some rows actually satisfy the full filter condition?

+ +

Root cause: There aren’t any rows that satisfy all the conditions in a linked filter. Continuing with the city and state example, if you manually enter the name of a city that isn’t in the selected state, no record will satisfy both conditions.

+ +

Steps to take:

+ +
    +
  1. Create a question that only uses the first filter and check that it produces some rows. (If it does not, adding a second filter isn’t going to make any rows appear.)
  2. +
  3. Create a question that you think should produce the same result as the combination of linked filter settings that isn’t producing any data. If it produces the result you expect, check for typing mistakes and that you are using the correct type of join.
  4. +
+ +

Do all rows that pass the first test also pass the second?

+ +

Root cause: In some cases all of the rows that satisfy the first filter’s condition also satisfy the second filter’s condition, so the second filter has no effect.

+ +

Steps to take:

+ +
    +
  1. Create a question that includes the first filter condition directly (i.e., in the question rather than using a variable), then add the second filter’s condition. If the result set does not change, the problem is in the logic rather than in the filters.
  2. +
+ +

Does the linked filter widget display a dropdown of filtered values?

+ +

Root cause: In order for a linked filter widget to display the correct subset of values as a dropdown, an explicit foreign key definition must be set up—linking the filters does not by itself tell Metabase about the relationship.

+ +

Steps to take:

+ +
    +
  1. Check that Metabase’s table metadata for your database includes the foreign key relationship.
  2. +
+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/loading-from-h2.html b/_site/docs/doc-update-detection/troubleshooting-guide/loading-from-h2.html new file mode 100644 index 000000000..910fb935c --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/loading-from-h2.html @@ -0,0 +1,3181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Using or migrating from an H2 application database | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Using or migrating from an H2 application database

+ +

You’ve installed Metabase, but:

+ +
    +
  • You’re trying to migrate the application database from H2 to another database and something has gone wrong,
  • +
  • You’re trying to downgrade rather than upgrade,
  • +
  • Metabase logs a liquibase error message when you try to run it,
  • +
  • Metabase logs another error message that mentions H2 or h2 while it is running, or
  • +
  • You’re on Windows 10 and get a warning about file permissions.
  • +
+ +

Are you currently using H2 as your application database?

+ +

Root cause: Metabase stores information about users, questions, and so on in a database of its own called the “application database”, or “app database” for short. By default Metabase uses H2 for the application database, but we don’t recommended it for production—because it’s an on-disk database, it’s sensitive to filesystem errors, such as a drive being corrupted or a file not being flushed properly.

+ +

Steps to take:

+ +
    +
  1. To check what you’re using as the app database, go to Admin Panel, open the Troubleshooting tab, scroll down to “Diagnostic Info”, and look for the application-database key in the JSON it displays.
  2. +
  3. See Migrating from H2 for instructions on how to migrate to a more robust app database.
  4. +
+ +

Are you trying to migrate the application database from H2 to something else?

+ +

Root cause: You are trying to migrate the app database from H2 to a production database such as PostgreSQL or MySQL/MariaDB using the load-from-h2 command, but this has failed because the database filename is incorrect with an error message like:

+ +
Command failed with exception: Unsupported database file version or invalid file header in file <YOUR FILENAME>
+
+ +

Steps to take:

+ +
    +
  1. +

    Create a copy of the exported H2 database (see Backing up Metabase Application Data). Do not proceed until you have done this in case something goes wrong.

    +
  2. +
  3. +

    Check that the H2 database file you exported is named metabase.db.mv.db.

    +
  4. +
  5. +

    H2 automatically adds .mv.db extension to the database path you specify on the command line, so make sure the path to the DB file you pass to the command does not include the .mv.db extension. For example, if you’ve exported an application database, and you want to load the data from that H2 database into a PostgreSQL database using load-from-h2, your command will look something like:

    + +
    export MB_DB_TYPE=postgres
    +export MB_DB_DBNAME=metabase
    +export MB_DB_PORT=5432
    +export MB_DB_USER=<username>
    +export MB_DB_PASS=<password>
    +export MB_DB_HOST=localhost
    +java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar load-from-h2 /path/to/metabase.db # do not include .mv.db
    +
    +
  6. +
+ +

If you’re using a Pro or Enterprise version of Metabase, you can use serialization to snapshot your application database. Serialization is useful when you want to preload questions and dashboards in a new Metabase instance.

+ +

Are you trying to downgrade?

+ +

Root cause: Metabase does not support downgrading (i.e., reverting to an early version of the application).

+ +

Steps to take:

+ +
    +
  1. Shut down Metabase.
  2. +
  3. Restore the backup copy of the app database you made before trying to upgrade or downgrade.
  4. +
  5. Restore the JAR file or container of the older version you want to revert to.
  6. +
  7. Restart Metabase.
  8. +
+ +

Is the app database locked?

+ +

Root cause: Sometimes Metabase fails to start up because an app database lock did not clear properly during a previous run. The error message looks something like:

+ +
liquibase.exception.DatabaseException: liquibase.exception.LockException: Could not acquire change log lock.
+
+ +

Steps to take:

+ +
    +
  1. +

    Open a shell on the server where Metabase is installed and manually clear the locks by running:

    + +
    java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar migrate release-locks
    +
    +
  2. +
  3. +

    Once this command completes, restart your Metabase instance normally (without the migrate release-locks flag).

    +
  4. +
+ +

Is the app database corrupted?

+ +

Root cause: H2 is less reliable than production-quality database management systems, and sometimes the database itself becomes corrupted. This can result in loss of data in the app database, but can not damage data in the databases that Metabase is connected.

+ +

Steps to take: Error messages can vary depending on how the app database was corrupted, but in most cases the log message will mention h2. A typical command and message are:

+ +
myUser@myIp:~$ java --add-opens java.base/java.nio=ALL-UNNAMED -cp metabase.jar org.h2.tools.RunScript -script whatever.sql -url jdbc:h2:~/metabase.db
+Exception in thread "main" org.h2.jdbc.JdbcSQLException: Row not found when trying to delete from index """"".I37: ( /* key:7864 */ X'5256470012572027c82fc5d2bfb855264ab45f8fec4cf48b0620ccad281d2fe4', 165)" [90112-194]
+    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
+    [etc]
+
+ +

How to fix this: not all H2 errors are recoverable (which is why if you’re using H2, please have a backup strategy for the application database file).

+ +

If you are running a recent version and using H2, the app database is stored in metabase.db.mv.db. - Open a shell on the server where the Metabase instance is running and attempt to recover the corrupted H2 file by running the following four commands:

+ +
java -cp metabase.jar org.h2.tools.Recover
+
+mv metabase.db.mv.db metabase-old.db.mv.db
+
+touch metabase.db.mv.db
+
+java --add-opens java.base/java.nio=ALL-UNNAMED -cp target/uberjar/metabase.jar org.h2.tools.RunScript -script metabase.db.h2.sql -url jdbc:h2:`pwd`/metabase.db
+
+ +

Are you running Metabase with H2 on Windows 10?

+ +

Root cause: In some situations on Windows 10, the Metabase JAR needs to have permissions to create local files for the application database. When running the JAR, you’ll see an error message like this:

+ +
Exception in thread "main" java.lang.AssertionError: Assert failed: Unable to connect to Metabase DB.
+
+ +

Steps to take:

+ +
    +
  1. Right-click on the Metabase JAR file (not the app database file).
  2. +
  3. Select “Properties”.
  4. +
  5. Select “Unblock.”
  6. +
+ +

Is the application database taking too long to load?

+ +

Root cause: You’re using H2 as your app database, and the app database is so large that it can’t be loaded in less than 5 seconds (which is the default timeout value). You’ll see the message “Timeout” appear in the console when you try to start Metabase.

+ +

Steps to take:

+ +
    +
  1. Use a production-quality database such as PostgreSQL for the app database (preferred).
  2. +
  3. Go to the Admin Panel and increase the timeout setting for the app database.
  4. +
  5. Move Metabase to a faster server (in particular, a server with faster disks).
  6. +
+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/models.html b/_site/docs/doc-update-detection/troubleshooting-guide/models.html new file mode 100644 index 000000000..397a7c6c7 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/models.html @@ -0,0 +1,3117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting models | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting models

+ +

What kind of problem are you having with your model?

+ +

Can’t create a model

+ +

If you don’t see the model button (three squares):

+ +
    +
  1. Check if you’re using a Metabase version that’s 0.42.0 or greater by going to the top right of the screen and clicking on the gear icon > About Metabase.
  2. +
  3. Clear your browser cache.
  4. +
  5. Ask your Metabase admin to clear the proxy cache (if you’re using one).
  6. +
+ +

Can’t edit or save changes to a model

+ +

If your changes to a model’s metadata or underlying question aren’t showing up:

+ +
    +
  1. Refresh your browser to confirm you’re not viewing cached results.
  2. +
  3. Search for known model issues using the label Querying/Models. For more information, go to How to find a known bug or limitation.
  4. +
+ +

Model performance is poor

+ +
    +
  1. +

    Use model persistence.

    + +
      +
    • Metabase can write back to your data warehouse. If you enable model persistence, Metabase will read a pre-computed and materialized version of the model directly from the database instead of running the query from scratch. Please consider this option is only available in some supported data warehouses.
    • +
    +
  2. +
  3. +

    Optimize the underlying saved question or SQL query.

    + + +
  4. +
  5. +

    Optimize your database schemas.

    + + +
  6. +
  7. +

    Optimize your data warehouse(s) or database(s).

    + + +
  8. +
+ +

Explanation

+ +

Models are a type of saved question, so they will only perform as fast as the original question or SQL query.

+ +

If you want to improve the performance of a model, you can make optimizations at the query, schema, or database level (depending on your data permissions, technical expertise, and willingness to tinker).

+ +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/my-dashboard-is-slow.html b/_site/docs/doc-update-detection/troubleshooting-guide/my-dashboard-is-slow.html new file mode 100644 index 000000000..41a980a74 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/my-dashboard-is-slow.html @@ -0,0 +1,3133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +My dashboard is slow | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

My dashboard is slow

+ +

First, you’ll want to make sure your browser is on friendly terms with Metabase:

+ +
    +
  • Clear your browser cache and disable all extensions before refreshing the page, or
  • +
  • Try loading the dashboard in a private/incognito session.
  • +
+ +

Dashboard has over 10 cards

+ +
    +
  1. Create a new dashboard for each group of cards that are related to the same time period or segment. +
      +
    • For example, create new dashboards for weekly vs. monthly metrics, or new vs. returning customers.
    • +
    +
  2. +
  3. Move your cards to the new dashboard(s) until each dashboard has 10 or fewer cards.
  4. +
  5. Use custom destinations to link related cards on different dashboards.
  6. +
+ +

Explanation

+ +

A dashboard with 50 cards is almost always going to be slower than 5 dashboards with 10 cards. Metabase displays a dashboard by refreshing all of the questions on it (that is, re-executing all of the queries against your database). Your data warehouse may try to run these queries at the same time to return the results faster, however, these queries can actually compete with each other and slow things down (like having too many programs open on your computer at once).

+ +

Aside from running faster, a small and focused dashboard is also easier for people to understand without getting overwhelmed. For more tips, check out our article on BI dashboard best practices.

+ +

Dashboard used by many people at the same time

+ +
    +
  1. Optional: use Metabase’s Usage analytics to look at your Metabase usage stats*.
  2. +
  3. Set up caching for the questions on your popular dashboard.
  4. +
  5. Run the dashboard during off-hours so that people can load the cached results in seconds instead of executing a fresh query to your database.
  6. +
+ +

* Available on Pro and Enterprise plans.

+ +

Explanation

+ +

If you have a dashboard that many people check around the same time (e.g., at the start of the work day), you may end up with queued queries or saturated database connections. Caching allows you to prepare for peak traffic by running those slow queries once, ahead of time, so that the results are ready to go.

+ +

Caching takes less effort because it doesn’t involve any changes to your schemas or databases. If you’re ready to invest more resources into the root cause of dashboard performance issues, check out this list of common schema and database optimizations.

+ +

Embedded dashboard is slow compared to original dashboard

+ +
    +
  1. To speed up the embedded dashboard, set up a locked parameter to pre-filter your data.
  2. +
+ +

Explanation

+ +

One of the easiest ways to make a question or dashboard run faster is to work with a smaller dataset. Your Metabase admin can apply automatic data limitations using things like SSO, data permissions, and data sandboxing.

+ +

When someone loads a question or a dashboard in a static embed, however, that question or dashboard will query the full dataset (rather than a smaller dataset limited by permissions). Static, signed embeds don’t require people to be logged in, and unauthenticated people viewing the signed embed won’t be subject to the permissions and data restrictions set up by your admin.

+ +

Dashboard is slow compared to similar dashboards

+ +
    +
  1. Remove fields (columns) that you don’t need in the final result.
  2. +
  3. Add a filter to reduce the amount of data being queried. For example: +
      +
    • Narrow down the time frame to the reporting period that you care about.
    • +
    • Exclude invalid records, such as: blanks, nulls, or rows with values like “cancelled”, “expired”, “invalid”, and so on.
    • +
    +
  4. +
  5. Remove joins to tables that aren’t being used.
  6. +
  7. If you’re aggregating data from the query builder, ask your database admin if there’s a pre-aggregated view that you can use instead.
  8. +
+ +

Explanation

+ +

When you update your question to use a minimal number of rows or columns (or switch your question to use a smaller table, such as a summary table) your database can spend less time scanning those records in order to return your results. Narrowing the scope of your question is especially important to think about if you’re starting from someone else’s saved question or model, because you might not need all of the data that the original creator decided to include.

+ +

If all of your dashboards are slow, you might be limited by the performance of a particular data source. In that case, we recommend teaming up with your database admin to Troubleshoot database performance.

+ + + + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/permissions.html b/_site/docs/doc-update-detection/troubleshooting-guide/permissions.html new file mode 100644 index 000000000..3f4e7ef4d --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/permissions.html @@ -0,0 +1,3098 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting permissions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting permissions

+ +

If someone has the wrong level of access to a dashboard or a question, the problem may be coming from group settings, collection permissions, or data permissions.

+ +
    +
  1. Go to Admin > People and check if the person is in more than one group with different permissions.
  2. +
  3. If a person can’t view or edit questions or dashboards, see Troubleshooting collection permissions.
  4. +
  5. If a person can’t access data, such as schema, tables, rows, or columns, see Troubleshooting data permissions.
  6. +
+ +

If you have a different issue, see related problems.

+ +

Troubleshooting collection permissions

+ + + +

Troubleshooting data permissions

+ +

Row and column permissions

+ + + +

Native query (SQL) permissions

+ + + +

Table or schema permissions

+ + + +

Do you have a different problem?

+ + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/proxies.html b/_site/docs/doc-update-detection/troubleshooting-guide/proxies.html new file mode 100644 index 000000000..d6a854f2f --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/proxies.html @@ -0,0 +1,3076 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Can't save questions or dashboards, or getting a blank page | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Can’t save questions or dashboards, or getting a blank page

+ +

If attempting to save a question or dashboard sometimes fails, or Metabase only loads a blank page, the problem might be the use of a proxy. A proxy could include other functions like a web application firewall (WAF), content optimization, or cache. Examples of proxies that are known to cause issues with Metabase include:

+ +
    +
  • Cloudflare’s Rocket Loader and WAF
  • +
  • Azure’s WAF
  • +
  • PageSpeed module for Apache
  • +
  • Some anti-virus browser extensions or add-ons
  • +
+ +

Saving questions or dashboards fails

+ +

If saving questions or dashboards fails and the save button displays “Save Failed,” or if you get the error, “Sorry you do not have permission to see that,” the problem might be with a WAF like Cloudflare or Azure.

+ +
    +
  • When the save fails, check the Console tab of your browser’s Developer Tools for any errors.
  • +
  • You should also check the Network tab in the Developer Tools in your browser to view the network request. It will usually fail with error code 403, indicating the error is coming from the WAF and not Metabase.
  • +
+ +

Clicking on the request will show more information, and looking at the headers will usually indicate where it originated from.

+ +

Some WAFs have dynamic protection, which means that the problem might only occur after an upgrade of Metabase, and might go away after a few days.

+ +

The solution is to disable the WAF for Metabase. Some services will show which rules were triggered, so it might be enough to disable those rules.

+ +

Seeing a blank page instead of the Metabase interface

+ +

If Metabase displays a blank page instead of its interface, the problem is usually with content optimization like PageSpeed or Cloudflare’s Rocket Loader.

+ +
    +
  • Check the Console tab of your browser’s Developer Tools for any errors involving Content Security Policy (CSP).
  • +
  • See if Metabase has been able to deliver the HTML code by right clicking on the blank page and selecting “View page source.” It might look like gibberish, but it should say <title>Metabase</title> near line 25.
  • +
+ +

The solution is to disable content optimization for Metabase.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/requesting-new-features.html b/_site/docs/doc-update-detection/troubleshooting-guide/requesting-new-features.html new file mode 100644 index 000000000..340bab2f0 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/requesting-new-features.html @@ -0,0 +1,3073 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +How to request new features | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

How to request new features

+ +
    +
  1. Check out the issues in the github repo to make sure someone hasn’t already requested the feature.
  2. +
  3. If someone has already requested the feature, click on the thumbs emoji to vote for the issue.
  4. +
  5. If you can add more context about the feature, add a comment that describes your use case or any nuances important to the feature that the description of the issue doesn’t already cover. Avoid comments like “Any updates?”
  6. +
  7. If your feature idea isn’t listed, create a new feature request issue.
  8. +
+ +

Feature description prompts

+ +

Follow these prompts when creating your issue.

+ +

Is your feature request related to a problem? Please describe.

+ +

A clear and concise description of what the problem is. Ex. I’m always frustrated when […]

+ +

Describe the solution you’d like

+ +

A clear and concise description of what you want to happen.

+ +

Describe alternatives you’ve considered

+ +

A clear and concise description of any alternative solutions or features you’ve considered.

+ +

How important is this feature to you?

+ +

Note: the more honest and specific you are here the more we will take you seriously.

+ +

Additional context

+ +

Add any other context or screenshots about the feature request here.

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/running.html b/_site/docs/doc-update-detection/troubleshooting-guide/running.html new file mode 100644 index 000000000..28b7cefe2 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/running.html @@ -0,0 +1,3128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting memory and JVM issues | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting memory and JVM issues

+ +

Metabase runs on the Java Virtual Machine (JVM), and depending on how it’s configured, it may use the server’s filesystem to store some information. Problems with either the JVM or the filesystem can therefore prevent Metabase from running.

+ +

Java version

+ +

Metabase should be run on Java version 21 (older versions are unsupported).

+ +

When searching for versions of Java, always use the latest minor version of the major version you’re choosing. E.g., when choosing between Java 21.0.1 and Java 21.0.4, choose the latest version (in this case, 21.0.4).

+ +

We recommend running only one version of Java on a single server, because running more than one version of Java on a single server can cause application problems. If you need to run multiple applications that each require a different java version, consider using containers (as containers were meant to solve this problem). Otherwise, just make sure that you can run all your applications with a single Java version.

+ +

Metabase’s memory usage

+ +

Metabase ships as a JAR file that runs on the Java Virtual Machine (JVM).

+ +

It’s important to distinguish Metabase’s memory usage from the JVM’s memory usage.

+ +

The JVM will consume a constant amount of memory. By default, the JVM will use about one fourth of a machine’s RAM (though you can change how much RAM you want the JVM to use).

+ +

JVM applications (like Metabase) will consume and release the RAM allocated to the JVM. The JVM, however, won’t release unused RAM to the machine; the JVM’s memory use will be constant.

+ +

So on a machine with 8 GB of RAM, by default the JVM will use 2 GB of RAM. Metabase will use some or all of these 2 GBs of JVM-allocated RAM, depending on Metabase’s activity. But from the machine’s perspective, the JVM will always be using that allocated 2GB of RAM, even when Metabase is only using a fraction of that allocated RAM.

+ +

Diagnosing memory issues

+ +

Given the above explanation of how the JVM handles memory, if you’re having performance issues with Metabase that you don’t think are due to your data warehouse, you’ll want to check for these red flags:

+ +

Metabase crashes due to Java heap space OutOfMemoryError

+ +

The JVM can normally figure out how much RAM is available on the system and automatically set a sensible upper bound for heap memory usage. On certain shared hosting environments, however, this doesn’t always work as desired. The usual symptom of this is an error message like:

+ +
java.lang.OutOfMemoryError: Java heap space
+
+ +

If you’re seeing this “Out of memory” (OOM) error, you’ll need to allocate more memory to the JVM.

+ +

When viewing memory usage over time as a line chart, you see a sawtooth pattern

+ +

You can use tools to view how Metabase uses the memory available to it over time. Check out:

+ + + +

The specific Prometheus metric you need to check is jvm_memory_bytes_used{area=”heap”}

+ +

A red flag to look out for: the sawtooth pattern. Metabase will quickly consume a lot of memory, which will trigger garbage collection, which frees up memory, which Metabase quickly consumes again. This up-down-up-down pattern of memory usage is the signature of frequent garbage collection cycles. The garbage collection will tie up CPU cycles, which can slow down your application.

+ +

If you’re seeing this, you’ll need to increase the amount of memory allocated to the JVM.

+ +

Allocating more memory to the JVM

+ +

You can set a JVM option to allocate more memory to the JVM’s heap. For example, your Java runtime might use the -X flag to do this:

+ +
java -Xmx2g -jar metabase.jar
+
+ +

Adjust the memory allocation upward until Metabase seems happy, but make sure to keep the number lower than the total amount of RAM available on your machine, because Metabase won’t be the only process running. Leaving 1 to 2 GB of RAM for other processes on the machine is generally enough, so you might set -Xmx to 1g on a machine with 2 GB of RAM, 2g on one with 4 GB of RAM, and so on. You may need to experiment with this settings to find one that makes Metabase and everything else play nicely together (and this experimentation may require upgrading to a machine with more memory).

+ +

You can also use the environment variable JAVA_OPTS to set JVM args instead of passing them directly to java. This is particularly useful when running the Docker image:

+ +
docker run -d -p 3000:3000 -e "JAVA_OPTS=-Xmx2g" metabase/metabase
+
+ +

Diagnosing memory issues causing OutOfMemoryErrors

+ +

If the Metabase instance starts and runs for a significant amount of time before running out of memory, there might be a specific event, such as a large query, triggering the OutOfMemoryError. One way to diagnose where the memory is being used is to enable heap dumps when an OutOfMemoryError is triggered. To enable this, you need to add two flags to the java invocation:

+ +
java -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/a/directory -jar metabase-jar
+
+ +

The -XX:HeapDumpPath flag specifies where to put the dump—the current directory is the default. When an OutOfMemoryError occurs, the JVM will dump an hprof file to the directory specified. These hprof files can be large (the size of the -Xmx argument) so make sure your disk has enough space. These hprof files can be read with many different tools, such as jhat (which is included with the JDK) or the Eclipse Memory Analyzer Tool.

+ +

Metabase cannot read or write from a file or folder (IOError)

+ +

If you see an error regarding file permissions, like Metabase being unable to read a SQLite database or a custom GeoJSON map file, check out the section “Metabase can’t read to/from a file or directory” in our Docker troubleshooting guide.

+ +

WARNING: sun.reflect.Reflection.getCallerClass is not supported

+ +

Don’t worry about it.

+ +
WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance.
+
+ +

If you see the above error, ignore it. Your Metabase is perfectly healthy and performing as it should.

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/saml.html b/_site/docs/doc-update-detection/troubleshooting-guide/saml.html new file mode 100644 index 000000000..5751b0bb8 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/saml.html @@ -0,0 +1,3138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting SAML authentication setup | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting SAML authentication setup

+ +
+
+ + + + + + + +

SAML authentication is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Some common problems when setting up SAML.

+ +

Does your app support SAML?

+ +

Verify that the application you created in your IdP supports SAML. Sometimes other options are presented during the app creation process.

+ +

Is the issuer or Entity ID correct?

+ +

After filling out the authentication form with your identity provider, you’re taken back to Metabase but it throws an error. To see the error, go to Admin settings > Troubleshooting > Logs. You’ll see an error that says something like Incorrect response <issuer>.

+ +

Root cause: Your issuer or Entity ID is incorrect.

+ +

Steps to take:

+ +
    +
  1. You should have received an XML file of metadata from your identity provider. Open that metadata file, and look for the correct issuer or Entity ID. This ID is a unique identifier for the identity provider. Depending on your provider, the issuer or Entity ID usually looks something like this: +
    http://www.example.com/141xkex604w0Q5PN724v
    +
    +
  2. +
  3. Copy the issuer or Entity ID from the XML file.
  4. +
  5. Go to Metabase and select Admin settings > Settings > Authentication > SAML. Enter the issuer or Entity ID into the SAML Identity Provider Issuer field.
  6. +
+ +

Is the SAML identity provider certificate value correct?

+ +

After filling out the authentication form with your identity provider, you go back to Metabase but it throws an error. Go to Admin settings > Troubleshooting > Logs. You’ll see an error that says something like Invalid assertion error <issuer>.

+ +

Root cause: The certificate value you entered is incorrect.

+ +

Steps to take:

+ +
    +
  1. +

    Go to Metabase and select Admin settings > Settings > Authentication > SAML. Check that the certificate that you entered into the SAML Identity Provider Certificate field matches the certificate in the XML file you got from your identity provider.

    + +
      +
    • +

      Depending on your provider, you might need to download the XML file, open it in a text editor, then copy and paste the certificate’s contents into the SAML Identity Provider Certificate field in Metabase.

      +
    • +
    • +

      Note that your certificate text may include header and footer comments that look like -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----. These comments should be included when pasting your certificate text into Metabase.

      +
    • +
    +
  2. +
+ +

Is the SSO URL correct?

+ +

Verify that the Single Sign On URL (or equivalent) that you enter on your SAML provider’s website has /auth/sso appended to it. For instance, if you want your users to end up at https://metabase.mycompany.com, the full URL should be https://metabase.mycompany.com/auth/sso.

+ +

Searching for private key and found a null

+ +

This error will only occur if you’re using Signed SSO requests. That is, in Metabase, you’ve filled out the fields in the configuration section in Admin settings > Settings > Authentication > SAML > Signed SSO requests. Those fields are:

+ +
    +
  • SAML Keystore Path: the absolute path to the Keystore file to use for signing SAML requests.
  • +
  • SAML Keystore Password: the password for opening the keystore.
  • +
  • SAML Keystore Alias: the alias for the key that Metabase should use for signing SAML requests.
  • +
+ +

Root cause: The certificate in the keystore file lacks a private key.

+ +

Steps to take:

+ +
    +
  1. Add a certificate with a private key to your keystore.
  2. +
+ +

Checking if SAML is working correctly

+ +

Go to your Metabase login page. If SAML is working correctly, you should see a single button to sign in with your identity provider (IdP). Once you’re authenticated, you should be automatically redirected to the Metabase home page.

+ +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/sandboxing.html b/_site/docs/doc-update-detection/troubleshooting-guide/sandboxing.html new file mode 100644 index 000000000..9b7645c85 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/sandboxing.html @@ -0,0 +1,3219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting sandbox access to rows and columns | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting sandbox access to rows and columns

+ +

Sandboxing data gives some people access to only a subset of the data. (The term comes from the practice of putting children in a sandbox to play safely.) To implement sandboxing, Metabase runs a query that filters rows and/or selects a subset of columns from a table based on the person’s permissions; the person’s query then runs on the initial query’s result (i.e., it runs on the sandboxed data).

+ +

These articles will help you understand how sandboxing works:

+ + + +

If you have a different data access issue, see related problems.

+ +

People can’t see rows in a table they should be able to see

+ +

Is a sandbox filtering rows by a user attribute?

+ +

Root cause: A sandbox is using user attribute to filter rows.

+ +

Steps to take:

+ +

This is expected behavior: using a user attribute to filter rows for a sandboxed table is how sandboxing works. But if you don’t want Metabase to filter those rows, you’ll need to either:

+ +
    +
  • Remove the sandbox (which would grant full access to all rows to everyone with access to that table). Go to Admin > Permissions, and change the access level for the table.
  • +
  • Add the person to a group (or create a group) with different permissions to the table. Check out Guide to data permissions.
  • +
+ +

People can see rows they’re not supposed to see

+ +

There are several reasons people could be seeing rows that they’re not supposed to see.

+ +

Are those people also in groups with permission to view the entire table?

+ +

Root cause: People are in groups with permissions to view the table, and therefore can see all rows, not just the sandboxed rows.

+ +

Steps to take:

+ +

For the person in question, check to see which groups they belong to. Do any of the groups have access to the table you’re trying to sandboxed? If so, remove them from that group. Remember that everyone is a member of the “All users” group; which is why we recommend you revoke permissions from the all users group, and create new groups to selectively apply permissions to your data sources.

+ +

Is the question available via Static embedding or Public Sharing?

+ +

Root cause: The question is public. Public questions, even those that use Static embedding, can’t be sandboxed. If someone views the question without logging into Metabase, Metabase lacks user attributes or group information for filtering the data, so it will show all results.

+ +

Steps to take:

+ +

You should avoid public sharing when you are sandboxing data. See public sharing.

+ +

Is the question written in SQL?

+ +

Root cause. People with SQL access to a database cannot be sandboxed. They have as much access to the database as the user account used to connect Metabase to the database. Even if you hide tables in Metabase, someone with SQL access to a database would still be able to query those tables. Which is also to say that SQL questions cannot be sandboxed. Sandboxing exclusively applies to questions composed in the query builder (even though you can use a SQL question to create a sandbox, e.g., to create a result set of a table that excludes some columns) +.

+ +

Steps to take

+ +
    +
  • +

    Don’t try to sandbox a question written in SQL, because you can’t.

    +
  • +
  • +

    If you want to sandbox access, avoid adding the person to a group with SQL access to that table (or any other more permissive access to that table, for that matter).

    +
  • +
  • +

    If you want to give them SQL access, but still limit what the person can see, you’ll need to set up permissions in your database, and connect that database via the user account with that restricted access. You can connect the same database to Metabase multiple times, each with different levels of access, and expose different connections to different groups. But again, you won’t be able to sandbox the data from a person with SQL access.

    +
  • +
+ +

Is the question retrieving data from a non-SQL data source?

+ +

Root cause: Data sandboxes do not support non-SQL databases.

+ +

Steps to take:

+ +

There is not much you can do here: if you need to sandbox data, you can’t use these databases.

+ +

If using Single Sign-on (SSO), are user attributes correct?

+ +

Root cause: If people are logging in with SSO, but the expected attributes aren’t being saved and made available, sandboxing will deny access.

+ +

Steps to take:

+ +

Our docs on Authenticating with SAML and Authenticating with JWT explain how to use your identity provider to pass user attributes to Metabase, which (the user attributes) can be used to sandbox data.

+ +

People can see columns they’re not supposed to see

+ +

Did the administrator forget to set up a sandbox?

+ +

Root cause: The administrator didn’t restrict access to the underlying table when setting up sandboxing.

+ +

Steps to take:

+ +
    +
  1. Go into Admin Panel > Permissions for the table in question.
  2. +
  3. Check that the sandbox exists, and that the question used to sandbox the table excludes the columns you don’t want people to see.
  4. +
+ +

Does the question used to set up the sandbox include the columns?

+ +

Root cause: The question used to create the sandbox includes the columns they’re not supposed to see.

+ +

Steps to take:

+ +

Make sure that you’re using a SQL question to create the sandbox, and that you’re not including columns you should be excluding.

+ +

If you build a question using the query builder (i.e., use a simple or custom question), you may unintentionally pull in additional columns. You can check exactly which columns are included by viewing the question in the Notebook Editor and clicking on the View the SQL button. But again: if you use SQL questions to sandbox the data, this problem goes away.

+ +

Is the person in another group with a different permission level for the table?

+ +

Root cause: You’ve sandboxed the table with the question, but the person is also in an group with a higher level of access to the table. If a person is in multiple groups, they’ll get the most permissive access to a data source across all of their groups.

+ +

Steps to take:

+ +

Remove the person from all groups with higher level access to the sandboxed table. If they need some permissions from those other groups, you’ll need to create a new group with a new set of permissions that only has sandboxed access to the table in question.

+ +

People can’t see columns they should be able to see

+ +

Do they only have sandboxed access to the table?

+ +

Root cause: They only have access to a sandboxed version of the table, where only some columns are shown.

+ +

Steps to take:

+ +

Add these people to a group (or create a new group) that has permissions to view the table.

+ +

Has an administrator hidden fields in the table?

+ +

Root cause:: An administrator has hidden fields in the table.

+ +

Steps to take:

+ +

Go to Admin > Table Metadata and find the table. Check to make sure that the fields you want to make visible are not hidden.

+ +

Is a field remapped to display info from a restricted table?

+ +

Root cause: If a table which the person does have sandboxed access has a field that uses remapping to display information from another table which the person lacks sandboxed access to, they won’t be able to see the table. For example, if you have remapped an ID field to display a product’s name instead, but the person lacks access to the product table, they won’t be able to see the column.

+ +

Steps to take:

+ +
    +
  1. Go to Admin Panel > Table Metadata for the fields in question.
  2. +
  3. If the value is remapped from a restricted table, change it so that Metabase will use the original value from the table. See Metadata editing for more information.
  4. +
+ +

Is the question available via static embedding?

+ +

Root cause: Static embedding will show all results by default. While it’s possible to control filtering with locked parameters, static embedding depends only on the token generated by the including page, not whether someone is logged into Metabase.

+ +

Steps to take:

+ +

Since someone must log in so that Metabase can apply sandboxed views to that person, avoid using static embedding when you want to restrict row or column access to a table.

+ +

People can’t see data they’re supposed to be able to see

+ +

Someone is supposed to be able to view some of the values in a table in their queries, but are denied access or get an empty set of results where there should be data.

+ +

Root cause: The administrator restricted access to the table. Administrators usually restrict access to tables as part of sandboxing; if the restrictions are too tight by mistake (e.g., “no access”) then people might not be able to see any data at all.

+ +

Steps to take:

+ +
    +
  1. Check the access level for the groups by going to Admin Panel and viewing Permissions for the table in question.
  2. +
  3. If the person isn’t in a group with access to that table, add them to a group that does, or create a new group with access to that table and add them to that new group.
  4. +
+ +

Is the person who can’t see the sandboxed data in multiple groups?

+ +

Root cause: We only allow one sandbox per table: if someone is a member of two or more groups with different permissions, every rule for figuring out whether access should be allowed or not is confusing. We therefore only allow one rule.

+ +

Steps to take:

+ +

The administrator can create a new group to capture precisely who’s allowed access to what.

+ +

Do you have a different problem?

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/server-logs.html b/_site/docs/doc-update-detection/troubleshooting-guide/server-logs.html new file mode 100644 index 000000000..104d872fc --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/server-logs.html @@ -0,0 +1,3066 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +How to read the server logs | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

How to read the server logs

+ +

Here’s an example log from running a query:

+ +
2021-07-07 15:53:18,560 DEBUG middleware.log :: POST /api/dataset 202 [ASYNC: completed] 46.9 ms (17 DB calls) App DB connections: 1/10 Jetty threads: 3/50 (4 idle, 0 queued) (72 total active threads) Queries in flight: 0 (0 queued); h2 DB 4 connections: 0/1 (0 threads blocked)
+
+ +

Let’s unpack the log:

+ +
    +
  • Time of log: 2021-07-07 15:53:18,560.
  • +
  • Log level: DEBUG. There are different types of log levels. To learn more, check out Metabase logs.
  • +
  • Namespace:. middleware.log. You can tweak your logging level to get more or less information from this namespace.
  • +
  • Method: POST. The HTTP method verb, like POST, PUT, GET, DELETE.
  • +
  • Path: /api/dataset. The handling URL. Note that URL parameters aren’t included, which can make debugging certain issues a little tricky.
  • +
  • Code: 202. The HTTP status code.
  • +
  • ASYNC: [ASYNC: completed]. Whether Metabase could deliver the results to the browser. If Metabase couldn’t deliver the results, for example if someone starts a query and closes their browser before the query finishes, the ASYNC status will say “cancelled”.
  • +
  • Response time: 46.9 ms. The time Metabase takes to handle the request (from when Metabase receives the request until it’s returned results back to the browser).
  • +
  • Database calls: (17 DB calls). The number of query statements used, which in addition to calls to the queried data source(s), includes calls to the Metabase application database.
  • +
  • Application database connections: App DB connections: 1/10. The number of active connections, and the available pool of connections.
  • +
  • Jetty threads: Jetty threads: 3/50 (4 idle, 0 queued). List the number of active threads, and the total pool of threads available. The (4 idle, 0 queued) are the spare hot threads, and the number of threads queued. If you find you’re maxing out the number threads in your pool, check out Metabase at scale.
  • +
  • Java threads: (72 total active threads). The total number of threads Metabase is using.
  • +
  • Queries in flight: Queries in flight: 0 (0 queued). The number of active and queued queries across all database sources connected to Metabase. We recommend checking the Database info below for troubleshooting issues with the database related to the request.
  • +
  • Database info:h2 DB 4 connections: 0/1 (0 threads blocked). Shows database type, database ID, connections active/pool (and queue). This info is specific to the database related to the request (in this case a POST request), and not to the overall queries in flight.
  • +
+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/sql.html b/_site/docs/doc-update-detection/troubleshooting-guide/sql.html new file mode 100644 index 000000000..e76e3f561 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/sql.html @@ -0,0 +1,3079 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting SQL questions | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting SQL questions

+ +

Incorrect results

+ + + +

SQL variables and field filters

+ + + +

SQL syntax errors

+ +

For some common error messages, see error messages.

+ +

Working with JSON in SQL

+ +

Using the ? operator for working with JSON in SQL may cause queries to fail. On PostgreSQL, you can use ?? instead.

+ +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/sync-fingerprint-scan.html b/_site/docs/doc-update-detection/troubleshooting-guide/sync-fingerprint-scan.html new file mode 100644 index 000000000..b0c6dc33a --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/sync-fingerprint-scan.html @@ -0,0 +1,3231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting syncs, scans, and fingerprinting | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting syncs, scans, and fingerprinting

+ +

First, check if your data is outdated because of browser caching:

+ +
    +
  1. Clear your browser cache.
  2. +
  3. Refresh your Metabase page.
  4. +
  5. Open your Metabase page in an incognito window.
  6. +
+ +

Once you’ve confirmed that you’re looking at a non-cached view of your tables and columns, tag your database admin for help with troubleshooting:

+ +
    +
  • Syncs, if your tables or columns are missing, or your column data types are wrong.
  • +
  • Scans, if your column values are missing or wrong (for example, in your filter dropdown menus).
  • +
  • Fingerprinting, if you’ve triggered a manual scan, but the changes aren’t taking effect.
  • +
+ +

Syncing

+ +
    +
  1. Make sure your database driver is up to date.
  2. +
  3. Go to Admin > Troubleshooting > Logs to check the status of the sync.
  4. +
  5. +

    Run a query against your database from the Metabase SQL editor to check for database connection or database privilege errors that aren’t listed in the logs:

    + +
    SELECT
    +   *
    +FROM
    +    "your_schema"."your_table_or_view"
    +LIMIT 1
    +
    +
  6. +
  7. Manually re-sync the table or view if needed.
  8. +
+ +

Special cases

+ +

If you’ve just set up a new database in Metabase, the initial sync query needs some time to kick off. If the sync hasn’t started at all, try Troubleshooting database connections.

+ +

Explanation

+ +

A sync query should show up like this in your database’s query execution table (using the privileges for the database user in the database connection details):

+ +
SELECT
+    TRUE
+FROM
+    "your_schema"."your_table_or_view"
+WHERE
+    1 <> 1
+LIMIT 0
+
+ +

To run the sync query, Metabase must:

+ +
    +
  • successfully connect to your database, and
  • +
  • be granted privileges to query that database.
  • +
+ +

If the connection is failing or the database privileges are wrong, the sync query won’t be able to run. If Metabase can’t sync with your database after you first set it up, then the initial scan and fingerprinting queries won’t run either.

+ +

Unfolding JSON columns with Object records

+ +
    +
  1. Go to Admin > Databases > your database > Show advanced options.
  2. +
  3. Click Disable “JSON unfolding”
  4. +
  5. Click Save changes.
  6. +
  7. Click Sync database schema.
  8. +
+ +

Explanation

+ +

Metabase will try to unfold JSON and JSONB records during the sync process, which can take up a decent chunk of query execution time. If you have a lot of JSON records, try disabling the automatic unfolding option to pull the sync out of slow-motion. Remember that you can follow the status of the sync from Admin > Troubleshooting > Logs.

+ +

Scanning

+ +
    +
  1. Go to Admin > Table Metadata.
  2. +
  3. Select the database and table.
  4. +
  5. Go to the column you want to update, and click the gear icon.
  6. +
  7. Click Discard cached field values.
  8. +
  9. Click Re-scan this field.
  10. +
  11. Go to Admin > Troubleshooting > Logs to follow the status of the scan and debug errors from there.
  12. +
+ +

Special cases

+ +

If you’re waiting for the initial scan to run after connecting a database, make sure the initial sync has completed first (remember you can check the status from Admin > Troubleshooting > Logs).

+ +

Explanation

+ +

Scan queries are run against your database to sample column values from the first 1,000 rows in a table or view:

+ +
SELECT
+    "your_table_or_view"."column" AS "column"
+FROM
+    "your_schema"."your_table_or_view"
+GROUP BY
+    "your_table_or_view"."column"
+ORDER BY
+    "your_table_or_view"."column" ASC
+LIMIT 1000
+
+ +

A failed scan is caused by a failed scan query—you can look at the logs to debug the query similar to other queries you’d run directly against your database.

+ +

Note that when you change a search box filter to a dropdown filter from the Table Metadata, you’ll trigger a scan query for that field. If you have a dropdown filter that isn’t picking up all the values in a field, remember that Metabase only samples the first 1,000 unique values per field, and stores a maximum of 100 kilobytes of text. If you’ve got more than 1,000 unique values in a column, or a lot of text-heavy data (like long URLs or survey responses), you can:

+ +
    +
  • Use a search box filter for that field.
  • +
  • Clean up the data further in your ETL or ELT process.
  • +
+ +

Fingerprinting

+ +

To manually re-trigger a fingerprinting query for a given column:

+ +
    +
  1. Go to Admin > Databases > your database > Show advanced options.
  2. +
  3. Toggle ON Periodically refingerprint tables and click Save changes.
  4. +
  5. Go to Admin > Table Metadata.
  6. +
  7. Select your database and table.
  8. +
  9. Change the visibility of the table to “Hidden”.
  10. +
  11. Change the visibility back to “Queryable”.
  12. +
  13. Wait 10 seconds.
  14. +
  15. Go to your column and change the Type from “Entity Key” to “No semantic type”, and back to “Entity Key”.
  16. +
+ +

Special cases

+ +

If you’re waiting for the initial fingerprinting query to run after connecting a database, make sure the initial sync has completed first (remember you can check the status from Admin > Troubleshooting > Logs).

+ +

If you’re using MongoDB, Metabase fingerprints the first 10,000 documents per collection. If you’re not seeing all of your fields, it’s because those fields might not exist in those first 10,000 documents. For more info, see our MongoDB reference doc.

+ +

Explanation

+ +

The initial fingerprinting query looks at the first 10,000 rows from a given table or view in your database:

+ +
SELECT
+    *
+FROM
+    "your_schema"."your_table_or_view"
+LIMIT 10000
+
+ +

If the first 10,000 rows aren’t representative of the data in a table (for example, if you’ve got sparse data with a lot of blanks or nulls), you could see issues such as:

+ +
    +
  • Incorrect filter types, such as a category when you want a calendar.
  • +
  • Histogram visualizations that don’t work (since Metabase needs a min and max value to generate the bins).
  • +
+ +

Metabase doesn’t have a built-in option to trigger manual fingerprinting queries. You can “reset” a field’s settings using the steps above to try and force a fingerprinting query, but it’s not guaranteed to work on all versions of Metabase.

+ +

Syncing or scanning is taking a long time

+ +

To speed up syncs:

+ + + +

To speed up scans:

+ + + +

Explanation

+ +

Syncs and scans are ultimately just two kinds of queries that are run against your database, so the speed of execution is limited by the number of queries that are run, the frequency of execution, the size of your data, and the amount of resources you’ve allocated to your database. Metabase gives you options to adjust the number and frequency of sync and scan queries, since unfortunately, we can’t imbue your database with more power… (yet?)

+ + + + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/timeout.html b/_site/docs/doc-update-detection/troubleshooting-guide/timeout.html new file mode 100644 index 000000000..6dc5e9bd5 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/timeout.html @@ -0,0 +1,3072 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting connection timeouts | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting connection timeouts

+ +

If your queries are hanging or timing out, the problem could be coming from your:

+ +
    +
  • Database connection
  • +
  • Load balancer
  • +
  • Reverse proxy server (e.g., Nginx)
  • +
  • Jetty
  • +
  • Cloud service
  • +
+ +

Resources for common deployments

+ +

Fixes for timeout problems will depend on your specific setup. These resources may help:

+ + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/timezones.html b/_site/docs/doc-update-detection/troubleshooting-guide/timezones.html new file mode 100644 index 000000000..67ee304b0 --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/timezones.html @@ -0,0 +1,3131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +The dates and times in my questions and charts are wrong | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

The dates and times in my questions and charts are wrong

+ +

You are doing calculations with dates and times, or displaying them in charts, but:

+ +
    +
  • the values appear to be wrong, or
  • +
  • summary values are wrong.
  • +
+ +

Is the problem due to time zones?

+ +

Root cause: Dates and times are stored using different time zones, but some or all of those time zones aren’t taken into account when doing calculations (i.e., the problem is inconsistent data).

+ +

Steps to take:

+ +

To fix this problem you’ll need answers to these questions:

+ +
    +
  1. What is the correct time zone of the data you think is being displayed improperly (i.e., what’s the right answer)?
  2. +
  3. Is there an explicit time zone setting on every timestamp, or are some or all timestamps being stored without a time zone? For example, Dec 1, 2019 00:00:00Z00 includes the time zone (shown after the Z), but Dec 1, 2019 doesn’t.
  4. +
  5. What time zone is the database server using?
  6. +
  7. What time zone is Metabase using?
  8. +
+ +

Once you have these answers, look for cases like these:

+ +
    +
  1. Your question or chart is comparing or sorting values with inconsistent or missing time zones. For example, if a flight’s departure and arrival times are reported in local time, it can appear to arrive before it has left.
  2. +
  3. Your question is aggregating timetsamps with different time zones: for example, the “daily” totals for your website’s traffic include more than 24 hours worth of data because you are using the local dates from East Asia, Europe, and the Americas.
  4. +
+ +

Once you think you have identified a problem, drill down to understand exactly what time zone conversion is causing the underlying problem. For example, suppose you’re looking at a time series with daily values; if your error is happening with weekly totals, you can:

+ +
    +
  1. Pick a specific day where you know the number is incorrect.
  2. +
  3. Click on the data point in a chart, or a cell in a result table, and select “See these X.”
  4. +
  5. Open this question in two other tabs in your browser. Change the date filters so that one tab has the rows in the underlying table from the previous day, and the other table has the rows in the underlying table from the next day.
  6. +
  7. Check that the date field being used to group the result in the underlying display is correct. If it is different from what you have stored in the database, or what you have in another tool, then the timestamp is being transformed incorrectly across the board. This often happens when you use a date or time lacking an explicit time zone.
  8. +
  9. If the underlying timestamps are correct (which they should if they have explicit time zones), the individual times are probably being grouped into days in a different time zone than the one you want.
  10. +
  11. To find out which time zone they are being transformed to, tweak the times on the date filters on the question you are looking at by moving the start time and start date backwards by an hour until you either get the correct number or you have gone back by 12 hours. (If any of your time zones include India, Newfoundland, or another jurisdiction with a half-step time zone, you may need to do this in half-hour increments.)
  12. +
  13. If that doesn’t work, try moving the start and end times forward by an hour until you either get the correct number of you’ve gone forward by 12 hours.
  14. +
  15. If by this point you have the correct value, it means your time zone was converted by the number of hours forward or backwards you manually set the filter. If that’s the case, check whether the offset you’ve come up with matches either the time zone of the data warehouse or the timezone of Metabase itself.
  16. +
+ +

Is the Report Time Zone set incorrectly?

+ +

Root cause: Wrong numbers in questions or charts can be caused by a mis-match in the time zone being used by Metabase and the time zone being used by the data warehouse.

+ +

Steps to take:

+ +
    +
  1. Check the report timezone setting from Admin settings > Settings > Localization.
  2. +
  3. If you’re using a database that doesn’t support the report timezone setting, ensure that Metabase’s time zone matches that of the database. Metabase’s time zone is the Java Virtual Machine’s time zone, typically set via a -Duser.timezone<..> parameter or the JAVA_TIMEZONE environment variable; exactly how it is set will depend on how you launch Metabase. Note that Metabase’s time zone doesn’t impact any databases that use a Report Time Zone.
  4. +
+ +

Are SQL queries not respecting the Reporting Time Zone setting?

+ +

Root cause: We don’t currently apply a reporting time zone to the results of SQL queries.

+ +

Steps to take:

+ +

Set a reporting time zone explicitly in your SQL query.

+ +

For example, you can write something like this with PostgreSQL:

+ +
SELECT column::TIMESTAMP AT TIME ZONE 'EST' AS column_est
+
+ +

This statement casts the column to a timestamp data type first, then converts the timestamp into a timestamptz data type, with time zone ‘EST’.

+ +

Are dates without an explicit time zone being converted to another day?

+ +

Root cause: You are grouping by a date (rather than by a time) that lacks a time zone.

+ +

Steps to take:

+ +
    +
  1. Look at every time field your question uses in the Data Model Reference and see if any of them are simply a “Date” field.
  2. +
  3. If so, make sure the server time zone reflects the reporting time zone, because when a query is run on Metabase, the server applies the configured time zone to that date.
  4. +
+ +

Are you mixing explicit and implicit time zones?

+ +

Root cause: You’re comparing or doing arithmetic on two dates where one has an explicit time zone and one doesn’t.

+ +

Steps to take:

+ +
    +
  1. This typically happens with a question that uses multiple fields: for example, you’re filtering on one timestamp and grouping by another. Check the time zones of each of the dates or times you are using in your question.
  2. +
  3. You’ll need to explicitly set the time zone for any value that lacks an explicit time zone. This will need to be done either in a SQL query or by transforming the data in your database to ensure both timestamps have time zones.
  4. +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/troubleshooting-guide/visualization.html b/_site/docs/doc-update-detection/troubleshooting-guide/visualization.html new file mode 100644 index 000000000..288e3b82d --- /dev/null +++ b/_site/docs/doc-update-detection/troubleshooting-guide/visualization.html @@ -0,0 +1,3094 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Troubleshooting question and dashboard visualizations | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Troubleshooting question and dashboard visualizations

+ +

To start, check if your current browser settings are compatible with Metabase:

+ +
    +
  1. Clear your browser cache, and refresh your page.
  2. +
  3. Disable all extensions and plugins. Load the page again.
  4. +
  5. Give it one last shot—try opening your page in a private/incognito session, or a different browser.
  6. +
+ +

Formatting dashboard cards

+ +
    +
  1. Make sure that you’re making and saving changes from the card’s settings (not the original question’s settings).
  2. +
  3. Reset your card’s visualization settings.
  4. +
+ +

Explanation

+ +

The visualization settings on a card are independent of the settings on the original question. When you first create a question, your selected visualization type is saved along with the query. When you add that question to a dashboard, the dashboard will display the same visualization as the original question by default. You can override the original visualization type by using the card’s visualization settings.

+ +

Visualizing SQL questions

+ +

Go to your SQL question and change the visualization type to a table. Then, check if any of the following situations apply to the raw query results:

+ + + +

Explanation

+ +

If your question or dashboard card is powered by a handwritten SQL query rather than the query builder, your visualization is going to be more sensitive to changes in the underlying data (for example, renamed fields, or the sudden appearance of a wild null value). To learn more, read about Common reasons for unexpected query results.

+ +

If you’re having problems with things like SQL syntax errors or SQL variables, see Troubleshooting SQL questions for more help.

+ + + + + +

Are you still stuck?

+ +

If you can’t solve your problem using the troubleshooting guides:

+ + + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/usage-and-performance-tools/audit.html b/_site/docs/doc-update-detection/usage-and-performance-tools/audit.html new file mode 100644 index 000000000..f8fcbf1d2 --- /dev/null +++ b/_site/docs/doc-update-detection/usage-and-performance-tools/audit.html @@ -0,0 +1,3172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Auditing tools | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Auditing tools

+ +
+

Auditing tools are deprecated. Instead, check out the (much better) Usage analytics.

+
+ +
+
+ + + + + + + +

Audit logs is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

As an administrator of Metabase, you already know the importance of using data to understand how people interact with your products or services. With the Audit tool, you can use Metabase to understand how people in your organization use Metabase. It’s, well, meta!

+ +

To view the audit logs, go to the top right of the screen and click on the gear icon > Admin settings > Audit. There’s a lot of data available, not only about your people, but also about your questions, dashboards, databases and more! We’ll walk you through each of the sections below.

+ +

People

+ +

Team members

+ +

Use the People section to gain a better understanding of how people are interacting with Metabase. You’ll want to pay attention to the Overview tab, especially when you first launch Metabase at your organization — it will give you data around how many active and newly created accounts you have each day. Further down the page, you’ll see charts showing you which people are most engaged.

+ +

Team Members

+ +

The Team Members panel has a view of other options for viewing your team’s usage data. The All Members tab will give you a list of your team members, and stats about their activity, such as when they were last active.

+ +

The Audit Log tab will display, in chronological order, each query, who viewed it, and when. Note that if the person didn’t save their query, its name will be listed as Ad-hoc. Each query name can be clicked to view more details about the person’s interactions with it, including a full revision history. You’ll also be able to view the query in Metabase. Note that this link will always show the latest version of the query - use the revision history to see changes over time.

+ +

Throughout the People section, names can be clicked to access the profile of a specific person’s activity. This profile includes:

+ +
    +
  • Dashboard views
  • +
  • Query views
  • +
  • Downloads
  • +
  • Subscriptions and Alerts
  • +
+ +

Team Members

+ +

Data

+ +

The Data section focuses on your databases, schemas and tables, and is divided into corresponding sections. Look here if you’re trying to uncover queries and schemas that need optimization. Each section provides visualizations around the use and speed of querying against your databases, schemas or tables. You will also be able to view lists of stats about all of your databases, schemas and tables.

+ +

Data

+ +

Items

+ +

The Items section focuses on questions, dashboards, downloads, and Subscriptions and Alerts.

+ +

Questions

+ +

The Questions section will show you your most popular queries, as well as your slowest queries. If queries you think are important aren’t appearing on your most popular queries list, you may want to make sure your team is focusing on the right things.

+ +

If important queries are appearing on the list of slowest queries, you will want to look at optimizing them. One option is to adjust your caching settings, but there are plenty of other options as well. To help you determine if your optimization efforts are heading in the right direction, use the Query views and speed per day visualization at the bottom of the page.

+ +

Items

+ +

A list of all of your questions is available as well, and you can see various data points about each question at a glance:

+ +
    +
  • Query Runs
  • +
  • Average Runtime
  • +
  • Cache Duration
  • +
  • Total Runtime
  • +
  • Database
  • +
  • Table
  • +
  • Collection
  • +
  • Public Link
  • +
+ +

You can also click on any question to drill into a more detailed profile showing:

+ +
    +
  • View activity
  • +
  • Revision History
  • +
  • A full audit log of who viewed the question, and when
  • +
+ +

Dashboards

+ +

The Dashboards section helps you understand what dashboards people are looking at, and to make sure they’re having a smooth experience. If you notice that a popular dashboard has a high average question loading time, you can investigate further using the Questions section outlined above.

+ +

Items

+ +

A list of all of your dashboards is available as well, and you can see various data points about each dashboard at a glance, such as:

+ +
    +
  • Number of views
  • +
  • Average question execution time(ms)
  • +
  • Number of cards
  • +
  • Saved by
  • +
  • Cache duration
  • +
  • Public link
  • +
  • Saved on
  • +
  • Last edited on
  • +
+ +

Downloads

+ +

Use the Downloads section to understand which people are downloading (or exporting) data, and the size (number of rows) of the downloads they’re performing. This section contains some visualizations, as well as a list of all downloads.

+ +

Subscriptions and Alerts

+ +

Here admins can get an overview of all of the dashboard subscriptions and alerts that are currently active for that Metabase.

+ +
    +
  • Dashboard name (or Question name for Alerts)
  • +
  • Recipients
  • +
  • Type (e.g., email or Slack)
  • +
  • Collection
  • +
  • Frequency
  • +
  • Created By
  • +
  • Created At
  • +
  • Filters
  • +
+ +

Admins can add and remove people from a subscription or alert by clicking on the item’s Recipients number. Admins can also delete the subscription or alert entirely by clicking on the X on the relevant line.

+ +

Everyone can view all of their subscriptions and alerts by clicking on the gear icon in the upper right and navigating to Account settings > Notifications.

+ +

For more, see how permissions work with alerts and subscriptions.

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-dashboards.png b/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-dashboards.png new file mode 100644 index 000000000..7e6a69d61 Binary files /dev/null and b/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-dashboards.png differ diff --git a/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-data.png b/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-data.png new file mode 100644 index 000000000..b1bab9d66 Binary files /dev/null and b/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-data.png differ diff --git a/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-questions.png b/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-questions.png new file mode 100644 index 000000000..01d7faa1e Binary files /dev/null and b/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-questions.png differ diff --git a/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-team.png b/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-team.png new file mode 100644 index 000000000..a1bb5ce67 Binary files /dev/null and b/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-team.png differ diff --git a/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-teammember.png b/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-teammember.png new file mode 100644 index 000000000..fcf9e5ca3 Binary files /dev/null and b/_site/docs/doc-update-detection/usage-and-performance-tools/images/audit-teammember.png differ diff --git a/_site/docs/doc-update-detection/usage-and-performance-tools/images/metabase-analytics.png b/_site/docs/doc-update-detection/usage-and-performance-tools/images/metabase-analytics.png new file mode 100644 index 000000000..29aa97282 Binary files /dev/null and b/_site/docs/doc-update-detection/usage-and-performance-tools/images/metabase-analytics.png differ diff --git a/_site/docs/doc-update-detection/usage-and-performance-tools/start.html b/_site/docs/doc-update-detection/usage-and-performance-tools/start.html new file mode 100644 index 000000000..cfb025871 --- /dev/null +++ b/_site/docs/doc-update-detection/usage-and-performance-tools/start.html @@ -0,0 +1,3073 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Tools overview | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Tools overview

+ +

Administration tools for managing your Metabase.

+ +

Usage analytics

+ +

See how people are using your Metabase.

+ +

Admin tools

+ +

View question error and model caching logs.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/usage-and-performance-tools/tools.html b/_site/docs/doc-update-detection/usage-and-performance-tools/tools.html new file mode 100644 index 000000000..645228846 --- /dev/null +++ b/_site/docs/doc-update-detection/usage-and-performance-tools/tools.html @@ -0,0 +1,3084 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Admin tools | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Admin tools

+ +

The Admin Tools tab contains features for troubleshooting. To get to the Admin tools sections, go to the top right of the screen and click on the gear icon > Admin settings > Tools.

+ +

Question error logs

+ +
+
+ + + + + + + +

Question error logs is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

Metabase will list the questions that returned errors when last run, including the:

+ +
    +
  • Error message,
  • +
  • Database that returned the error,
  • +
  • Collection that houses the question that errored.
  • +
+ +

You can select and rerun multiple questions at a time while you troubleshoot to see whether you’ve resolved their errors.

+ +

Model caching logs

+ +

Here you can view the:

+ +
    +
  • Models being persisted
  • +
  • The status of the last model query refresh
  • +
  • When the model was last refreshed
  • +
  • And who created the persisted model
  • +
+ +

You can also click the refresh icon to rerun the model’s query to update its results.

+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/usage-and-performance-tools/usage-analytics.html b/_site/docs/doc-update-detection/usage-and-performance-tools/usage-analytics.html new file mode 100644 index 000000000..fe1139744 --- /dev/null +++ b/_site/docs/doc-update-detection/usage-and-performance-tools/usage-analytics.html @@ -0,0 +1,3521 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Usage analytics | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + doc-update-detection + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ + +
+ These are the docs for Metabase doc-update-detection. + Check out the docs for the latest version, Metabase v0.53. +
+ + +
+ + +

Usage analytics

+ +
+
+ + + + + + + +

Usage analytics is only available on Pro and Enterprise plans + + (both self-hosted and on Metabase Cloud). +

+
+
+ +

The Usage analytics collection is a special collection that contains view-only questions, dashboards, and models that help you understand how people are using your Metabase.

+ +

Usage analytics collection

+ +

You can find the Usage analytics collection under collections in the left navigation sidebar. You can also create custom reports.

+ +

These resources are useful for:

+ +
    +
  • Understanding Usage: Understand how people use your Metabase (e.g., new questions, most active people and groups, and so on).
  • +
  • Auditing activity: Know who viewed or did what and when, including tracking dashboard and question views, queries, downloads, and other activity like changing settings or inviting people to your Metabase.
  • +
  • Improving operations: Know the slowest dashboards and questions, how your database’s are performing, who’s consuming the most resources, and so on.
  • +
+ +
+

Metabase creates some default user accounts that you might see in your usage analytics, like internal@metabase.com. See Default accounts.

+
+ +

Access to Usage analytics

+ +

You can find the Usage analytics collection under collections in the navigation sidebar. By default, only admins can see the Usage analytics collection, but admins can grant other groups view access to it. You can manage permissions for the collection in Admin settings > Permissions > Collections.

+ +

There are only two access types for the Usage analytics collection: View and No access. Even admins can’t curate Usage analytics.

+ +

Additionally, this Usage analytics collection has a default sub-collection called “Custom reports” which you can use to save duplicated/modified questions, dashboards, and models. This sub-collection inherits the same permissions, but it’s not view-only; admins have curate access by default, and can grant other groups view access.

+ +
+

If you’re upgrading from a version older than 48, people in groups with monitoring access will also get access to the Usage analytics collection. But after that initial grandfathering in, the monitoring access privilege is unrelated to the Usage analytics collection; you’ll need to specifically grant groups access to the Usage analytics collection.

+
+ +

Viewing usage insights for a question, dashboard, or model

+ +
+

Only people in groups with view access to the Usage analytics collection will see this Usage insights option.

+
+ +

To view usage analytics for a question, dashboard, or model:

+ +
    +
  • Visit the item.
  • +
  • Click on the info button in the upper right.
  • +
  • Click Insights.
  • +
+ +

Metabase will take you to the relevant usage dashboard and plug in the item’s ID.

+ +

How long Metabase keeps usage data

+ +

By default, Metabase will keep the data about activity, views, and query execution for 720 days. Twice a day, Metabase will delete rows older than this threshold. You can change this limit by adjusting the environment variable MB_AUDIT_MAX_RETENTION_DAYS.

+ +

Metabase Open Source edition, which is also used on the Metabase Cloud Starter plan, doesn’t collect Activity and View data. If you upgrade from the Open Source/Starter to a Pro or Enterprise plan, you’ll only see View and Activity data in Usage Analytics starting from the time when you upgraded.

+ +

Creating custom reports

+ +

You can duplicate any of the questions, dashboards and models in the Usage analytics collection and tweak them to your liking, but you’ll need to save them to a different collection.

+ +

Custom reports collection

+ +

While you can save custom questions, models, and dashboards wherever you like (except for the Usage analytics collection), we recommend that you save your custom Usage analytics reports in the conveniently named “Custom reports” sub-collection. That way these items inherit the same permissions as the parent Usage analytics collection.

+ +

There is one thing to know about the Custom reports collection: its metadata resets whenever Metabase restarts. While you are able to temporarily rename the Custom reports collection, or give it a description or an Official badge, Metabase will drop this collection’s metadata when it restarts. But rest assured that Metabase will preserve any questions, models, events, or dashboards that you add to the Custom reports collection.

+ +

Dashboards

+ +

The Usage analytics collection includes a set of read-only dashboards.

+ +

Metabase metrics dashboard

+ +

General information about people viewing and creating dashboards, questions, subscriptions, and alerts. Cards include:

+ +
    +
  • Active users last week
  • +
  • Question views last week
  • +
  • Questions created last week
  • +
  • Dashboards created last week
  • +
  • Alerts and subscriptions created last week
  • +
  • Weekly active users
  • +
  • Question views per week
  • +
  • Most active users
  • +
  • Most active creators
  • +
  • Most viewed dashboards
  • +
  • Most viewed cards
  • +
+ +

Most viewed content dashboard

+ +

View the most relevant content in your Metabase. Cards include:

+ +
    +
  • Most viewed dashboards
  • +
  • Most viewed questions
  • +
  • Most viewed tables
  • +
+ +

Person overview dashboard

+ +

See what someone’s been up to in your Metabase. Cards include:

+ +
    +
  • Member of
  • +
  • Active alerts
  • +
  • Questions created per month
  • +
  • Question views per month
  • +
  • Most viewed dashboards
  • +
  • Most viewed questions
  • +
  • Last viewed dashboards
  • +
  • Last viewed questions
  • +
  • Last viewed tables
  • +
  • Recent activity
  • +
  • Last queries
  • +
+ +

Dashboard overview dashboard

+ +

Information about dashboards, questions, models, and tables. Cards include:

+ +
    +
  • Dashboard metadata
  • +
  • Dashboard views per month
  • +
  • Question performance
  • +
  • Most active people on this dashboard
  • +
  • Questions in this dashboard
  • +
  • Most active people on this dashboard
  • +
  • Questions in this dashboard
  • +
  • Recent activity on dashboard
  • +
  • Subscriptions on this dashboard
  • +
+ +

Question overview dashboard

+ +

Views, performance, activity, and other data for a particular question. Cards include:

+ +
    +
  • Question metadata
  • +
  • Question views per month
  • +
  • Question performance
  • +
  • Most active people on this question
  • +
  • Dashboards with this question
  • +
  • Last activity on this question
  • +
  • Alerts on this question
  • +
+ +

Performance overview dashboard

+ +

Question, dashboard and database performance. Cards include:

+ +
    +
  • Slowest dashboards
  • +
  • Dashboards consuming most resources
  • +
  • Slowest questions
  • +
  • Questions consuming the most resources
  • +
  • Dashboards with more questions in the same tab
  • +
  • Users consuming the most resources
  • +
+ +
+

If you’re using MySQL or MariaDB as your application database, the Performance overview dashboard won’t display results for the cards displaying the 50th and 90th percentile query running times, because MySQL and MariaDB don’t support the Percentile aggregation. We recommend using PostgreSQL as your application database.

+
+ +

Content with cobwebs dashboard

+ +

Dashboards and questions that you could consider archiving. Cards include:

+ +
    +
  • Dashboards without recent reviews
  • +
  • Questions without recent reviews
  • +
  • Questions that don’t belong to a dashboard
  • +
+ +

Models

+ +

The Usage analytics collection includes a bunch of useful models based on Metabase’s application database.

+ +

Activity log model

+ +

Each row of this model describes one event of a particular topic. Fields include:

+ +
    +
  • ID
  • +
  • Topic
  • +
  • Timestamp
  • +
  • End Timestamp
  • +
  • User ID
  • +
  • Model
  • +
  • Model ID
  • +
  • Details
  • +
+ +

The topics include:

+ +
    +
  • alert-create
  • +
  • alert-delete
  • +
  • card-create
  • +
  • card-delete
  • +
  • card-update
  • +
  • dashboard-add-cards
  • +
  • dashboard-create
  • +
  • dashboard-delete
  • +
  • dashboard-remove-cards
  • +
  • install
  • +
  • metric-create
  • +
  • metric-delete
  • +
  • metric-update
  • +
  • segment-create
  • +
  • segment-delete
  • +
  • segment-update
  • +
  • setting-update
  • +
  • subscription-create
  • +
  • subscription-delete
  • +
  • user-joined
  • +
+ +

View log model

+ +

Tracks views cards (which includes models), dashboards, and tables. Fields include:

+ +
    +
  • ID
  • +
  • Timestamp
  • +
  • User ID
  • +
  • Entity Type (card, dashboard, or table)
  • +
  • Entity ID
  • +
  • Entity Qualified ID
  • +
+ +

Query log model

+ +

Information about all queries Metabase ran across all dashboards. Fields include:

+ +
    +
  • Entity ID
  • +
  • Started At
  • +
  • Running Time Seconds
  • +
  • Result Rows
  • +
  • Is Native
  • +
  • Query Source
  • +
  • Error
  • +
  • User ID
  • +
  • Card ID
  • +
  • Card Qualified ID
  • +
  • Dashboard ID
  • +
  • Dashboard Qualified ID
  • +
  • Pulse ID
  • +
  • Database ID
  • +
  • Database Qualified ID
  • +
  • Cache Hit
  • +
  • Action ID
  • +
+ +

Query sources include:

+ +
    +
  • action
  • +
  • ad-hoc
  • +
  • collection
  • +
  • csv-download
  • +
  • dashboard
  • +
  • embedded-dashboard
  • +
  • embedded-csv-download
  • +
  • embedded-json-download
  • +
  • embedded-question
  • +
  • embedded-xlsx-download
  • +
  • json-download
  • +
  • map-tiles
  • +
  • metabot (experimental)
  • +
  • public-dashboard
  • +
  • public-question
  • +
  • pulse (which includes dashboard subscriptions and alerts)
  • +
  • question
  • +
  • xlsx-download
  • +
+ +

Alerts model

+ +

All alerts, both active and archived.

+ +
    +
  • Entity ID
  • +
  • Entity Qualified ID
  • +
  • Created At
  • +
  • Updated At
  • +
  • Creator ID
  • +
  • Card ID
  • +
  • Card Qualified ID
  • +
  • Alert Condition
  • +
  • Schedule Type
  • +
  • Schedule Day
  • +
  • Schedule Hour
  • +
  • Archived
  • +
  • Recipient Type
  • +
  • Recipients
  • +
  • Recipient External
  • +
+ +

Content model

+ +

Questions, dashboards, models, events, and collections.

+ +
    +
  • Entity ID
  • +
  • Entity Qualified ID
  • +
  • Entity Type
  • +
  • Created At
  • +
  • Updated At
  • +
  • Creator ID
  • +
  • Name
  • +
  • Description
  • +
  • Collection ID
  • +
  • Made Public By User
  • +
  • Is Embedding Enabled
  • +
  • Archived
  • +
  • Action Type
  • +
  • Action Model ID
  • +
  • Collection Is Official
  • +
  • Collection Is Personal
  • +
  • Question Viz Type
  • +
  • Question Database ID
  • +
  • Question Is Native
  • +
  • Event Timestamp
  • +
+ +

Entity types include:

+ +
    +
  • action
  • +
  • collection
  • +
  • dashboard
  • +
  • event
  • +
  • model
  • +
  • question
  • +
+ +

People model

+ +

Everyone in your Metabase, including deactivated accounts. Fields include:

+ +
    +
  • User ID
  • +
  • Email
  • +
  • First Name
  • +
  • Last Name
  • +
  • Full Name
  • +
  • Date Joined
  • +
  • Last Login
  • +
  • Updated At
  • +
  • Is Admin
  • +
  • Is Active
  • +
  • SSO Source
  • +
  • Locale
  • +
+ +

Dashboard subscriptions model

+ +

Which subscriptions are active, who created them, who’s subscribed to them, when they’re sent, and more.

+ +
    +
  • Entity ID
  • +
  • Entity Qualified ID
  • +
  • Created At
  • +
  • Updated At
  • +
  • Creator ID
  • +
  • Archived
  • +
  • Dashboard Qualified ID
  • +
  • Schedule Type
  • +
  • Schedule Day
  • +
  • Schedule Hour
  • +
  • Recipient Type
  • +
  • Recipients
  • +
  • Recipient External
  • +
  • Parameters
  • +
+ +

Dashboard cards model

+ +

Each row is a dashboard card: either a question card or a text card. Fields include:

+ +
    +
  • ID
  • +
  • Dashboard ID
  • +
  • Dashboardtab ID
  • +
  • Question ID
  • +
  • Created At
  • +
  • Updated At
  • +
  • Size X
  • +
  • Size Y
  • +
  • Visualization Settings
  • +
  • Parameter Mappings
  • +
+ +

Databases model

+ +

Information about your connected data sources. Fields include:

+ +
    +
  • Entity ID
  • +
  • Entity Qualified ID
  • +
  • Created At
  • +
  • Updated At
  • +
  • Name
  • +
  • Description
  • +
  • Database Type
  • +
  • Metadata Sync Schedule
  • +
  • Cache Field Values Schedule
  • +
  • Timezone
  • +
  • Is On Demand
  • +
  • Auto Run Queries
  • +
  • Cache Ttl
  • +
  • Creator ID
  • +
  • Db Version
  • +
+ +

Tables model

+ +

List of all tables across all connected data sources. Fields include:

+ +
    +
  • Entity ID
  • +
  • Entity Qualified ID
  • +
  • Created At
  • +
  • Updated At
  • +
  • Name
  • +
  • Display Name
  • +
  • Description
  • +
  • Active
  • +
  • Database ID
  • +
  • Schema
  • +
  • Is Upload
  • +
+ +

Fields model

+ +

All fields from all connected data sources. Fields include:

+ +
    +
  • Entity ID
  • +
  • Entity Qualified ID
  • +
  • Created At
  • +
  • Updated At
  • +
  • Name
  • +
  • Display Name
  • +
  • Description
  • +
  • Base Type
  • +
  • Visibility Type
  • +
  • Fk Target Field ID
  • +
  • Has Field Values
  • +
  • Active
  • +
  • Table ID
  • +
+ +

System tasks model

+ +

Describes the last 14 days of Metabase internal processes tasks.

+ +
    +
  • ID
  • +
  • Task
  • +
  • Database Qualified ID
  • +
  • Started At
  • +
  • Ended At
  • +
  • Duration Seconds
  • +
  • Details
  • +
+ + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/doc-update-detection/users-guide.html b/_site/docs/doc-update-detection/users-guide.html new file mode 100644 index 000000000..9664adb8b --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/03-basic-exploration.html b/_site/docs/doc-update-detection/users-guide/03-basic-exploration.html new file mode 100644 index 000000000..313c6493c --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/03-basic-exploration.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/04-asking-questions.html b/_site/docs/doc-update-detection/users-guide/04-asking-questions.html new file mode 100644 index 000000000..da0c6efb0 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/04-asking-questions.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/05-visualizing-results.html b/_site/docs/doc-update-detection/users-guide/05-visualizing-results.html new file mode 100644 index 000000000..c75a27feb --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/05-visualizing-results.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/06-sharing-answers.html b/_site/docs/doc-update-detection/users-guide/06-sharing-answers.html new file mode 100644 index 000000000..da0c6efb0 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/06-sharing-answers.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/07-dashboards.html b/_site/docs/doc-update-detection/users-guide/07-dashboards.html new file mode 100644 index 000000000..fd68404d1 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/07-dashboards.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/08-dashboard-filters.html b/_site/docs/doc-update-detection/users-guide/08-dashboard-filters.html new file mode 100644 index 000000000..28c4c90a0 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/08-dashboard-filters.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/09-multi-series-charting.html b/_site/docs/doc-update-detection/users-guide/09-multi-series-charting.html new file mode 100644 index 000000000..41fa72057 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/09-multi-series-charting.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/12-data-model-reference.html b/_site/docs/doc-update-detection/users-guide/12-data-model-reference.html new file mode 100644 index 000000000..bfdbd24fc --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/12-data-model-reference.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/13-sql-parameters.html b/_site/docs/doc-update-detection/users-guide/13-sql-parameters.html new file mode 100644 index 000000000..33dca35e4 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/13-sql-parameters.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/14-x-rays.html b/_site/docs/doc-update-detection/users-guide/14-x-rays.html new file mode 100644 index 000000000..5269f4540 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/14-x-rays.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/15-alerts.html b/_site/docs/doc-update-detection/users-guide/15-alerts.html new file mode 100644 index 000000000..b23407084 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/15-alerts.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/account-settings.html b/_site/docs/doc-update-detection/users-guide/account-settings.html new file mode 100644 index 000000000..066e6922b --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/account-settings.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/collections.html b/_site/docs/doc-update-detection/users-guide/collections.html new file mode 100644 index 000000000..ec02cb691 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/collections.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/dashboard-subscriptions.html b/_site/docs/doc-update-detection/users-guide/dashboard-subscriptions.html new file mode 100644 index 000000000..6e64cbb2c --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/dashboard-subscriptions.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/events-and-timelines.html b/_site/docs/doc-update-detection/users-guide/events-and-timelines.html new file mode 100644 index 000000000..fe897469a --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/events-and-timelines.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/expressions-list.html b/_site/docs/doc-update-detection/users-guide/expressions-list.html new file mode 100644 index 000000000..83fbf858b --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/expressions-list.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/expressions.html b/_site/docs/doc-update-detection/users-guide/expressions.html new file mode 100644 index 000000000..387cdeba0 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/expressions.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/field-types.html b/_site/docs/doc-update-detection/users-guide/field-types.html new file mode 100644 index 000000000..63563097d --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/field-types.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/interactive-dashboards.html b/_site/docs/doc-update-detection/users-guide/interactive-dashboards.html new file mode 100644 index 000000000..6b2b139e3 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/interactive-dashboards.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/join.html b/_site/docs/doc-update-detection/users-guide/join.html new file mode 100644 index 000000000..62ba0c81c --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/join.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/models.html b/_site/docs/doc-update-detection/users-guide/models.html new file mode 100644 index 000000000..2b90a8934 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/models.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/referencing-saved-questions-in-queries.html b/_site/docs/doc-update-detection/users-guide/referencing-saved-questions-in-queries.html new file mode 100644 index 000000000..c2da6c321 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/referencing-saved-questions-in-queries.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/doc-update-detection/users-guide/sql-snippets.html b/_site/docs/doc-update-detection/users-guide/sql-snippets.html new file mode 100644 index 000000000..0a5dff266 --- /dev/null +++ b/_site/docs/doc-update-detection/users-guide/sql-snippets.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/installation-and-operation/java-versions.html b/_site/docs/installation-and-operation/java-versions.html new file mode 100644 index 000000000..2c19233fd --- /dev/null +++ b/_site/docs/installation-and-operation/java-versions.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/landing-pages.md b/_site/docs/landing-pages.md new file mode 100644 index 000000000..aed5f486d --- /dev/null +++ b/_site/docs/landing-pages.md @@ -0,0 +1,535 @@ +# Creating Landing Pages + +## Basic checklist + +1. Add a file to directory `_lp`, like `_lp/some-name.html`. +2. Add a `data: some-name` metadata entry to the top of the file created in 1. +3. Add a file to `_data/landing-pages` like `_data/landing-pages/some-name.yml`. +4. Make sure you use the same name in all places marked `some-name` above. +5. Fill out the `yml` file using some of the components listed below, and their APIs. + +At the bottom of this document you can find a [simulated page](#simulated-page) with all the components filled out. + +## Components + +### Header + +![image](/images/docs/landing-pages/header.png) + +- `-component: header` +- `hide-menu`: true or empty + +
+ +### Hero A + +![image](/images/docs/landing-pages/hero-a.png) + +- `- component: hero-a` +- `headline`: the headline +- `subheading`: typically a phrase +- `links`: a list of + - `text`: the text in the link + - `href`: the URL in the link + - `extra-classes`: pass custom classes, for example `btn-outline-blue` to make it outlined +- `media`, with entries + - `type`: use `image`, `video`, or `youtube` + - `src`: if `type` is `image`, the path and filename. If type is `youtube`, the embed URL, looking like https://www.youtube.com/embed/5ZLtyTU2qIQ. + - `alt`: if `type` is `image`, an alt string + - `id`: if `type` is `video`, a string that is unique to the page + - `poster`: if `type` is `video`, the path and filename for the fallback image, which can be a gif + - `source_mp4`: if `type` is `video`, the path and filename for the mp4 video + - `source_webm`: if `type` is `video`, the path and filename for the webm video + +
+ +### Hero B + +![image](/images/docs/landing-pages/hero-b.png) + +- `- component: hero-b` +- `headline`: the headline +- `subheading`: optional, typically a phrase +- `badge-text`: typically a word or short phrase +- `links`: a list of + - `text`: the text in the link + - `href`: the URL in the link + - `extra-classes`: pass custom classes, for example `btn-outline-blue` to make it outlined +- `media`, with entries + - `type`: use `image` or `video` + - `src`: if `type` is `image`, the path and filename. If type is `youtube`, the embed URL, looking like https://www.youtube.com/embed/5ZLtyTU2qIQ. + - `alt`: if `type` is `image`, an alt string + - `id`: if `type` is `video`, a string that is unique to the page + - `poster`: if `type` is `video`, the path and filename for the fallback image, which can be a gif + - `source_mp4`: if `type` is `video`, the path and filename for the mp4 video + - `source_webm`: if `type` is `video`, the path and filename for the webm video + +
+ +### Hero C + +![image](/images/docs/landing-pages/hero-c.png) + +- `- component: hero-c` +- `headline`: the headline +- `subheading`: typically a phrase +- `badge-text`: typically a word or short phrase +- `links`: a list of + - `text`: the text in the link + - `href`: the URL in the link + - `extra-classes`: pass custom classes, for example `btn-outline-blue` to make it outlined +- `cards`: a list of + - `headline`: the headline + - `text`: typically a short paragraph + - `icon`: the prefix for an icon in the `svg-icons` directory + +
+ +### Hero with Embedded Iframe + +![image](/images/docs/landing-pages/hero-with-embedded-iframe.png) + +- `- component: hero-with-embedded-iframe` +- `headline`: the headline +- `subheading`: typically a phrase +- `embed`: a string of HTML, typically an iframe +- `media`, with entries + - `type`: use `image` or `video` + - `src`: if `type` is `image`, the path and filename. If type is `youtube`, the embed URL, looking like https://www.youtube.com/embed/5ZLtyTU2qIQ. + - `alt`: if `type` is `image`, an alt string + - `id`: if `type` is `video`, a string that is unique to the page + - `poster`: if `type` is `video`, the path and filename for the fallback image, which can be a gif + - `source_mp4`: if `type` is `video`, the path and filename for the mp4 video + - `source_webm`: if `type` is `video`, the path and filename for the webm video + +
+ +### Customer Logos + +![image](/images/docs/landing-pages/customer-logos.png) + +- `- component: customer-logos` + +
+ +### Feature Container + +![image](/images/docs/landing-pages/feature-container.png) + +- `component: feature-container` +- `headline`: the headline +- `subheading`: typically a phrase +- `list-items`: a list of strings or HTML +- `right-hand-list-items`: a list of strings or HTML. These will be displayed in the colored box to the right. +- `media`, with entries + - `type`: use `image` or `video` + - `src`: if `type` is `image`, the path and filename. If type is `youtube`, the embed URL, looking like https://www.youtube.com/embed/5ZLtyTU2qIQ. + - `alt`: if `type` is `image`, an alt string + - `id`: if `type` is `video`, a string that is unique to the page + - `poster`: if `type` is `video`, the path and filename for the fallback image, which can be a gif + - `source_mp4`: if `type` is `video`, the path and filename for the mp4 video + - `source_webm`: if `type` is `video`, the path and filename for the webm video + +
+ +### Feature Container Reverse + +![image](/images/docs/landing-pages/feature-container-reverse.png) + +- `component: feature-container-reverse` +- `headline`: the headline +- `subheading`: typically a phrase +- `list-items`: a list of strings or HTML +- `left-hand-list-items`: a list of strings or HTML. These will be displayed in the colored box to the right. +- `media`, with entries + - `type`: use `image` or `video` + - `src`: if `type` is `image`, the path and filename. If type is `youtube`, the embed URL, looking like https://www.youtube.com/embed/5ZLtyTU2qIQ. + - `alt`: if `type` is `image`, an alt string + - `id`: if `type` is `video`, a string that is unique to the page + - `poster`: if `type` is `video`, the path and filename for the fallback image, which can be a gif + - `source_mp4`: if `type` is `video`, the path and filename for the mp4 video + - `source_webm`: if `type` is `video`, the path and filename for the webm video + +
+ +### Two Checklists + +![image](/images/docs/landing-pages/two-checklists.png) + +- `component: two-checklists` +- `left-checklist`, with entries + - `headline`: the headline + - `subheading`: typically a phrase + - `list-items`: a list of strings or HTML + +- `right-checklist`, with entries + - `headline`: the headline + - `subheading`: typically a phrase + - `list-items`: a list of strings or HTML + +
+ +### Comparison Table + +![image](/images/docs/landing-pages/comparison-table.png) + +- `component: comparison-table` +- `headline`: the headline +- `subheading`: typically a phrase +- `option1`: header of the table, a word or two +- `option2`: header of the table, a word or two +- `rows`: a list of + - `text`: a short phrase + - `option1`: `check` for a tick, or empty, a string or HTML + - `option2`: `check` for a tick, or empty, a string or HTML +- `link` + - `text`: the text in the link + - `href`: the URL in the link + +
+ +### Testimonial + +![image](/images/docs/landing-pages/testimonial.png) + +- `component: testimonial` +- `testimony`: Typically a paragraph +- `image`, with entries + - `src`: the path and filename + - `alt`: an alt string +- `author`: Name of the person +- `role-and-company`: Role of the person in the company, Company + +
+ +### FAQ + +![image](/images/docs/shared/faq.png) + +- `component: faq` +- `items`: a list of + - `question`: Text or HTML + - `answer`: Please wrap each paragraph with a `

` tag. +- `contact-box`: + - `icon`: the prefix for an icon in the `svg-icons` directory + - `text`: a short phrase or two. + - `link`: + - `text`: the text in the link + - `href`: the URL in the link + +


+ +### Three Cards + +![image](/images/docs/landing-pages/three-cards.png) + +- `component: three-cards` +- `headline`: a short phrase or two +- `cards`: a list of three + - `icon`: the prefix for an icon in the `svg-icons` directory + - `headline`: a short phrase or two + - `text`: can be plain text or HTML + +
+ +### Three Cards with Variable Heights + +![image](/images/docs/landing-pages/three-cards.png) + +- `component: three-cards-variable-heights` +- `headline`: a short phrase or two +- `cards`: a list of three + - `image`, with entries + - `src`: the path and filename + - `alt`: an alt string + - `headline`: a short phrase or two + - `text`: can be plain text or HTML + +
+ +### Full Width Sky Blue + +![image](/images/docs/landing-pages/full-width-sky-blue.png) + +- `component: full-width-sky-blue` +- `headline`: the headline +- `subheading`: typically a phrase or two +- `image` + - `src`: the path and filename +- `links`: a list of + - `text`: the text in the button + - `href`: the link in the button + - `extra-classes`: pass custom classes, for example `full-width-sky-blue__cta--clear` to make it outlined + - `quote`: + - `avatar`: path and filename of the image + - `text`: typically a paragraph or two + - `author`: name of the person + - `role-and-company`: Role of the person in the company, Company + +
+ +### Feature and Rolling Testimonials + +![image](/images/docs/landing-pages/feature-and-rolling-testimonials.png) + +- `component: feature-and-rolling-testimonials` +- `headline`: the headline +- `subheading`: typically a phrase or two +- `text-before-list`: typically a phrase +- `list-items`: a list of strings, typically 1 or 2 phrases each + +
+ +### Feature and Rolling Databases + +![image](/images/docs/landing-pages/feature-and-rolling-databases.png) + +- `component: feature-and-rolling-databases` +- `headline`: the headline +- `subheading`: typically a phrase or two +- `list-items`: a list of strings, typically 1 or 2 phrases each + +
+ +### CTAS + +![image](/images/docs/landing-pages/ctas.png) + +- `component: ctas` +- `title`: A string or HTML +- `cta`: + - `text`: the text in the link + - `href`: the URL in the link +- `items`: + - `badge`: A word or two + - `text`: the text in the link + - `href`: the URL in the link + +
+ +### Event + +![image](/images/docs/landing-pages/event.png) + +- `component: event` +- `headline`: the headline +- `subheading`: typically a phrase or two +- `slug`: the slug from an event in `\_data/events.yml`. + +
+ +### Try Metabase Footer + +![image](/images/docs/shared/try-metabase-footer.png) + +- `component: try-metabase-footer` + +- `headline`: the headline + +- `subheading`: typically a phrase + +- `link` + - `text`: the text in the link + - `href`: the URL in the link + +
+ +### Footer + +![image](/images/docs/landing-pages/footer.png) + +- `component: footer` + +## Simulated Page + +The yml below has several components, each using all the attributes possible. + +You can use it as a starting point or reference for your page. + +```yml +- component: header + hide-menu: true + +- component: hero-a + headline: Don't be a bottleneck + subheading: Fast analytics with the friendly UX and integrated tooling to let your company explore data on their own. + links: + - text: Get started + href: https://store.metabase.com/checkout + extra-classes: btn-primary + - text: Watch demo + href: /demo + extra-classes: btn-outline-blue + media: + type: image + src: /images/landing-pages/hero-sample-image.png + alt: An alt for the image + +- component: hero-b + badge-text: CSV Upload + headline: Upload and analyze your spreadsheets in Metabase + subheading: Analyze CSV data with Metabase’s query builder. It’s simple enough for anyone on the team to use—no SQL or data expertise needed. + media: + type: video + id: csv-uploads + source_mp4: /images/product/csv-uploads/csv-uploads.mp4 + poster: /images/product/csv-uploads/csv-uploads.gif + links: + - text: Get started + href: https://store.metabase.com/checkout + extra-classes: btn-primary + - text: Watch demo + href: /demo + extra-classes: btn-outline-blue + +- component: hero-c + headline: Self-service analytics
on your terms + subheading: The simple but powerful Metabase you love, with tighter security and permissions, interactive embedding, and a reasonable price tag. + buttons: + - label: Get started + href: https://store.metabase.com/checkout + extra-classes: btn-primary + - label: Watch demo + href: /demo + extra-classes: btn-outline-blue + cards: + - icon: coin + headline: Get a custom quote + text: Based on your use case and requirements to keep up with you as you scale. + - icon: document + headline: No credit card required (to trial, or after) + text: We’ll work with your procurement team for invoicing and your preferred payment method. + - icon: modules + headline: Modular contracts + text: Get to proof of concept faster with professional services, and onboarding for your whole team. + +- component: customer-logos + +- component: feature-container + headline: Set Row-level permissions so people only see data they need to + subheading: Make privacy a priority with more control over what to show and what to hide in data sandboxes. + list-items: + - "Oversee what people can see and do with row-, and column-level permissions." + - "Manage group permissions manually or via SSO to filter their table views." + - "Block whole groups of people to keep data in selected databases off-limits." + media: + type: video + id: row-level-permissions + source_mp4: /images/product/pro/row-level-permissions.mp4" type="video/mp4 + poster: /images/product/pro/row-level-permissions.gif + +- component: feature-container-reverse + headline: Set Row-level permissions so people only see data they need to + subheading: Make privacy a priority with more control over what to show and what to hide in data sandboxes. + list-items: + - "Oversee what people can see and do with row-, and column-level permissions." + - "Manage group permissions manually or via SSO to filter their table views." + - "Block whole groups of people to keep data in selected databases off-limits." + media: + type: video + id: csv-uploads + source_mp4: /images/product/pro/row-level-permissions.mp4" type="video/mp4 + poster: /images/product/pro/row-level-permissions.gif + media: + type: video + id: row-level-permissions-2 + source_mp4: /images/product/pro/row-level-permissions.mp4" type="video/mp4 + poster: /images/product/pro/row-level-permissions.gif + +- component: testimonial + testimony: Advanced permissions and row filtering are essential features for us! They enable us to effortlessly create scalable dashboards that display only the information that a user is authorized to view. Metabase has become an essential tool in our workflow. + image: + src: /images/profiles/arthur-benhamou.png + alt: Photo of Arthur Benhamou + author: Arthur Benhamou + role-and-company: Chief Operations Officer, Comptoir de L’or + +- component: faq + items: + - question: Question 1 + answer:

Answer 1

+ - question: Question 2 + answer:

Answer 2

+ - question: Question 3 + answer:

Answer 3

+ - question: Question 4 + answer:

Answer 4

+ - question: Question 5 + answer:

Answer 5

+ contact-box: + icon: balloon-squarish + text: Have more questions? We’d be happy to help. + link: + text: Contact us + href: /talk-to-a-person/ + +- component: three-cards + headline: Premium service without breaking the bank + cards: + - icon: coin + headline: Get a custom quote + text: Based on your use case and requirements to keep up with you as you scale. + - icon: document + headline: No credit card required (to trial, or after) + text: We’ll work with your procurement team for invoicing and your preferred payment method. + - icon: modules + headline: Modular contracts + text: Get to proof of concept faster with professional services, and onboarding for your whole team. + +- component: full-width-sky-blue + headline: Ready to get started? + subheading: Get up and running with a 14-day free trial in 5 minutes. Or get in touch with our sales team to talk to an expert. + image: + src: "/images/landing-pages/full-width-sky-blue-sample-image.png" + links: + - text: Get started + href: https://store.metabase.com/checkout + - text: Watch demo + href: /demo + extra-classes: full-width-sky-blue__cta--clear + quote: + avatar: /images/profiles/sincera_ian-meyers.png + text: "Metabase was the embedded solution we were looking for: easy-to-integrate, customizable and performant." + author: Ian Meyers + role-and-company: Co-Founder at Sincera + +- component: comparison-table + headline: Wait, isn’t there a free version of Metabase? + subheading: Sometimes the best things in life are free, like unconditional love, and awesome open source software. And sometimes it’s worth paying a little extra for convenience and accessible technical support. + option1: Competitor + option2: Metabase + rows: + - text: Unlimited questions + option1: check + option2: check + - text: Unlimited charts + option1: check + option2: check + - text: 15+ visualization types + option1: check + option2: check + - text: Scheduled updates and alerts via email and Slack + option1: check + option2: check + - text: Connects to 20+ database types, including CSV upload + option1: check + option2: check + - text: SOC2 Type II Compliance + option1: check + option2: check + - text: Unlimited technical support + option1: check + option2: check + link: + text: See all features + href: /pricing/#compare + +- component: try-metabase-footer + headline: Try Metabase Starter 14 days free + subheading: Pay as you go, or get 10% off with an annual subscription. + link: + href: https://store.metabase.com/checkout + text: Get started + +- component: footer +``` diff --git a/_site/docs/latest/faq/general/does-metabase-have-access-to-my-companys-data.html b/_site/docs/latest/faq/general/does-metabase-have-access-to-my-companys-data.html new file mode 100644 index 000000000..3ca6c4434 --- /dev/null +++ b/_site/docs/latest/faq/general/does-metabase-have-access-to-my-companys-data.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/latest/faq/setup/which-databases-does-metabase-support.html b/_site/docs/latest/faq/setup/which-databases-does-metabase-support.html new file mode 100644 index 000000000..e7ab1893d --- /dev/null +++ b/_site/docs/latest/faq/setup/which-databases-does-metabase-support.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/latest/faq/start.html b/_site/docs/latest/faq/start.html new file mode 100644 index 000000000..0e1abcfa7 --- /dev/null +++ b/_site/docs/latest/faq/start.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/latest/faq/using-metabase/how-do-i-reset-my-password.html b/_site/docs/latest/faq/using-metabase/how-do-i-reset-my-password.html new file mode 100644 index 000000000..cc10b1900 --- /dev/null +++ b/_site/docs/latest/faq/using-metabase/how-do-i-reset-my-password.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/latest/paid-features/index.html b/_site/docs/latest/paid-features/index.html new file mode 100644 index 000000000..865e6b1d1 --- /dev/null +++ b/_site/docs/latest/paid-features/index.html @@ -0,0 +1,6109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Paid features | Metabase Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + +
+
+ + + +
+
+
+ +
+ + + + + + + + + +
+ + + +
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + +
+ + + + + + + What’s new + + + +
+ + + +
+
+ + +
+ + +
+ +
+ + +

Paid features

+ +

This page lists the paid features included with the Enterprise Edition of Metabase used in both the Pro and Enterprise plans. See Pricing.

+ +

Query data

+ +

A straight-forward way for everyone to ask questions and get answers from your data on their own.

+ +

Granular result and duration caching

+ +

Get super specific about which databases, dashboards, and questions to cache, and for how long. Learn more.

+ +

Data visualization and sharing

+ +

Dashboards and charts that people will actually use.

+ +

Scheduled delivery and alerts via email

+ +

Send scheduled updates to yourself, your team, or even people outside of your org. Get alerts when things change you and need to take action. Learn more.

+ +

Scheduled delivery with custom filters

+ +

Set different filters for each subscription when sending results. Learn more.

+ +

Customize suggested recipients

+ +

Control which recipients people can see when they create a new dashboard subscription or alert. Learn more.

+ +

Organization

+ +

Analytics with a bit of order, so it’s easy to find and return to important stuff.

+ +

Official collections

+ +

Admins can mark collections as fresh and trustworthy. Learn more.

+ +

Moderated questions

+ +

Show which questions have been vetted by someone in the know. Learn more.

+ +

Verified models

+ +

Make sure your team is using an accurate data source with models marked as verified. Learn more.

+ +

Permissions

+ +

Fine-grained control over who sees what.

+ +

SSO permission mapping

+ +

Manage permissions at scale easier by mapping to user attributes with SSO. Learn more.

+ +

Row- and column-level permissions (data sandboxes)

+ +

Granular control over permissions, especially important for multi-tenant analytics. Learn more.

+ +

Database-managed row-level permissions

+ +

Apply the permissions you’ve set up for people in your database in Metabase. Learn more.

+ +

Snippet controls

+ +

Save and organize your Snippets with controlled permissions. Learn more.

+ +

Download results

+ +

Determine which groups can download results, and how many rows. Learn more.

+ +

Group managers

+ +

Group managers can manage other people within their group. Learn more.

+ +

Table metadata permissions

+ +

Control who can see and edit table metadata. Learn more.

+ +

Database management permissions

+ +

Control who can see and edit database connections. Learn more.

+ +

Security and Single sign-on

+ +

Secure your perimeter and stay compliant with all the best practices.

+ +

LDAP

+ +

Authenticate your users with LDAP and automatically map permissions. Learn more.

+ +

LDAP group membership filter

+ +

Sync only the groups you want. Learn more.

+ +

Syncing user attributes with LDAP

+ +

Manage user attributes such as names, emails, and roles from your LDAP directory. Learn more.

+ +

SAML

+ +

Authenticate your users and maps permissions with Okta, Auth0, Google, Keycloak, and more. Learn more.

+ +

JWT

+ +

Authenticate your users and map permissions with JSON web token. Learn more.

+ +

SLO

+ +

End auth sessions with multiple apps with a single logout. Learn more.

+ +

SCIM account provisioning

+ +

Decouple authentication from provisioning, with support for deprovisioning user accounts. Learn more.

+ +

Authenticating with a provider for PostgreSQL

+ +

Authenticate with a provider for PostgreSQL. Learn more.

+ +

Disabling password login

+ +

Enforce logging in via Single Sign-on. Learn more.

+ +

Session timeout

+ +

Set time limit for when people are logged out of Metabase. Learn more.

+ +

Approved domains

+ +

Limit the available domains for dashboard subscription and alert emails. Learn more.

+ +

Multiple domains for Google Sign-in

+ +

Allow people to sign in with multiple domains in your Google Workspace. Learn more.

+ +

Meta analytics

+ +

See who did what, when to ensure your data’s being put to good use, and to meet compliance needs.

+ +

Usage analytics

+ +

See which dashboards and questions are being viewed, downloaded and subscribed to most. Learn more.

+ +

Question error logs

+ +

See which queries returned errors when last run. Learn more.

+ +

Embedded analytics

+ +

Let your customers see and play with their data with as much (or as little) flexibility as you want.

+ +

Static embedding

+ +

Basic embedding of dashboards and charts. Learn more.

+ +

Interactive embedding

+ +

The full power of Metabase in your app, with interactive features like the drill-through menu to explore, and your branding. (The most awesome version of embedding). Learn more.

+ +

Embedded query builder

+ +

Let your customers ask their own questions for fully customized access to their data. Learn more.

+ +

Multi-tenant analytics

+ +

Fine-grained permissions mapped with SSO so your customers or users only see what they need to. Learn more.

+ +

White-label with your branding

+ +

Metabase made to look like you, with your logo, colors, even name and domain name. Learn more.

+ +

Custom colors, fonts, and UI elements

+ +

Full control over your Metabase’s look, down to the copy. Choose from our library or upload your own fonts and colors. Learn more.

+ +

Multi-language embeds

+ +

Set locale for interactive embeds. Learn more.

+ +

Embedded analytics SDK for React

+ +

React toolkit for fully integrated, custom in-app analytics Learn more.

+ +

Disabling downloads for static embeds

+ +

Control whether people can download results from static embeds. Learn more.

+ +

Data sources

+ +

Put a simple, intuitive interface between your data and your business-users for easier analytics.

+ +

Deleting models and tables created by uploads

+ +

Remove models and tables created by people uploading CSVs. Learn more.

+ +

Deployment

+ +

Self-host your own instance or let us do it for you.

+ +

Fully air-gapped deployment

+ +

Run Metabase on-prem in ultra-secure and private environments Learn more.

+ +

Serialization

+ +

Export and import everything about an instance to create backups, or parallel instances for testing, staging and production environments. Learn more.

+ +

Loading settings from a configuration file

+ +

Initialize Metabase on launch from a config file Learn more.

+ + + +
+
+ +

+ Read docs for other versions of Metabase. +

+ +
+
+ +
+ + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_site/docs/latest/paid-features/start.html b/_site/docs/latest/paid-features/start.html new file mode 100644 index 000000000..8c9a20ffe --- /dev/null +++ b/_site/docs/latest/paid-features/start.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/latest/permissions/no-self-service-deprecated.html b/_site/docs/latest/permissions/no-self-service-deprecated.html new file mode 100644 index 000000000..f1aec39c0 --- /dev/null +++ b/_site/docs/latest/permissions/no-self-service-deprecated.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/latest/releases.html b/_site/docs/latest/releases.html new file mode 100644 index 000000000..a6502bf46 --- /dev/null +++ b/_site/docs/latest/releases.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/latest/users-guide/custom-questions.html b/_site/docs/latest/users-guide/custom-questions.html new file mode 100644 index 000000000..f620e7273 --- /dev/null +++ b/_site/docs/latest/users-guide/custom-questions.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/_site/docs/promo-banners.md b/_site/docs/promo-banners.md new file mode 100644 index 000000000..0da3dee08 --- /dev/null +++ b/_site/docs/promo-banners.md @@ -0,0 +1,19 @@ +# In-Page Promo Banners + +In-page promo banners are used to promote a specific product or service on a page. + +## Creating a New Banner + +Duplicate `_includes/shared/in-page-promo.html` and update the content as needed. + +For now, the image must be square — typically an event category thumbnail. + +## Placing your New Banner + +To place your new banner on a page, add the following code to the page's markdown file: + +```liquid +{% include shared/your-in-page-promo-name.html %} +``` + +Be sure to replace `your-in-page-promo-name` with the name of your new banner file. diff --git a/_site/docs/real-life-examples.md b/_site/docs/real-life-examples.md new file mode 100644 index 000000000..5cf84ed61 --- /dev/null +++ b/_site/docs/real-life-examples.md @@ -0,0 +1,121 @@ +# Creating Example of Metabase in Real Life + +## Basic checklist + +1. Add a file to directory `_examples`, like `_examples/YYYY-MM-DDsome-name.html`. Please note that pages are ordered from most recent to least recent, according to the prepend date in the filename prefix. + +Be sure to add a `permalink` to the frontmatter of the file, like `/examples/some-name/`. Typically, the permalink is the same as the filename, but without the date prefix. + +At the bottom of this document you can find a [simulated page](#simulated-page) with components filled in. + +### Intro Component + + + +This is the left-hand block on an example page. + +Place its contents as frontmatter in `_examples/some-name.html`. + +- `title`: Druid +- `summary`: a short phrase, no period at the end +- `dashboard_url`: the URL of the dashboard +- `thumbnail`: /images/examples/your-name.png, should be 1164 × 720px including a blue background and a box-shadow under the screenshot +- `categories`: please use the same name as listed in`\_data/public-metabase-example-categories.yml` + +### Other Components + +Add the components as frontmatter under the key `components` in your html file. + +### Title Component + +- `component`: title +- `text`: the text + +
+ +### Paragraph + +- `component`: paragraph +- `text`: the text + +
+ +### Numbered List + + + +- `component`: numbered-list +- `headline`: the headline +- `list-items`: a list of + - `title`: the title + - `text`: the text + +
+ +### Testimonial + + + +- `component`: testimonial +- `text`: the text +- `author`: + - `name`: author's name + - `company`: author's company and position, comma-separated + - `image`: the url + +
+ +### Simulated Page + +The yml below has several components. + +You can use it as a starting point or reference for your page. + +```html +- component: title + text: Developed vs. Developing World Finance + +- component: paragraph + text: Tracks donations, grants, and expenses, offering a clear view of funds raised versus goals. It shows funding by source and allocation across projects, helping NGOs monitor financial health and plan future fundraising. + +- component: carousel + items: + - type: youtube + id: OK-eq5obu3o + - type: image + src: /images/stats-dashboard.svg + alt: Metabase MongoDB analytics + - type: youtube + id: LgPiQdkV4g8 + - type: image + src: https://placehold.co/1600x900 + alt: Metabase MongoDB analytics + - type: image + src: /images/stats-dashboard.svg + alt: Metabase MongoDB analytics + +- component: paragraph + text: The INDIGO project at Oxford University, which kindly consented to the reproduction of their dataset, has been mapping the development and growth of outcomes funds — and government outcomes commissioning generally — since 2010. + +- component: paragraph + text: Their dataset includes both a snapshot of deployed outcomes as well as a pipeline dataset which provides interesting clues into the outcomes-based financing programmes being developed around the world. + +- component: testimonial + headline: A word from Metabase team + text: Their dataset includes both a snapshot of deployed outcomes as well as a pipeline dataset which provides interesting clues into the outcomes-based financing programmes being developed around the world. + author: + image: /images/events/guests/margaret-rimek.jpeg + name: Margaret Rimek + company: Growth & Partnerships, Metabase + +- component: numbered-list + headline: How to use Metabase to build a dashboard like this + items: + - title: Skip the custom quote + text: That's right, no sales calls necessary—just sign up, and get running in under 5 minutes. + - title: Plugin your database + text: We connect to the most popular production databases and data warehouses. + - title: Build your dashboards + text: Invite your team and start building dashboards—no SQL required. + +``` diff --git a/_site/docs/roadmap.md b/_site/docs/roadmap.md new file mode 100644 index 000000000..49b7cc3d0 --- /dev/null +++ b/_site/docs/roadmap.md @@ -0,0 +1,30 @@ +# Managing the Roadmap Page (/roadmap) + +Data for the page lives in \_data/roadmap.yml. + +Place a given entry under one of the time slots below: + +* now +* soon +* later +* shipped + +## An entry + +A given entry will have the following structure: + +* `- paid`: true or false. Default: false +* `title`: a short phrase, no period at the end +* `description`: a short paragraph +* `class`: one-by-one, one-by-two (if so, can also have right-side as a class, see below). Default: two-by-one. +* `image`, with entries + * `src`: path and filename + * `alt`: short piece of text + +### On classes and tiling + +We can tile the entries using a few variations. + +The logic of the class names is: horizontal-by-vertical. Therefore one-by-two is one column and two rows. + +If a one-by-two tile will live on the right column, you must add `right-side` as a class, so it will look like `one-by-two right-side`. diff --git a/_site/docs/w9.html b/_site/docs/w9.html new file mode 100644 index 000000000..754f741d4 --- /dev/null +++ b/_site/docs/w9.html @@ -0,0 +1,11 @@ + + + + Redirecting… + + + + +

Redirecting…

+ Click here if you are not redirected. + diff --git a/script/check_incoming_branchname.clj b/script/check_incoming_branchname.clj new file mode 100644 index 000000000..2e22ab073 --- /dev/null +++ b/script/check_incoming_branchname.clj @@ -0,0 +1,34 @@ +(ns check-incoming-branchname) + +(defn usage [] + (println "Usage: script/check_incoming_branchname.clj branchname") + (System/exit 1)) + +(def release-regex #"release-x\.(\d+)\.x") + +(defn extract-release-num [release-branchname] + (let [[_ num] (re-matches release-regex release-branchname)] + num)) + +(defn categorize-branchname [branchname] + (cond + (= branchname "master") [:master] + (re-matches release-regex branchname) [:release (extract-release-num branchname)])) + +(defn -main + "This is called from the `process_docs_changes.yml` workflow. It checks that + the branchname is either `master` or a release branch. If not, it exits with + an error code, stopping the workflow before it goes ahead and opens a PR with + the docs changes." + [& args] + (let [branchname (or (first args) (usage)) + _ (println "Checking branchname:" branchname) + [category release-num] (categorize-branchname branchname)] + (case category + :master (println "Master branch detected.") + :release (println "Release branch detected:" release-num) + (do (println "Unpublishable branchname: " branchname) + (System/exit 1))))) + +(when (= *file* (System/getProperty "babashka.file")) + (apply -main *command-line-args*)) diff --git a/script/update_or_create_pr.clj b/script/update_or_create_pr.clj new file mode 100644 index 000000000..5827b0fb3 --- /dev/null +++ b/script/update_or_create_pr.clj @@ -0,0 +1,76 @@ +#!/usr/bin/env bb +(ns update-or-create-pr + (:require [babashka.process :as p] + [cheshire.core :as json] + [clojure.string :as str])) + +(defn usage [] + (println "Usage: script/update_or_create_pr.clj branchname") + (System/exit 1)) + +(def artifact-dirs ["_docs" "_site/docs"]) ;; Directories to copy + + + +(defn existing-pr? [target-branch] + (let [pr-data (-> + (p/shell {:out :string :continue true} + "curl" + (str "https://api.github.com/repos/metabase/docs.metabase.github.io/pulls?head=metabase:" "update-" "doc-update-detection")) + :out + json/parse-string) + _ (println "→ PR data: " (pr-str pr-data)) + pr-num (some #(when (= target-branch (get % "title")) + (get % "number")) + pr-data)] + (println "→ PR number:" pr-num) + (boolean pr-num))) + +(defn -main [& args] + (let [source-branch (or (first args) (usage)) + target-branch (str "update-" source-branch) + _ (println "Swithcing to target branch.") + _ (p/shell "git" "checkout" "-B" target-branch) + _ (doseq [ad artifact-dirs] + (println "Adding" ad "...") + (p/shell "git" "add" ad)) + {:keys [exit]} (p/shell {:continue true} "git" "diff" "--cached" "--quiet")] + + (if (zero? exit) + (println "→ No changes to commit.") + (do + (println "→ Changes detected, committing...") + (p/shell "git" "commit" "-m" (str "[auto] adding content to " target-branch)) + (p/shell "git" "push" "--force" "origin" target-branch) + (println "→ Branch updated successfully."))) + + (println "→ Checking for existing PR...") + + (if (existing-pr? target-branch) + (println "✓ PR already exists: #" existing-pr?) + (do + (println "→ Creating new PR...") + (p/shell "gh" "pr" "create" + "--repo" "metabase/docs.metabase.github.io" + "--title" target-branch + "--body" (str "updated: " (pr-str artifact-dirs)) + "--head" target-branch))))) + +(when (= *file* (System/getProperty "babashka.file")) + (apply -main *command-line-args*)) + +(defmacro the-env [] + (into {} (for [k (keys &env)] + [(name k) k]))) + +(defmacro nocommit-repl [] + `(clojure.main/repl + :init (fn [] + (remove-ns '~'temp) + (create-ns '~'temp) + (doseq [[binding# value#] (the-env)] + (intern '~'temp (symbol binding#) value#))) + :prompt (fn [] (printf "paused.%s=> " (peek (clojure.string/split (str *ns*) #"\.")))) + :eval (fn [f#] (binding [clojure.test/*test-out* *out*] (eval f#))) + :read clojure.core.server/repl-read + :print clojure.pprint/pprint))