序列化:在新 Metabase 实例中预加载仪表盘

如何使用 Metabase 的序列化功能将问题、仪表板、集合、设置等从一个 Metabase 实例复制到新的 Metabase 实例。

Metabase 序列化

序列化仅适用于 ProEnterprise 计划(包括自托管和 Metabase 云服务)。

许多使用 专业版和企业版计划 的客户在多租户环境中使用 Metabase,这需要上传一组预定义的问题 (questions) 或仪表板 (dashboards),无论是为了设置新的 Metabase 实例,还是新的数据库连接。

本文将介绍如何

  1. 创建一组默认的问题和仪表板。
  2. 导出这些仪表板。
  3. 将这些仪表板重新导入到新实例中。

具体来说,我们将使用 Metabase 序列化功能 中的 exportimport 命令来执行第二和第三步,并对导出的文件进行少量手动整理。

我们将使用 Docker 运行我们的源 Metabase 和目标 Metabase,并使用 PostgresSQL 作为它们的 应用程序数据库。我们不建议在生产环境中使用默认的 H2 数据库。

虽然本教程使用 Metabase exportimport 命令,但您也可以通过 API 序列化 Metabase 应用程序数据

计划

我们将创建一个源 Metabase,创建一个仪表板,导出该仪表板,然后将该仪表板导入到一个新的 Metabase(我们的目标)。以下是计划:

  1. 创建一个名为 metanet 的专用网络.
  2. 启动两个 Metabase:源和目标.
  3. 在源 Metabase 中创建仪表板和集合
  4. 从源 Metabase 导出数据.
  5. 将源导出导入到目标 Metabase.
  6. 验证我们的仪表板和集合已加载到目标 Metabase 中.

先决条件

您需要在机器上安装 Docker

步骤 1 - 创建专用网络

要创建名为“metanet”的专用网络,请从您选择的终端运行以下命令:

docker network create metanet

您可以使用以下命令确认网络已创建:

docker network ls

该网络将具有本地范围和桥接驱动程序。

步骤 2 - 启动两个 Metabase:源和目标

启动两个 Metabase,分别命名为 metabase-sourcemetabase-target(尽管您可以随意命名这些环境)。请注意,我们在创建这些 Docker 容器时使用 --rm -d,以便它们在停止时都被删除并在后台运行。您可以随意更改这些标志以修改其行为。

源 Metabase

创建 Postgres 数据库

docker run --rm -d --name postgres \
    -p 5433:5432 \
    -e POSTGRES_USER=metabase \
    -e POSTGRES_PASSWORD=knockknock \
    --network metanet \
    postgres:12

创建我们的源 Metabase,并将其连接到我们刚刚创建的 Postgres 数据库。

docker run --rm -d --name metabase-source \
    -p 5001:3000 \
    -e MB_DB_TYPE=postgres \
    -e MB_DB_DBNAME=metabase \
    -e MB_DB_PORT=5432 \
    -e MB_DB_USER=metabase \
    -e MB_DB_PASS=knockknock \
    -e MB_DB_HOST=postgres \
    --network metanet \
    metabase/metabase-enterprise:v1.56.2

您可以查看容器的日志以查看容器的进度

docker logs metabase-source

一旦看到包含“Metabase initialization COMPLETE”的行,您就可以在浏览器中打开 https://:5001 来查看您的 Metabase 实例。

目标 Metabase

设置目标 Metabase 类似。在我们的 metanet 网络上,我们将设置一个 Postgres 数据库作为我们的应用程序数据库,然后在另一个 Docker 容器中启动另一个 Metabase。

请注意以下更改:

  • Postgres (5434) 和 Metabase 服务器 (5002) 的端口
  • 实例名称:postgres-targetmetabase-target

应用程序数据库

docker run --rm -d --name postgres-target \
    -p 5434:5432 \
    -e POSTGRES_USER=metabase \
    -e POSTGRES_PASSWORD=knockknock \
    --network metanet postgres:12

Metabase 实例

docker run --rm -d --name metabase-target \
    -p 5002:3000 \
    -e MB_DB_TYPE=postgres \
    -e MB_DB_DBNAME=metabase \
    -e MB_DB_PORT=5432 \
    -e MB_DB_USER=metabase \
    -e MB_DB_PASS=knockknock \
    -e MB_DB_HOST=postgres-target \
    --network metanet \
    metabase/metabase-enterprise:v1.56.2

