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

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

Metabase序列化

序列化功能仅在Pro企业版计划(包括自托管和Metabase Cloud)上可用。

许多在Pro和企业版计划上的客户,在需要上传预定义的问题仪表盘的多租户环境中使用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-sourcemetabase-target 的 Metabase(尽管您可以根据需要为这些环境命名)。请注意,我们创建这些 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.51.2

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

docker logs metabase-source

一旦您看到包含“Metabase 初始化 完成”的行,您就可以打开浏览器访问 https://127.0.0.1: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.51.2

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

  • metabase-source 在 https://127.0.0.1:5001
  • metabase-target 在 https://127.0.0.1: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":"[email protected]","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":"[email protected]","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://127.0.0.1:5001 并以您创建的管理员用户身份登录。用户 ID 是 [email protected],密码是 Metapass123

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

A fresh instance of Metabase.

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

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

我们需要一些要导出的应用程序数据,因此让我们使用 Metabase 中包含的 示例数据库 创建一些仪表板。或者,不如让 Metabase 为我们创建一些仪表板!

根据您的数据尝试这些 X-Rays 部分,单击带有 黄色闪电 的卡片,上面写着类似 查看产品 的内容。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.51.2 "export /target"

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

如果一切顺利,几秒钟后您应该看到一些输出,然后在您的终端中看到一条消息,表明 serialization.cmd :: 导出到 '/target' 完成! 🚛💨 📦

为了验证导出,请进入您的目录:/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 一起提供的示例数据库。

集合

在集合目录中是设置的集合、仪表板和问题。目录 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: [email protected]
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目录设置完成,我们可以运行导入命令将元数据导入目标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.51.2 "import /target"

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

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

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

序列化限制

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

通过API进行序列化

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

序列化的其他用例

使用序列化功能导出问题和仪表板,可以开启一些有趣的可能,包括

  • 给问题和仪表板添加版本控制。您可以将下载的元数据检入到存储库中,并通过版本控制软件(如git)管理该数据的变化。
  • 为Metabase设置预发布环境。您可以在预发布环境中进行试验,直到对更改满意为止,然后导出元数据,并将其上传到生产环境。

尝试使用序列化功能,并让我们知道您如何在我们的论坛上使用它。

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

在一个预发布的Metabase中创建模型、问题和仪表板,将您的更改提交到存储库,然后将这些更改推送到生产Metabase。

下一篇文章