mz-deploy

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

mz-deploy

mz-deploy

mz-deploy
is declarative SQL project tooling for Materialize. A project is a git-tracked directory of
.sql
files describing the desired state of a Materialize environment;
mz-deploy
compiles it, type-checks it offline, tests it in a local container, and deploys changes through an atomic stage-then-promote lifecycle.
bash
brew install materializeinc/materialize/mz-deploy
mz-deploy
是Materialize的声明式SQL项目工具。一个项目是一个受git追踪的目录,包含描述Materialize环境期望状态的
.sql
文件;
mz-deploy
会编译这些文件、离线类型检查、在本地容器中测试,并通过原子化的“先预发布再推广”(stage-then-promote)生命周期部署变更。
bash
brew install materializeinc/materialize/mz-deploy

Discover Before You Run

运行前先了解

The CLI is self-documenting, and its help text is the source of truth. Do not guess command names, flags, or argument order.
  1. mz-deploy help
    — all commands, grouped by purpose.
  2. mz-deploy help <command>
    — the detailed usage guide for one command: behavior, every flag, examples, error recovery, and exit codes.
  3. mz-deploy help profiles
    — the configuration topic guide (profiles, variables, suffixes, file overrides, TLS).
This skill covers the concepts and the shape of the workflow so you know which command to reach for. Read that command's
help
for the flags before running it.
Run commands from the project root, or pass
-d <path>
. Global options worth knowing:
-p/--profile
selects the connection profile,
--output json
for machine-readable output (supported by most commands, useful in CI),
-v
for verbose debugging,
-q
to suppress informational output.
该CLI自带文档,其帮助文本是权威信息来源。请勿猜测命令名称、标志或参数顺序。
  1. mz-deploy help
    —— 按用途分组的所有命令。
  2. mz-deploy help <command>
    —— 单个命令的详细使用指南:行为、所有标志、示例、错误恢复和退出码。
  3. mz-deploy help profiles
    —— 配置主题指南(配置文件、变量、后缀、文件覆盖、TLS)。
本技能涵盖工作流的概念和流程,帮助你了解该使用哪个命令。在运行命令前,请阅读对应命令的
help
查看标志。
从项目根目录运行命令,或传递
-d <path>
。值得了解的全局选项:
-p/--profile
选择连接配置文件,
--output json
用于机器可读输出(大多数命令支持,在CI中很有用),
-v
用于详细调试,
-q
抑制信息输出。

Project Layout

项目布局

project.toml              # project config: mz_version, dependencies, per-profile settings
profiles.toml             # connection profiles (also resolved from ~/.mz)
.mzprofile                # gitignored per-checkout default profile
types.lock                # cached schemas of external dependencies, for offline type checking
target/                   # gitignored local build cache (safe to delete; see `clean`)
models/
  <database>/
    <schema>.sql          # schema mod file — schema-level statements (see below)
    <schema>/
      <object>.sql        # one view, materialized view, table, source, sink, connection, or secret
clusters/<name>.sql       # cluster definitions (+ their GRANTs)
roles/<name>.sql          # role definitions
network-policies/<name>.sql
The path determines the object's fully qualified name: an MV in
models/materialize/catalog/clusters.sql
is
materialize.catalog.clusters
. A schema mod file
<schema>.sql
sitting beside the
<schema>/
directory — holds statements that apply to the schema as a whole, such as
SET api = stable
.
mz-deploy new <name>
scaffolds this structure in a new directory;
init
does the same in the current one.
project.toml              # 项目配置:mz_version、依赖、按配置文件设置
profiles.toml             # 连接配置文件(也可从~/.mz解析)
.mzprofile                # 受git忽略的每个检出版本的默认配置文件
types.lock                # 外部依赖的缓存模式,用于离线类型检查
target/                   # 受git忽略的本地构建缓存(可安全删除;参见`clean`命令)
models/
  <database>/
    <schema>.sql          # 模式修改文件——模式级语句(见下文)
    <schema>/
      <object>.sql        # 单个视图、物化视图、表、源、汇、连接或密钥
