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

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

Metabase 序列化

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

许多使用 Pro 和 Enterprise 计划的客户在多租户环境中使用 Metabase,这需要上传一组预定义好的问题仪表盘,无论是为了设置新的 Metabase 实例,还是新的数据库连接。

本文将介绍如何:

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

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

我们将使用 Docker 来运行我们的源和目标 Metabase,并使用 PostgreSQL 作为其应用程序数据库。我们不建议在生产环境中使用默认的 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.55.2

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

docker logs metabase-source

一旦您看到包含“Metabase initialization COMPLETE”的行,您就可以在浏览器中打开 http://localhost: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.55.2

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

  • metabase-source 在 http://localhost:5001
  • metabase-target 在 http://localhost: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 实例启动并您的用户创建完毕后,打开 http://localhost:5001 并使用您创建的管理员用户登录。用户 ID 为 admin@metabase.local,密码为 Metapass123

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

A fresh instance of Metabase.

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

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

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

根据您的数据尝试这些 X-Ray 部分,点击带有黄色闪电标志的卡片,上面写着类似 产品概览 的内容。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.55.2 "export /target"

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

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

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

设置

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

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

以下是一个名为 Products per category 的示例问题(称为卡片)的预览:

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 以查看原始序列化数据目录与您将用于导入到目标 Metabase 的序列化加载目录之间的更改:

cd /tmp
diff -r metabase_data serialize_import

您应该会看到以下内容:

Only in metabase_data: databases

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

现在,当我们的 /tmp/serialize_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.55.2 "import /target"

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

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

就这样:您已经为 Metabase 的新实例预加载了一个包含仪表盘和各种问题的集合!

序列化限制

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

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

通过 API 序列化

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

序列化的其他用例

使用序列化功能导出问题和仪表盘开启了一些很酷的可能性,包括:

  • 为问题和仪表盘添加版本控制。您可以将下载的元数据签入存储库,并通过 Git 等版本控制软件管理该数据的更改。
  • 为 Metabase 设置一个暂存环境。您可以随意使用暂存环境,直到对更改满意为止,然后导出元数据,并将其上传到生产环境。

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

下一步:设置基于 Git 的工作流

在 Metabase 暂存环境中创建模型、问题和仪表盘,将您的更改提交到存储库,然后将这些更改推送到您的 Metabase 生产环境。

下一篇文章
© . All rights reserved.