在我们的 Metabase 实例完成初始化后(请耐心,这可能需要一两分钟),我们现在应该有两个 Metabase 正在运行:

  • metabase-source 在 https://:5001
  • metabase-target 在 https://:5002

向我们的源 Metabase 添加用户

让我们向我们的 metabase-source 实例添加一个管理员帐户和两个基本用户。

您可以手动将用户添加到 Metabase(即在 Metabase 应用程序中),但这里有一个快速的 bash 脚本,可以创建一个管理员用户(初始用户)和两个基本用户:

您需要安装 jq 来处理此脚本中的 JSON。

#!/bin/sh

ADMIN_EMAIL=${MB_ADMIN_EMAIL:-admin@metabase.local}
ADMIN_PASSWORD=${MB_ADMIN_PASSWORD:-Metapass123}

METABASE_HOST=${MB_HOSTNAME}
METABASE_PORT=${MB_PORT:-3000}

echo "⌚︎ Waiting for Metabase to start"
while (! curl -s -m 5 http://${METABASE_HOST}:${METABASE_PORT}/api/session/properties -o /dev/null); do sleep 5; done

echo "😎 Creating admin user"

SETUP_TOKEN=$(curl -s -m 5 -X GET \
    -H "Content-Type: application/json" \
    http://${METABASE_HOST}:${METABASE_PORT}/api/session/properties \
    | jq -r '.["setup-token"]'
)

MB_TOKEN=$(curl -s -X POST \
    -H "Content-type: application/json" \
    http://${METABASE_HOST}:${METABASE_PORT}/api/setup \
    -d '{
    "token": "'${SETUP_TOKEN}'",
    "user": {
        "email": "'${ADMIN_EMAIL}'",
        "first_name": "Metabase",
        "last_name": "Admin",
        "password": "'${ADMIN_PASSWORD}'"
    },
    "prefs": {
        "allow_tracking": false,
        "site_name": "Metawhat"
    }
}' | jq -r '.id')


echo -e "\n👥 Creating some basic users: "
curl -s "http://${METABASE_HOST}:${METABASE_PORT}/api/user" \
    -H 'Content-Type: application/json' \
    -H "X-Metabase-Session: ${MB_TOKEN}" \
    -d '{"first_name":"Basic","last_name":"User","email":"basic@somewhere.com","login_attributes":{"region_filter":"WA"},"password":"'${ADMIN_PASSWORD}'"}'

curl -s "http://${METABASE_HOST}:${METABASE_PORT}/api/user" \
    -H 'Content-Type: application/json' \
    -H "X-Metabase-Session: ${MB_TOKEN}" \
    -d '{"first_name":"Basic 2","last_name":"User","email":"basic2@somewhere.com","login_attributes":{"region_filter":"CA"},"password":"'${ADMIN_PASSWORD}'"}'

echo -e "\n👥 Basic users created!"

将上述代码保存为 create_users.sh,并使其可执行:

chmod +x create_users.sh

然后运行

MB_HOSTNAME=localhost MB_PORT=5001 ./create_users.sh

在您的 metabase-source 实例启动并创建用户后,打开 https://:5001 并使用您创建的管理员用户登录。用户 ID 为 admin@metabase.local,密码为 Metapass123

您应该会看到一个全新的 Metabase 实例。

A fresh instance of Metabase.

登录后,激活您的许可证密钥

步骤 3 - 在源 Metabase 中创建仪表板和集合

我们需要一些应用程序数据来导出,所以让我们使用 Metabase 附带的示例数据库创建一些仪表板。或者更确切地说,让我们让 Metabase 为我们创建一些仪表板!

根据您的数据尝试这些 X 射线 部分,点击带有黄色闪电符号的卡片,上面写着类似 查看产品 的内容。Metabase 将为您生成一组问题,您可以将其保存为仪表板。

An X-ray of the Products table in the Sample Database included with Metabase.

点击保存此项按钮,Metabase 会将仪表板及其问题保存到一个名为 查看产品集合中。

这个集合将保存到名为 自动生成的仪表板 的父集合中。您可以通过点击导航栏左上角的 Metabase 徽标返回主屏幕来找到这个集合。从主页的我们的分析部分,点击 自动生成的仪表板 部分。在那里您应该会看到集合 查看您的产品表

A collection titled A look at your Products table.

接下来,创建一个新集合。您可以随意命名;我们将使用令人兴奋的名称 默认集合,并将其保存到我们的分析集合中。

Creating a new collection, titled Default Collection.

然后,我们将把 查看产品 集合移动到我们新创建的 默认集合 中。在 查看产品 集合页面上,点击省略号 并选择移动

步骤 4 - 从源 Metabase 导出

现在我们开始使用 Metabase 的序列化功能。

我们的 metabase-source 实例已经设置了一些问题,现在是时候导出这些数据并将其导入到我们的 metabase-target 中了。这样我们就无需在目标 Metabase 中手动重新创建我们的默认集合。

我们首先在 /tmp 目录中创建一个名为 metabase_data 的目录来存储我们的导出数据。

cd /tmp
mkdir metabase_data

接下来,我们将运行导出命令。

docker run --rm --name metabase-export \
    --network metanet \
    -e MB_DB_CONNECTION_URI="postgres://postgres:5432/metabase?user=metabase&password=knockknock" \
    -v "/tmp/metabase_data:/target" \
    metabase/metabase-enterprise:v1.56.2 "export /target"

此命令创建一个名为 metabase-export 的临时 Metabase 实例。这个临时 Metabase 将连接到我们源 Metabase 的 Postgres 应用程序数据库,并导出其应用程序数据。

如果一切顺利,几秒钟后您应该会看到一些输出,然后终端中会出现一条消息,显示 serialization.cmd :: Export to '/target' complete! 🚛💨 📦

要验证导出,请 cd 到您的目录:/tmp/metabase_data。您应该会看到类似两个目录和三个 YAML 文件的内容:

设置

settings 文件包含许多您在设置新实例时可以配置的选项。它看起来会像:

aggregated-query-row-limit: null
application-colors: null
application-favicon-url: null
application-font: null
application-font-files: null
application-logo-url: null
application-name: null
available-fonts: null
available-locales: null
available-timezones: null
breakout-bins-num: null
custom-formatting: null
custom-geojson: null
custom-geojson-enabled: null
default-maps-enabled: null
enable-embedding: null
enable-nested-queries: null
enable-sandboxes?: null
enable-whitelabeling?: null
enable-xrays: null
hide-embed-branding?: null
humanization-strategy: null
landing-page: null
loading-message: null
native-query-autocomplete-match-style: null
persisted-models-enabled: null
report-timezone: null
report-timezone-long: null
report-timezone-short: null
search-typeahead-enabled: null
show-homepage-data: null
show-homepage-pin-message: null
show-homepage-xrays: null
show-lighthouse-illustration: null
show-metabot: null
show-static-embed-terms: null
site-locale: null
site-name: Metawhat
source-address-header: null
start-of-week: null
subscription-allowed-domains: null
unaggregated-query-row-limit: null
uploads-database-id: null
uploads-enabled: null
uploads-schema-name: null

数据库

此目录包含您所有已连接数据库的元数据设置。在本例中,我们只包含 Metabase 附带的示例数据库。

集合

在 collections 目录中是所有我们已设置的集合、仪表板和问题。eDuYBjvKEwhFg6QxtBziP_default_collection 目录包含子集合和其他项。每个项都以代码作为前缀,以避免命名冲突。

以下是集合 YAML 文件的示例:

name: Default collection
description: null
entity_id: qmJu_4D1gviNjHUCcn978
slug: default_collection
created_at: "2024-03-12T15:01:45.955848Z"
archived: false
type: null
parent_id: null
personal_owner_id: null
namespace: null
authority_level: null
serdes/meta:
  - id: qmJu_4D1gviNjHUCcn978
    label: default_collection
    model: Collection

以下是名为 每类别产品 的问题(称为卡片)示例:

ame: Products per Category
description: null
entity_id: bnghENFKtgeKRMfU3sF7y
created_at: "2024-03-12T14:59:01.795343Z"
creator_id: admin@metabase.local
display: row
archived: false
collection_id: JI0l2T_O-_EhdAxk2pdin
collection_preview: true
collection_position: null
query_type: query
dataset: false
cache_ttl: null
database_id: Sample Database
table_id:
  - Sample Database
  - PUBLIC
  - PRODUCTS
enable_embedding: false
embedding_params: null
made_public_by_id: null
public_uuid: null
parameters: []
parameter_mappings: []
dataset_query:
  database: Sample Database
  query:
    aggregation:
      - - count
    breakout:
      - - field
        - - Sample Database
          - PUBLIC
          - PRODUCTS
          - CATEGORY
        - null
    source-table:
      - Sample Database
      - PUBLIC
      - PRODUCTS
  type: query
result_metadata: null
visualization_settings:
  column_settings: null
  graph.colors:
    - "#EF8C8C"
  graph.dimensions:
    - CATEGORY
  graph.metrics:
    - count
  graph.series_labels:
    - null
serdes/meta:
  - id: bnghENFKtgeKRMfU3sF7y
    label: products_per_category
    model: Card
initially_published_at: null
metabase_version: v1.49.0
type: question

步骤 5 - 导入到目标 Metabase

您需要至少一个管理员帐户加载到目标 Metabase 中才能上传导出数据。您可以通过应用程序登录创建该用户,或者使用我们上面使用的脚本:只需记住将 MB_PORT 更改为 5002,因为这是我们分配给目标 Metabase 的端口。例如,cd 到您保存 create_users.sh 脚本的目录,然后运行:

MB_HOSTNAME=localhost MB_PORT=5002 ./create_users.sh

我们可以将所有这些设置上传到目标 Metabase,但是让我们假设我们只希望导入我们的默认集合。

我们来复制 /tmp/metabase_data 目录,这样我们就可以保留原始内容并对副本进行更改。

cp -r /tmp/metabase_data /tmp/serialize_import

由于每个 Metabase 实例都包含示例数据库,并且我们没有对元数据进行任何更改,因此让我们删除 databases 目录。运行

rm -r /tmp/serialize_import/databases

要验证更改,您可以运行 diff 命令来查看原始 serialized_data 目录与您将导入到目标 Metabase 的 serialized_load 目录之间的差异

cd /tmp
diff -r metabase_data serialize_import

您应该会看到以下内容:

Only in metabase_data: databases

在将数据导入到目标 Metabase 之前,您需要激活您的许可证

现在,设置好 /tmp/serialize_import 目录后,我们可以运行 import 命令将元数据导入到我们的目标 Metabase 中。

docker run --rm --name metabase-export \
    --network metanet \
    -e MB_DB_CONNECTION_URI="postgres://postgres-target:5432/metabase?user=metabase&password=knockknock" \
    -v "/tmp/serialize_import:/target" \
    metabase/metabase-enterprise:v1.56.2 "import /target"

步骤 6 - 验证目标 Metabase 中的仪表板和集合

现在,如果您登录到 https://:5002 上的目标 Metabase,您应该会看到我们的 默认集合 已经就绪,其中包含我们的 查看您的产品表 集合。

就是这样:您已经用一个包含仪表板和问题的集合预加载了一个全新的 Metabase 实例!

序列化限制

请注意,序列化转储不包含某些数据

  • 权限设置
  • 用户帐户或设置
  • 已保存问题上的警报
  • 个人收藏或其内容

通过 API 序列化

您也可以通过 API 导入和导出 Metabase 应用程序数据。请参阅 通过 API 序列化 Metabase。通过 API 导出和导入对于 Metabase Cloud 上的实例(您无法访问环境)非常有用。

序列化的其他用例

使用序列化功能导出问题和仪表板带来了许多酷炫的可能性,包括:

  • 为问题和仪表板添加版本控制。您可以将下载的元数据检入存储库,并通过像 git 这样的版本控制软件管理对该数据的更改。
  • 为 Metabase 设置一个暂存环境。您可以在暂存环境中进行尝试,直到对更改满意为止,然后导出元数据,并将其上传到生产环境。

试用序列化功能,并通过我们的论坛告诉我们您是如何使用它的。

这有帮助吗?

感谢您的反馈!
分析师每周技巧
获取可行的见解
关于 AI 和数据的资讯,直接发送到您的收件箱
© . This site is unofficial and not affiliated with Metabase, Inc.