clusters/<name>.sql       # 集群定义(及其GRANT语句)
roles/<name>.sql          # 角色定义
network-policies/<name>.sql
路径决定了对象的完全限定名称:位于
models/materialize/catalog/clusters.sql
中的物化视图(MV)是
materialize.catalog.clusters
模式修改文件——与
<schema>/
目录同级的
<schema>.sql
——包含应用于整个模式的语句,例如
SET api = stable
mz-deploy new <name>
在新目录中生成此结构;
init
则在当前目录中完成同样操作。

Command Map

命令映射表

GroupCommands
Getting started
new
,
init
,
profile
(list/set/current),
setup
,
debug
Develop
compile
,
clean
,
test
,
explain
,
dev
,
lsp
,
sql
,
mcp
Infrastructure
lock
,
apply
,
delete
Deploy
stage
,
wait
,
promote
,
abort
,
describe
,
list
,
log
One-time bootstrap:
mz-deploy setup
creates the
_mz_deploy
tracking database, its tables, the
_mz_deploy_server
cluster, and three roles. It must be run by a superuser when RBAC is enabled, because it grants system privileges. Everything after that runs as an ordinary user.
分组命令
入门
new
,
init
,
profile
(列出/设置/当前),
setup
,
debug
开发
compile
,
clean
,
test
,
explain
,
dev
,
lsp
,
sql
,
mcp
基础设施
lock
,
apply
,
delete
部署
stage
,
wait
,
promote
,
abort
,
describe
,
list
,
log
一次性引导:
mz-deploy setup
创建
_mz_deploy
跟踪数据库、其表、
_mz_deploy_server
集群以及三个角色。当启用RBAC时,必须由超级用户运行,因为它会授予系统权限。之后所有操作都可由普通用户运行。

Workflow

工作流

bash
mz-deploy compile              # parse, resolve dependencies, type-check offline
mz-deploy test                 # run unit tests in a local Materialize container
mz-deploy apply                # converge infrastructure (see below)
mz-deploy stage                # deploy changed views/MVs to suffixed staging schemas
mz-deploy wait <DEPLOY_ID>     # watch clusters hydrate until ready
mz-deploy promote <DEPLOY_ID>  # atomic swap into production
compile
needs no database connection, so it belongs in CI on every commit. A passing
compile
guarantees
stage
and
apply
will not fail at the SQL parsing stage. Note that every profile variant is validated regardless of
--profile
, so a syntax error in
foo#staging.sql
still fails
compile --profile production
.
Alongside:
list
shows unpromoted deployments (like
git branch
),
describe <ID>
details one,
log
shows promotion history (like
git log
), and
abort <ID>
destroys a staging deployment without promoting it.
bash
mz-deploy compile              # 解析、解析依赖、离线类型检查
mz-deploy test                 # 在本地Materialize容器中运行单元测试
mz-deploy apply                # 收敛基础设施(见下文)
mz-deploy stage                # 将变更后的视图/MV部署到带后缀的预发布模式
mz-deploy wait <DEPLOY_ID>     # 监控集群直到准备就绪
mz-deploy promote <DEPLOY_ID>  # 原子化切换到生产环境
compile
不需要数据库连接,因此应在每次提交时的CI中运行。
compile
通过意味着
stage
apply
不会在SQL解析阶段失败。注意,无论
--profile
如何,都会验证所有配置文件变体,因此
foo#staging.sql
中的语法错误仍会导致
compile --profile production
失败。
配套命令:
list
显示未推广的部署(类似
git branch
),
describe <ID>
展示单个部署的详细信息,
log
显示推广历史(类似
git log
),
abort <ID>
销毁预发布部署而不进行推广。

Key Concepts

核心概念

