序列化
一旦你真正开始使用Metabase,你可能会启动多个Metabase实例。你可能有几个测试或开发实例和一些生产实例,或者你可能为每个办公室或地区使用一个单独的Metabase。
为了帮助你在这种情况下,Metabase有一个序列化功能,它允许你创建一个Metabase内容的导出,然后可以将其导入一个或多个Metabase。
导出将源Metabase的内容序列化为YAML文件。
导入将读取这些导出的YAML文件,并根据这些YAML文件中序列化的内容在目标Metabase中创建或更新项。
运行这些导出
和导入
命令有两种方法
我们感兴趣的是如何改进序列化以适应您的流程。支持现有问题,让我们知道这对您很重要。如果尚无相关问题,请创建一个问题并告诉我们您需要什么。
序列化用例
- 预发布环境。通过从Metabase预发布实例导出并将它们导入您的生产实例(s)来启用重要仪表板的预发布到生产流程。
- 版本控制。将导出的文件存入版本控制并审计它们的变化,因为导出中包含的YAML文件非常易于阅读。
- 将资产复制到其他Metabase实例。从源Metabase导出“模板”数据并将其导入一个或多个目标实例。
查看我们的指南以
序列化不适用于如复制资产或交换同一Metabase实例内的数据源等用例。如果您正在同一实例内使用序列化来复制资产,请查看导出如何工作,导入如何工作以及序列化的其他用途中的您的用例说明。
导出如何工作
导出什么
Metabase只会在导出中包含一些工件
- 集合(但除非在导出选项中明确指定,否则个人集合不会导出)
- 仪表板
- 保存的问题
- 操作
- 模型
- 指标
- SQL代码片段
- 数据模型和表元数据
- 细分
- 问题和仪表板的公共共享设置
- 一般Metabase设置
- 事件和时间线
- 数据库连接字符串(只有当通过导出选项指定时才包含)(#customize-what-gets-exported)。
Metabase将工件导出到YAML文件目录。导出包括
-
包含各种Metabase实体YAML文件的目录。一个示例导出可能包括以下目录,具体取决于您导出什么以及您的Metabase内容
- 动作
- 集合
- 卡片
- 仪表板
- 时间线
- 数据库
通过API序列化时,导出目录将被压缩成.tar.gz文件。
-
一个包含一些Metabase全局设置的
settings.yaml
文件
默认情况下,不包括数据库连接细节,但您可以通过配置导出来包含它们。
导出的通用Metabase设置
以下是Metabase在settings.yaml
文件中导出的通用设置列表。有关Metabase设置的更多信息,请参阅配置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
自定义要导出的内容
您可以根据需要自定义导出内容。您可以告诉Metabase
- 导出特定集合
- 不导出集合
- 不导出Metabase设置
- 不导出表元数据
- 包含示例字段值(默认不包含)
- 包含数据库连接细节(默认不包含)
序列化问题的示例
问题可以在集合目录的cards
目录中找到。以下是一个使用SQL编写的带有字段过滤器和区域图可视化的示例问题YAML文件
为了保留原生查询的多行格式,请从原生查询中删除尾随空格。如果您的原生查询有尾随空格,YAML会将您的查询转换为单个字符串字面量(这只会影响展示,而不会影响功能)。
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: [email protected]
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使用实体ID来标识和引用Metabase项目
Metabase为每个Metabase项目(仪表板、问题、模型、集合等)分配一个唯一的实体ID。实体ID使用NanoID格式。
您可以在导出的YAML文件中的entity_id
字段中看到项目的实体ID。例如,在序列化问题的示例中,您将看到该问题的实体ID
entity_id: r6vC_vLmo9zG6_r9sAuYG
此ID也出现在serdes/meta → id
字段中(这些ID必须匹配)
serdes/meta:
- id: r6vC_vLmo9zG6_r9sAuYG
为了区分具有相同名称的实体,Metabase在导出实体的文件和目录名称中包含实体ID。
r6vC_vLmo9zG6_r9sAuYG_products_by_week.yaml
IA96oUzmUbYfNFl0GzhRj_accounts_model.yaml
KUEGiWvoBFEc5oGQCEnPg_converted_customers.yaml
例如,在序列化问题的示例中,您可以看到字段collection_id
collection_id: onou5H28Wvy3kWnjxxdKQ
此ID指的是保存问题的集合。在实际导出中,您将能够找到一个以其实体ID开头的YAML文件,例如:onou5H28Wvy3kWnjxxdKQ
。
数据库、模式、表和字段通过名称标识
默认情况下,Metabase导出一些数据库和数据模型设置。导出默认不包含数据库连接字符串。您可以明确包含数据库连接字符串。您也可以选择完全排除数据模型。
Metabase 将数据库和表序列化到 databases
目录中。它将为每个数据库、表、字段、段和度量创建 YAML 文件。
数据库、表和字段通过其名称引用(与通过实体 ID 引用的 Metabase 特定项目不同)。
例如,在 序列化问题的示例 中,有几个 YAML 键引用了“示例数据库”。
database_id: Sample Database
---
dataset_query:
database: Sample Database
在示例中字段过滤器(category_filter:
)的描述中,可以看到对用于填充过滤器选项的字段的引用。
dimension:
- field
- - Sample Database
- PUBLIC
- PRODUCTS
- CATEGORY
它指的是“示例数据库”中 PUBLIC
架构下的 PRODUCTS
表中的 CATEGORY
字段。在 databases
目录中序列化的 Sample Database
也将包括此字段和表的 YAML 文件。
导入工作原理
在导入过程中,Metabase 将读取提供的 YAML 文件,并根据 YAML 规范创建项目。《序列化问题的示例》说明了 Metabase 如何记录重建项目所需的信息。
Metabase 在导入过程中不会从目标实例中删除项目,但会覆盖已经存在的项目。
Metabase 依赖于 实体 ID 来确定要创建或覆盖的项目,以及项目之间的关系。在将内容导入已有内容的实例时,请注意
-
如果您导入一个具有不存在于目标 Metabase 中的
entity_id
的项目,Metabase 将创建一个新的项目。 -
如果您导入一个在目标 Metabase 中已经存在的
entity_id
的项目,现有项目将被覆盖。特别是,这意味着如果您导出一个问题,然后在导出的 YAML 文件中进行更改(例如,通过直接编辑
name
字段来重命名问题),然后导入编辑后的文件,Metabase 将尝试将您所做的更改应用到 YAML 上。 -
如果您导入一个具有空白
entity_id
(以及空白serdes/meta → id
)的项目,Metabase 将创建一个新的项目。 -
在 YAML 中引用的所有项目和数据源必须在目标 Metabase 中已存在,或者包含在导入中。
例如,如果导出的 YAML 中有字段
collection_id: onou5H28Wvy3kWnjxxdKQ
,则目标实例中必须已经存在onou5H28Wvy3kWnjxxdKQ
的集合,或者必须有一个具有此 ID 的集合导出 YAML 文件。
序列化最佳实践
使用与源实例和目标实例相同的 Metabase 版本
目前,只有当源和目标 Metabase 有相同的主版本时,序列化才能工作。如果您正在使用 CLI 序列化命令,您用于运行序列化命令的 .jar 文件的版本应与源和目标 Metabase 版本匹配。
如果您使用 H2 作为应用程序数据库,您需要在导入或导出之前停止 Metabase
如果您使用 Postgres 或 MySQL 作为应用程序数据库,您可以在 Metabase 运行时导入和导出。
避免使用序列化进行备份
仅作参考:序列化 不是 用来备份您的 Metabase。
请参阅 备份 Metabase。
如果您想从随Metabase提供的默认H2数据库迁移到MySQL/Postgres数据库,请使用迁移指南。
您需要手动添加许可证令牌
Metabase将您的许可证令牌排除在导出之外,因此如果您运行多个Metabase企业版的实例,您需要手动将许可证令牌添加到目标Metabase实例中,无论是通过Metabase用户界面,还是通过环境变量。
Metabase将日志添加到导出和导入过程中
导出:Metabase将日志添加到压缩目录中的export.log
文件中。
导入:您可以使用-o -
标志将日志直接导出到终端,或者使用-o import.log
将其保存到文件。
使用CLI命令进行序列化
在Metabase Cloud上序列化数据,请使用导入和导出API端点
Metabase提供export
和import
CLI命令。
有关序列化的通用信息,请参阅导出是如何工作的、导入是如何工作的和序列化最佳实践。
使用CLI进行导出
要导出Metabase实例的内容,请切换到运行Metabase JAR文件的目录,并运行以下命令:
java -jar metabase.jar export dir_name
其中dir_name
可以是您想要的任何目录名。
export
选项
要查看export
选项的列表,请使用help
命令。
java -jar metabase.jar help export
它将运行并打印类似以下内容:
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
默认情况下,Metabase将包括所有集合(除了个人集合)在导出中。要包括个人集合,您必须使用--collection
标志显式添加它们。
--collection
标志(别名-c
)允许您通过ID指定一个或多个要包含在导出中的集合。您可以在集合的URL中找到集合ID,例如,对于位于your-metabase.com/collection/42-terraforming-progress
的集合,ID将是42
。
如果您想指定多个集合,请使用逗号分隔ID。例如:
java -jar metabase.jar export export_name --collection 1,2,3
--no-collections
--no-collections
标志(别名-C
)告诉Metabase排除所有集合从导出。
--no-settings
--no-settings
标志(别名-S
)告诉Metabase排除包含全局设置的settings.yaml
文件,该文件默认导出。
--no-data-model
--no-data-model
标志(别名-D
)告诉Metabase排除导出中的表元数据设置。管理员在管理设置的表元数据标签页中定义元数据设置。
--include-field-values
标志 --include-field-values
(别名 -f
)指示 Metabase 包含字段值的样本值,这些值用于 Metabase 显示下拉菜单。默认情况下,Metabase 排除这些样本字段值。
--include-database-secrets
标志 --include-database-secrets
(别名 -s
)指示 Metabase 包含连接详情,包括数据库用户名和密码。默认情况下,Metabase 排除这些数据库连接密钥。如果您不使用此标志,您需要手动在目标 Metabase 中输入凭据。
使用 CLI 导入
要将导出的项目导入到 Metabase 实例中,请转到运行目标 Metabase 的目录(您要导入的 Metabase),并使用以下命令,其中 path_to_export
是要导入的导出路径
java -jar metabase.jar import path_to_export
目前,您只能将导出的项目导入到与同一版本 Metabase 创建的 Metabase 实例中。
import
选项
大多数选项是在从 Metabase 导出数据时定义的。要查看导入标志列表,请运行
java -jar metabase.jar help import
它将打印出
import path & options
Load serialized Metabase instance as created by the [[export]] command from directory `path`.
通过 API 进行序列化
与 CLI 序列化命令一样,这些端点仅适用于 Pro 和 Enterprise 计划。
您可以通过 Metabase 的 API 导入和导出序列化的 Metabase 数据,这使得在 Metabase Cloud 部署中实现序列化成为可能。
有两个端点
POST /api/ee/serialization/export
POST /api/ee/serialization/import
对于
/export
端点,我们使用POST
而不是GET
。导出操作不会修改您的 Metabase,但操作耗时且强度大,因此我们使用POST
以防止意外导出。
目前,这些端点是同步的。如果序列化过程耗时过长,请求可能会超时。在这种情况下,我们建议使用 CLI 命令。
有关序列化的通用信息,请参阅导出是如何工作的、导入是如何工作的和序列化最佳实践。
API 导出参数
您可以将可选参数附加到 Metabase,以指定要从导出中包含或排除的内容。您还可以组合参数(当然,不包括 all_collections
和选择性的集合)。
因此,假设您正在本地测试(localhost
),并且您想从导出中排除所有集合,您将按如下格式格式化 URL
https://127.0.0.1:3000/api/ee/serialization/export?all_collections=false
您可以将多个参数包括在内,参数之间用 &
分隔。例如,要排除导出中的设置和数据模型
https://127.0.0.1:3000/api/ee/serialization/export?data_model=false&settings=false
collection
类型:整数数组。
默认值:除非将 all_collections
设置为 false
,否则 Metabase 将导出所有集合。
要选择要导出的集合,请包括集合 ID。例如,要包括集合 1
和 2
collection=1&collection=2
all_collections
类型:布尔值。
默认值:true
(除非您使用 collection
指定子集集合)。
要排除所有集合
all_collections=false
settings
类型:布尔值。
默认值:true
。
要排除包含全局设置的 settings.yaml
文件
settings=false
data_model
类型:布尔值。
默认值:true
。
要排除 表元数据
data_model=false
field_values
类型:布尔值。
默认: false
。
包括字段的示例值,Metabase 使用这些值来显示下拉菜单
field_values=true
database_secrets
类型:布尔值。
默认: false
。
包括数据库连接详情,例如数据库用户名和密码
database_secrets=true
dirname
类型:字符串。
默认: <实例名称>-<YYYY-MM-dd_HH_mm>
指定不同的目录
dirname=name_of_your_directory
在通过 API 调用序列化时,您必须压缩您的文件
为了控制通过网络传输的文件大小,export
和 import
端点都期望 GZIP 压缩的 Tar 文件(.tgz
)。
压缩目录
要压缩目录(例如,名为 metabase_data
的目录)。
tar -czf metabase_data.tgz metabase_data
解压目录
解压/解压缩目录
tar -xvf metabase_data.tgz
序列化 API 示例
步骤 1:设置 API 密钥
- 创建一个 API 密钥。
- 将密钥分配给管理员组
步骤 2:导出
- 发送一个
curl
请求来导出数据
curl \
-H 'x-api-key: YOUR_API_KEY' \
-X POST 'http://your-metabase-url/api/ee/serialization/export' \
-o metabase_data.tgz
将 YOUR_API_KEY
替换为您的 API 密钥,将 your-metabase-url
替换为您的 Metabase 实例 URL。
我们使用
POST
而不是GET
来请求/export
端点。
此命令将下载名为 metabase_data.tgz
的 GZIP 压缩 Tar 文件。
- 解压压缩文件
tar -xvf metabase_data.tgz
解压后的目录将命名为类似 metabase-yyyy-MM-dd_HH-mm
的名称,其中包含导出的日期和时间。
步骤 3:导入
- 压缩包含序列化 Metabase 应用程序数据的目录
假设您有一个名为 metabase_data
的目录,其中包含 Metabase 应用程序数据的 YAML 文件。在将文件导入目标 Metabase 之前,您需要压缩这些文件。
tar -czf metabase_data.tgz metabase_data
- 向
/api/ee/serialization/import
发送 POST 请求。
从您存储 GZIP 压缩文件的目录运行
curl -X POST \
-H 'x-api-key: YOUR_API_KEY' \
-F file=@metabase_data.tgz \
'http://your-metabase-url/api/ee/serialization/import' \
-o -
将 YOUR_API_KEY
替换为您的 API 密钥,将 your-metabase-url
替换为您的 Metabase 实例 URL。使用 -o -
选项将在终端中输出日志。
如果您将 Metabase 数据导入与导出相同的 Metabase,您将覆盖现有的问题、仪表板等。请参阅 导入如何工作。
序列化的其他用途
序列化旨在用于版本控制、预发布到生产流程以及将资产复制到其他 Metabase 实例。虽然可以使用序列化处理其他用例(例如,在单个实例内复制资产),但我们官方不支持这些用例。
我们提供了一些如何处理这些不受支持的用例的指导,但您应自行承担风险。我们强烈建议您首先在一个非生产实例上测试涉及序列化的任何流程,如果有任何问题,请联系 [email protected]。
在同一个 Metabase 内使用序列化来复制内容
使用序列化来复制内容并不简单,因为您需要处理所有要复制的项目以及与其相关联的项目 实体ID,以避免覆盖现有数据。
在开始这次危险之旅之前,请查看 导出如何工作 和 导入如何工作,如有任何问题,请联系 [email protected]。
您需要注意
- 导入具有已存在实体ID的项目将覆盖现有项目。要使用现有的YAML文件创建新项目,您需要:a) 创建新的实体ID或b) 清除实体ID。
- 两个项目不能有相同的实体ID。
- 在YAML文件中,
entity_id
和serdes/meta → id
字段应匹配。 - 如果YAML文件中项目的
entity_id
和serdes/meta → id
字段为空,Metabase将创建一个带有新实体ID的新项目。 -
项目和数据源应已存在于目标Metabase中,或者包含在导入中。
例如,一个集合可以包含一个仪表板,该仪表板包含一个基于模型构建的问题,该模型引用数据源。所有这些依赖项必须包含在导入中或已存在于目标实例中。
这意味着您可能需要进行多阶段导出/导入:首先在Metabase中创建一些需要的项目(如集合),然后导出以获取它们的实体ID,然后导出要复制的项目,并在引用它们的项目中使用这些ID。
例如,要复制一个仅包含直接基于原始数据构建的问题的集合(不包括基于模型或其他已保存问题的),不更改问题的数据源,可以使用以下过程
- 在Metabase中创建一个“模板”集合,并添加您想要复制的项目。
- 在Metabase中创建一个新的集合,该集合将作为复制项目的目标。
- 导出模板集合和目标集合(您可以使用导出参数仅导出一些集合)。导出的模板问题的YAML文件将有自己的实体ID,并引用模板集合的实体ID。
- 从其导出中获取目标集合的实体ID。
-
在模板集合导出的问题的YAML文件中
- 清除问题的
entity_id
和serdes/meta → id
字段的值。这将确保模板问题不会被覆盖,相反,Metabase将创建新的问题。 - 将模板集合的
collection_id
引用替换为新集合的ID
- 清除问题的
- 导入编辑后的文件。
此过程假定复制的所有问题都将使用相同的数据源。您可以将此与切换实例内问题的数据源结合使用,为每个复制的集合使用不同的数据源。
如果您想一次性创建一个集合的多个副本,那么您不必为每个副本重复此过程,您可以创建自己的目标实体ID(可以是任何使用NanoID格式的字符串),复制所有模板YAML文件,并用您创建的实体ID替换模板实体ID及其任何引用。
如果您的集合包含仪表板、模型和其他可以添加依赖项的项目,这个过程可能会变得更复杂——您需要处理每个依赖项。我们强烈建议您首先在一个非生产环境的Metabase上测试您的序列化,如果您需要任何帮助,请联系[email protected]。
使用序列化在单个实例中交换问题的数据源
如果您想更改Metabase中一些问题的数据源——例如,仅更改单个集合中的问题——您可以手动序列化这些问题,然后编辑导出的YAML文件。
如果您想将建立在数据库A上的所有问题切换到使用数据库B,并且数据库B具有与数据库A完全相同的模式,您不需要使用序列化:您只需在“管理员 > 数据库”中交换连接字符串即可。
您的数据库必须具有相同的引擎,理想情况下它们应该具有相同的模式。
您需要注意
- 在Metabase中,数据库、表和字段是通过名称进行引用的(请参阅)
- 默认情况下不会导出数据库连接详情。要导出数据库连接详情,您需要在导出参数中指定。
- 引用的数据库、表和字段应已在目标Metabase中存在,或包含在导入中。
例如,如果您想将“电影评论
”集合中的所有问题切换到使用“浪漫
”数据库而不是“恐怖
”数据库,并且两个数据库具有相同的模式,您可以按照以下过程操作
- 在Metabase中,在“管理员 > 数据库”中添加一个新的数据库连接,并将其命名为“
浪漫
”。 -
导出“
电影评论
”集合。您可以让Metabase导出单个集合,或者您可以导出所有集合,然后只处理“
电影评论
”集合文件夹中的文件。 - 在此集合项的YAML文件中,将所有对“
恐怖
”数据库的引用替换为对“浪漫
”数据库的引用。 - 导入编辑后的文件。
导入将覆盖原始问题。如果您想创建使用不同数据源的新问题,可以将此过程与使用序列化在同一个Metabase中复制资产结合起来。
此过程假设新数据源具有完全相同的模式。如果模式不同,您还需要替换所有对表和字段的引用。此过程可能很复杂且容易出错,因此我们强烈建议您首先在一个非生产实例上测试您的序列化,如果您需要任何帮助,请联系[email protected]。
从旧序列化命令迁移
如果您是从Metabase版本46.X或更旧版本升级,以下是需要了解的内容
- “
export
”命令替换了“dump
”命令。 - “
import
”命令替换了“load
”命令。
以下是一些其他更改要点
- 导出的 YAML 文件结构略有不同
- Metabase 会为每个文件前缀添加一个 24 位的实体 ID(例如
IA96oUzmUbYfNFl0GzhRj_accounts_model.yaml
)。您可以在导出之前运行 Metabase 命令来删除实体 ID。 - 文件树略有不同。
- Metabase 会为每个文件前缀添加一个 24 位的实体 ID(例如
- 要序列化个人收藏夹,只需在
-c
选项(即--collection
)后面的逗号分隔 ID 列表中包含个人收藏夹 ID 即可。
如果您编写了自动化序列化的脚本,您需要
- 使用升级后的 Metabase 重新序列化您的 Metabase(使用新的
export
和import
命令)。请注意,序列化仅在您使用相同的 Metabase 版本导出和导入 Metabase 时才会生效。 - 更新脚本以使用新命令。请参阅新的 导出选项。
- 如果您的脚本对导出的 YAML 文件进行任何后处理,您可能需要更新您的脚本以适应略有不同的目录和 YAML 文件结构。
进一步阅读
- 序列化教程.
- 多个环境
- 基于 git 的工作流程设置.
- 需要帮助?请联系 [email protected]。
阅读其他 Metabase 版本的文档。