apply
owns infrastructure;
stage
owns views.
apply
is declarative, diff-based, and idempotent, converging clusters, roles, network policies, secrets, connections, sources, and tables in dependency order.
stage
handles views and materialized views. Tables and sources are never created by
stage
— they must already exist, so
apply
runs first.
delete <type> <name>
is the inverse of
apply
: it drops one object without CASCADE and removes its project file.
Deploy IDs and staging suffixes. Each deployment gets an ID — by default the first 7 characters of the current commit SHA — used to suffix its schemas and clusters (
public
public_abc123
). Staging clusters are cloned from the corresponding production cluster's configuration, including any auto-scaling strategy, so staged objects hydrate the way production will. Staging runs in isolation alongside production.
Change detection is hash-based.
stage
compares each object's SQL hash against the last promoted snapshot and deploys only what changed, plus anything downstream of a change. Unchanged objects are not recreated. Override with
--redeploy-schema <db.schema>
or
--redeploy-all
.
Promotion is atomic and resumable.
promote
executes
ALTER … SWAP
on schemas and clusters inside a single transaction, then does post-swap work: creating deferred sinks, applying replacement MVs, repointing sinks at the new production objects, and dropping the old resources. If it dies mid-flight, re-running the same command detects the post-swap state and resumes cleanup.
Sinks are deferred to promote. They must not start producing until the deployment is live, so
stage
records them and
promote
creates them.
Conflict detection works at schema and cluster granularity. Because a whole schema is swapped as a unit, two deployments touching any of the same schemas or clusters conflict — even when they modify different objects inside them. The first to promote wins; the second is rejected and must be re-staged against current production.
--force
skips the check, and doing so drops the other deployer's schemas, since schemas are swapped wholesale rather than merged. Only use it when clobbering that work is the intent.
Stable API schemas. By default a changed object is recreated in staging and its whole schema is swapped, which redeploys in-project dependents automatically but breaks consumers in other mz-deploy projects. Adding
SET api = stable
to a schema mod file marks that schema as an API boundary: changed MVs are updated in place via
ALTER MATERIALIZED VIEW … APPLY REPLACEMENT
, preserving object identity. Downstream consumers — in any project — need no redeployment. Constraints: stable schemas may contain only materialized views, and a changed replacement MV does not propagate dirtiness to its dependents.
Type checking is offline.
compile
and
test
read external dependency schemas from
types.lock
. Declare external objects in
project.toml
as
dependencies = ["db.schema.table"]
and run
mz-deploy lock
to refresh the file. Source tables created by
CREATE TABLE FROM SOURCE
are auto-discovered and need no declaration;
apply tables
regenerates the lock automatically.
Roles.
setup
creates
materialize_deployer
(stage, promote, abort),
materialize_developer
(read-only deployment state, plus
dev
overlays), and
materialize_monitor
. Each user must belong to exactly one — holding several is an error. Use separate profiles with distinct users for deploying, developing, and monitoring.
apply
负责基础设施;
stage
负责视图。
apply
是声明式、基于差异且幂等的,会按依赖顺序收敛集群、角色、网络策略、密钥、连接、源和表。
stage
处理视图和物化视图。表和源永远不会
stage
创建——它们必须已存在,因此需先运行
apply
delete <type> <name>
apply
的逆操作:它会删除一个对象且不使用CASCADE,并移除其项目文件。
部署ID和预发布后缀。 每个部署都会获得一个ID——默认是当前提交SHA的前7个字符——用于为其模式和集群添加后缀(
public
public_abc123
)。预发布集群会从对应生产集群的配置克隆而来,包括任何自动扩缩策略,因此预发布对象的 hydrated 方式与生产环境一致。预发布与生产环境隔离运行。
变更检测基于哈希。
stage
会将每个对象的SQL哈希与上次推广的快照进行比较,仅部署变更的内容,以及变更内容的下游依赖。未变更的对象不会重新创建。可使用
--redeploy-schema <db.schema>
--redeploy-all
覆盖此行为。
推广是原子化且可恢复的。
promote
在单个事务中对模式和集群执行
ALTER … SWAP
,然后执行切换后的工作:创建延迟的汇、应用替换物化视图、将汇重新指向新的生产对象,并删除旧资源。如果中途中断,重新运行相同命令会检测切换后的状态并恢复清理工作。
汇延迟到推广阶段创建。 它们必须在部署上线后才开始生成数据,因此
stage
会记录它们,
promote
再创建它们。
冲突检测在模式和集群粒度上工作。 由于整个模式作为一个单元进行切换,两个涉及任何相同模式或集群的部署会发生冲突——即使它们修改的是模式内的不同对象。第一个完成推广的部署获胜;第二个会被拒绝,必须针对当前生产环境重新预发布。
--force
会跳过检查,但这样做会删除其他部署者的模式,因为模式是整体切换而非合并。仅当有意覆盖其他工作时才使用此选项。
稳定API模式。 默认情况下,变更后的对象会在预发布环境中重新创建,其整个模式会被切换,这会自动重新部署项目内的依赖,但会破坏其他mz-deploy项目中的消费者。在模式修改文件中添加
SET api = stable
会将该模式标记为API边界:变更后的物化视图会通过
ALTER MATERIALIZED VIEW … APPLY REPLACEMENT
进行就地更新,保留对象标识。下游消费者——无论属于哪个项目——都无需重新部署。约束条件:稳定模式可能包含物化视图,且变更后的替换物化视图不会将脏数据传播给其依赖。
类型检查是离线的。
compile
test
types.lock
读取外部依赖模式。在
project.toml
中声明外部对象为
dependencies = ["db.schema.table"]
,并运行
mz-deploy lock
刷新该文件。通过
CREATE TABLE FROM SOURCE
创建的源表会被自动发现,无需声明;
apply tables
会自动重新生成锁文件。
角色。
setup
创建
materialize_deployer
(负责stage、promote、abort)、
materialize_developer
(只读部署状态,加上
dev
覆盖)和
materialize_monitor
。每个用户必须属于恰好一个角色——同时属于多个角色是错误的。为部署、开发和监控使用不同的配置文件和不同的用户。

Profiles and Per-Profile Configuration

配置文件和按配置文件的配置

A profile is a named connection target in
profiles.toml
, resolved from
--profiles-dir
, then
MZ_DEPLOY_PROFILES_DIR
, then
~/.mz
. The active profile resolves from
--profile
, then
MZ_DEPLOY_PROFILE
, then the gitignored
.mzprofile
in the project root (written by
mz-deploy profile set
). A built-in
emulator
profile always exists, so a local Materialize emulator works with zero configuration.
Passwords support
${VAR}
substitution, overridable by
MZ_PROFILE_<NAME>_PASSWORD
.
sslmode
follows PostgreSQL's vocabulary and defaults to
prefer
for loopback hosts,
require
otherwise — use
verify-full
for Materialize Cloud.
The profile does more than pick a host. It also selects, at compile time:
  • profile_suffix
    (in
    project.toml
    ) — appended to every database and cluster name, including
    IN CLUSTER
    references. Write the delimiter yourself:
    "_staging"
    , not
    "staging"
    . Staging suffixes stack on top (
    foo
    foo_staging
    foo_staging_a
    ).
  • SQL variables
    [<profile>.variables]
    in
    project.toml
    , referenced in any
    .sql
    file with psql syntax:
    :name
    (raw),
    :'name'
    (quoted string),
    :"name"
    (quoted identifier). Referencing an undefined variable fails compilation.
  • File overrides
    name#<profile>.sql
    replaces
    name.sql
    when that profile is active. All variants are validated at compile time regardless of which is active, and all must share the same primary statement type. Views and materialized views cannot have file overrides — use SQL variables instead.
配置文件是
profiles.toml
中命名的连接目标,解析顺序为
--profiles-dir
MZ_DEPLOY_PROFILES_DIR
~/.mz
活动配置文件的解析顺序为
--profile
MZ_DEPLOY_PROFILE
、项目根目录中受git忽略的
.mzprofile
(由
mz-deploy profile set
写入)。内置的
emulator
配置文件始终存在,因此本地Materialize模拟器无需任何配置即可工作。
密码支持
${VAR}
替换,可通过
MZ_PROFILE_<NAME>_PASSWORD
覆盖。
sslmode
遵循PostgreSQL的术语,默认对回环主机使用
prefer
,其他情况使用
require
——对Materialize Cloud使用
verify-full
配置文件的作用不仅仅是选择主机。它还会在编译时选择:
  • profile_suffix
    (在
    project.toml
    中)——附加到每个数据库和集群名称,包括
    IN CLUSTER
    引用。自行写入分隔符:
    "_staging"
    ,而非
    "staging"
    。预发布后缀会叠加(
    foo
    foo_staging
    foo_staging_a
    )。
  • SQL变量——
    project.toml
    中的
    [<profile>.variables]
    ,在任何
    .sql
    文件中使用psql语法引用:
    :name
    (原始)、
    :'name'
    (引号字符串)、
    :"name"
    (引号标识符)。引用未定义的变量会导致编译失败。
  • 文件覆盖——当该配置文件处于活动状态时,
    name#<profile>.sql
    会替换
    name.sql
    。无论哪个配置文件处于活动状态,所有变体都会在编译时验证,且所有变体必须共享相同的主语句类型。视图和物化视图不能使用文件覆盖——请改用SQL变量。

Rollback

回滚

There is no rollback command. Reverse the change in the project and promote the result:
bash
git revert <commit>
mz-deploy stage
mz-deploy promote <DEPLOY_ID>
Because
promote
swaps atomically, the rollback promotion is itself atomic — production switches back in a single transaction.
没有专门的回滚命令。在项目中撤销变更并推广结果:
bash
git revert <commit>
mz-deploy stage
mz-deploy promote <DEPLOY_ID>
由于
promote
是原子化切换,回滚推广本身也是原子化的——生产环境会在单个事务中切换回之前的状态。

Unit Tests

单元测试

mz-deploy test
runs tests written inline in the same
.sql
file as the view they cover, using
EXECUTE UNIT TEST
with mocked dependencies. The syntax is specific to mz-deploy and documented nowhere else — see references/unit-tests.md for the full grammar, worked examples, and failure modes.
mz-deploy test
运行与所覆盖视图在同一
.sql
文件中内联编写的测试,使用
EXECUTE UNIT TEST
和模拟依赖。该语法是mz-deploy特有的,无其他文档——请参阅references/unit-tests.md获取完整语法、示例和失败模式。

Gotchas

注意事项

  • stage
    requires a clean git tree.
    Commit, stash, or pass
    --allow-dirty
    .
  • setup
    needs a superuser under RBAC
    , one time only.
  • test
    and
    explain
    need Docker
    , and share one container named
    mz-deploy-sandbox
    across invocations on the host. Reuse is by name, not by image, so
    --docker-image
    has no effect until you
    docker rm -f mz-deploy-sandbox
    .
  • delete
    never cascades.
    If dependents exist it fails and leaves the project file in place.
  • dev
    will not target a production cluster.
    Provision a dedicated dev cluster.
  • A profile's
    cluster
    option is ignored.
    mz-deploy pins every connection to its own internal
    _mz_deploy_server
    cluster; resize that with a standard
    ALTER CLUSTER
    if needed.
  • stage
    failures roll back automatically.
    Pass
    --no-rollback
    to keep the partial deployment for debugging, then clean up with
    abort
    .
  • A stale
    target/
    cache
    can produce confusing compile or type errors. Run
    mz-deploy clean
    .
  • stage
    需要干净的git工作区。
    提交、暂存或传递
    --allow-dirty
  • 启用RBAC时,
    setup
    需要超级用户
    ,仅需运行一次。
  • test
    explain
    需要Docker
    ,并在主机上的多次调用中共享一个名为
    mz-deploy-sandbox
    的容器。复用是按名称而非镜像,因此
    --docker-image
    在你
    docker rm -f mz-deploy-sandbox
    之前不会生效。
  • delete
    永远不会级联。
    如果存在依赖,它会失败并保留项目文件。
  • dev
    不会指向生产集群。
    请配置专用的开发集群。
  • 配置文件的
    cluster
    选项会被忽略。
    mz-deploy会将每个连接固定到其内部的
    _mz_deploy_server
    集群;如有需要,使用标准的
    ALTER CLUSTER
    调整其大小。
  • stage
    失败会自动回滚。
    传递
    --no-rollback
    以保留部分部署用于调试,然后使用
    abort
    清理。
  • 过期的
    target/
    缓存
    可能会导致混淆的编译或类型错误。运行
    mz-deploy clean