Skip to main content

设置开发环境

本节中的文档有点像是知识的大杂烩, 代表了运行 Superset 的多种方式(docker-compose,仅使用 "docker",在 "metal(裸机)" 上,或使用 Makefile)。

note

我们现在演进到更积极地推荐和支持 docker-compose 作为主要的运行方式, 用于 Superset 的开发并保持你的理智。 大多数人应该坚持阅读前面几节 - ("Fork & Clone","docker-compose" 和 "安装开发工具")

Fork 和 Clone

首先,在 GitHub 上 Fork 仓库, 然后克隆它。

其次,你可以直接克隆主仓库,但是你将无法发送 PRs。

git clone git@github.com:your-username/superset.git
cd superset

docker-compose (推荐!)

设置好环境以便在 Superset 的任何部分挤出一句 "hello world" 应该像下面这样简单

docker-compose up

请注意:

  • 这将拉取/构建 Docker 镜像并运行一组服务,包括:
    • 一个 Superset Flask web server,挂载本地的 Python 仓库/代码
    • 一个 Superset Celery worker,同样挂载本地的 Python 仓库/代码
    • 一个 Superset Node service,挂载、编译和打包 JS/TS 资源
    • 一个 Superset Node websocket service 来驱动异步后端
    • Postgres 作为元数据数据库和存储示例数据集、图表和仪表板,这些应该在启动时填充
    • Redis 作为我们的异步后端的消息队列和缓存后端
  • 在首次启动时,它会向数据库加载示例
  • 所有其他细节和指向可在 docker-compose.yml 中找到
  • 本地仓库在服务内部挂载,这意味着在主机上更新代码将在 Docker 镜像中反映出来
  • Superset 在 localhost:8088/ 提供服务
  • 您可以使用 admin/admin 登录
caution

由于 docker-compose 主要设计用于在 单个主机 上运行一组容器, 并且因此无法可靠地支持 高可用性, 我们不支持也不推荐使用我们的 docker-compose 构造来支持生产类型的用例。 对于单主机环境,我们推荐使用 minikube 并 结合我们的 在 k8s 上安装 文档。

安装开发工具

note

虽然 docker-compose 简化了很多设置,但你仍然希望在本地设置许多东西来为你的 IDE 提供动力, 以及像 commit hookslinterstest-runners 这样的工具。 请注意,你可以使用像 docker-compose exec superset_app bash 这样的命令在 Docker 镜像内执行这些操作, 但许多人喜欢从主机运行这些工具。

Python 环境

假设你已经有了一种设置 Python 环境的方法,如 pyenvvirtualenv 或其他方法, 你所需要做的就是安装我们的开发、固定的 Python 依赖包

pip install -r requirements/development.txt

Git Hooks

Superset 使用 pre-commit 提供的 Git 预提交钩子。 要安装,请运行以下命令:

pre-commit install

一系列检查现在会在你进行 Git 提交时运行。

docker-compose 的替代方案

caution

这部分文档是一些与不使用 docker-compose 设置开发环境相关的信息的大杂烩, 它们被不同程度地记录和支持。很难维护如此广泛的方法,并确保它们在不同环境中都能正常工作。

Flask server

OS 依赖

在遵循这些步骤之前,请确保你的机器满足 OS 依赖。 你也需要安装 MySQL 或 MariaDB

确保你正在使用 Python 版本 3.9、3.10 或 3.11,然后继续执行:

# 创建虚拟环境并激活它(推荐)
python3 -m venv venv # 设置 Python3 虚拟环境
source venv/bin/activate

# 安装外部依赖项
pip install -r requirements/development.txt

# 以可编辑(开发)模式安装 Superset
pip install -e .

# 初始化数据库
superset db upgrade

# 在您的元数据数据库中创建管理员用户(使用 `admin` 作为用户名以便能够加载示例)
superset fab create-admin

# 创建默认的角色和权限
superset init

# 加载一些数据来操作。
# 注意:在此之前必须使用用户名 `admin` 创建一个管理员用户,这条命令才能生效。
superset load-examples

# 从虚拟环境中启动 Flask 开发 Web 服务器。
# 注意此时页面可能没有 CSS。
# 请参阅下面的说明来构建前端资源。
superset run -p 8088 --with-threads --reload --debugger --debug

或者你可以通过我们的 Makefile 进行安装

# 创建虚拟环境并激活它(推荐)
$ python3 -m venv venv # 设置 Python3 虚拟环境
$ source venv/bin/activate

# 安装 pip 包以及预提交(pre-commit)配置
$ make install

# 安装 Superset 的 pip 包并仅设置环境
$ make superset

# 仅设置预提交(pre-commit)
$ make pre-commit

注意:FLASK_APP env 变量通常不需要手动设置,因为它当前是通过 .flaskenv 控制的,但如果确实需要设置的话,应该设为 superset.app:create_app()

如果你对 FAB 管理的模板进行了更改,这些模板的构建方式与较新的、基于 React 的前端资源不同,你需要不带 --with-threads 参数启动应用,如下所示: superset run -p 8088 --reload --debugger --debug

依赖项

如果你添加了一个新的依赖或更新了现有的依赖(参见 setup.py 中的 install_requires 部分),你必须重新编译(freeze)Python 依赖项,以确保对于持续集成(CI)、测试等场景,构建是确定性的。这可以通过以下命令实现,

$ python3 -m venv venv
$ source venv/bin/activate
$ python3 -m pip install -r requirements/development.txt
$ pip-compile-multi --no-upgrade

当升级单个包的版本号时,你应该使用 pip-compile-multi 命令加上 -P 标志:

$ pip-compile-multi -P my-package

要根据 setup.pyrequirements/*.in 中定义的限制更新所有依赖项,请运行 pip-compile-multi,无需添加任何标志:

$ pip-compile-multi

这应该定期执行,但建议彻底手动测试应用程序,以确保没有引入未被单元测试和集成测试捕获的破坏性更改。

将日志记录到浏览器控制台

此功能仅适用于 Python 3。当你调试应用程序时,可以使用 ConsoleLog 包将服务器日志直接发送到浏览器控制台。你需要通过在 config.pysuperset_config.py 中添加以下内容来修改应用:

from console_log import ConsoleLog

def FLASK_APP_MUTATOR(app):
app.wsgi_app = ConsoleLog(app.wsgi_app, app.logger)

然后确保你使用正确的 worker 类型运行你的 WSGI 服务器:

gunicorn "superset.app:create_app()" -k "geventwebsocket.gunicorn.workers.GeventWebSocketWorker" -b 127.0.0.1:8088 --reload

你可以将任何内容记录到浏览器控制台,包括对象:

from superset import app
app.logger.error('An exception occurred!')
app.logger.info(form_data)

前端

前端资源(TypeScript、JavaScript、CSS 和 images)必须被编译才能正确显示 Web UI。 superset-frontend 目录包含了所有由 NPM 管理的前端资源。 请注意,对于某些遗留页面,还有额外的前端资源与 Flask-Appbuilder 捆绑在一起(例如 jQuery 和 bootstrap)。 这些资源不由 NPM 管理,未来可能会逐步淘汰。

前提条件

nvm 和 node

首先,确保你使用的是以下版本的 Node.js 和 npm:

  • Node.js: 版本 18
  • npm: 版本 10

我们推荐使用 nvm 来管理你的 node 环境:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.0/install.sh | bash

in case it shows '-bash: nvm: command not found'
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion

cd superset-frontend
nvm install --lts
nvm use --lts

或者,如果你使用的是 macOS Catalina 及更高版本的默认 shell zsh,可以尝试:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.0/install.sh)"

对于感兴趣的人来说,你也可以尝试使用 avn 来自动切换到运行 Superset 前端所需的 node 版本。

安装依赖

通过以下命令安装 package.json 中列出的第三方依赖:

# 从仓库的根目录
cd superset-frontend

# 安装 `package-lock.json` 中的依赖项
npm ci

请注意,Superset 使用 Scarf 来捕获关于安装版本的遥测/分析数据,包括 scarf-js npm 包和分析像素。如本文档其他地方所述,Scarf 收集聚合统计信息以利于安全/发布策略,不会捕获/保留 PII。你可以在这里阅读关于 scarf-js 包的详细信息,以及各种退出方式,但你可以通过将 SCARF_ANALYTICS 环境变量设置为 false 来退出 npm 包 分析像素,或者通过在 superset-frontent/package.json 中添加以下设置来退出分析像素:

// your-package/package.json
{
// ...
"scarfSettings": {
"enabled": false
}
// ...
}

构建资源

你可以构建三种类型的资源:

  1. npm run build: 生产资源,CSS/JSS 已 minified 并 optimized
  2. npm run dev-server: 本地开发资源,带有源映射(sourcemaps)和热刷新支持
  3. npm run build-instrumented: 用于从 Cypress 测试收集代码覆盖率的 instrumented 后的应用程序代码

如果在使用上述命令时遇到与文件监视器限制相关的错误:

Error: ENOSPC: System limit for number of file watchers reached

这个错误是因为系统监视的文件数量达到了限制。 你可以通过增加 inotify 观察者的数量来解决这个错误。

当前的最大监视文件数可以通过以下命令查看:

cat /proc/sys/fs/inotify/max_user_watches

编辑文件 /etc/sysctl.conf 来增加这个值。 这个值需要根据系统内存来决定 (更多信息请参阅这个 StackOverflow 回答)

在编辑器中打开文件,在底部添加一行指定最大监视文件数的值:

fs.inotify.max_user_watches=524288

保存文件并退出编辑器。 为了确认更改成功,运行以下命令来从 sysctl.conf 加载更新后的 max_user_watches 值:

sudo sysctl -p

Webpack dev server

开发服务器默认启动于 http://localhost:9000 并将 后端请求代理到 http://localhost:8088

因此,典型的开发工作流程如下:

  1. 使用 Flask 在本地运行 Superset, 端口为 8088 — 但不要直接访问它,

    # Install Superset and dependencies, plus load your virtual environment first, as detailed above.
    superset run -p 8088 --with-threads --reload --debugger --debug
  2. 同时,在端口 9000 上本地运行 Webpack 开发服务器,

    npm run dev-server
  3. 在你的浏览器中访问 http://localhost:9000(Webpack server,不是 Flask)。这样会使用来自 Webpack 开发服务器的热重载前端资源,并将后端查询重定向到 Flask/Superset:你对 Superset 代码库的更改 — 无论是前端还是后端 — 都将在浏览器中实时反映出来。

可以更改 Webpack 服务器设置:

# 启动开发服务器至 `http://localhost:9000`
npm run dev-server

# 在非默认端口上运行开发服务器
npm run dev-server -- --port=9001

# 将后端请求代理到运行在非默认端口上的 Flask 服务器
npm run dev-server -- --env=--supersetPort=8081

# 将请求代理到远程后端但提供本地资源
npm run dev-server -- --env=--superset=https://superset-dev.example.com

--superset= 选项在你需要调试生产环境问题或需要在防火墙后面设置 Superset 时很有用。 它允许你在另一个环境中运行 Flask 服务器,同时保持本地构建资产,以获得最佳的开发者体验。

其他 npm 命令

另外,还有一些其他的 NPM 命令你可能会发现有用:

  1. npm run build-dev:在开发模式下构建资源。
  2. npm run dev:在监视模式下构建开发资源,当文件发生变化时会自动重建。

Docker (docker compose)

请参阅文档 这里

更新 NPM 包

按照规定的方式使用 npm,确保 superset-frontend/package-lock.json 根据 npm 推荐的最佳实践进行更新。

功能标志

Superset 支持一个服务器范围的 feature flag 系统,这有助于逐步开发新功能。 要添加一个新的功能标志,只需在 superset_config.py 中进行如下修改:

FEATURE_FLAGS = {
'SCOPED_FILTER': True,
}

如果你想在客户端代码中使用相同的标志,还需将其添加到 @superset-ui/core 中的 FeatureFlag TypeScript 枚举。例如,

export enum FeatureFlag {
SCOPED_FILTER = "SCOPED_FILTER",
}

superset/config.py 包含 DEFAULT_FEATURE_FLAGS, 它会被 superset_config.py 中指定的 FEATURE_FLAGS 覆盖。 例如,在 superset/config.py 中有 DEFAULT_FEATURE_FLAGS = { 'FOO': True, 'BAR': False }, 而在 superset_config.py 中有 FEATURE_FLAGS = { 'BAR': True, 'BAZ': True }, 那么最终合并后的功能标志将是 { 'FOO': True, 'BAR': True, 'BAZ': True }

每个标志的可用状态(稳定版 vs 测试版等)可以在 RESOURCES/FEATURE_FLAGS.md 中找到。

Git Hooks

Superset 使用 Git 预提交钩子, 这得益于 pre-commit。要安装,请运行以下命令:

pip3 install -r requirements/development.txt
pre-commit install

当你进行 Git 提交时,一系列检查现在将会运行。

或者,也可以通过 tox 运行 pre-commit:

tox -e pre-commit

或者手动运行 pre-commit:

pre-commit run --all-files

代码检查

Python

我们使用 Pylint 进行代码检查,可以通过以下方式调用:

# for python
tox -e pylint

关于最佳实践,请避免全局禁用 Pylint 消息(通过 .pylintrc 文件)或在文件头部顶层禁用, 尽管存在一些例外情况。禁用应该在 inline 内进行,因为这样做可以防止掩盖问题, 并且能够提供禁用某条消息的原因上下文。

此外,Python 代码使用 Black 自动格式化, 它被配置为预提交钩子。 还有许多 编辑器集成

TypeScript

cd superset-frontend
npm ci
# 运行 eslint 代码检查
npm run eslint -- .
# 运行 tsc (typescript) 代码检查
npm run type

如果你在使用 vscode 的 eslint 扩展,请在你的工作区 settings.json 文件中加入以下内容:

"eslint.workingDirectories": [
"superset-frontend"
]

测试

Python 测试

所有 Python 测试都在 tox 中执行,这是一个标准化的测试框架。 所有 Python 测试都可以通过 tox 的任何 environments 运行,例如,

tox -e <environment>

例如,

tox -e py38

或者,你可以通过以下命令运行单个文件中的所有测试:

tox -e <environment> -- tests/test_file.py

或者针对特定测试运行:

tox -e <environment> -- tests/test_file.py::TestClassName::test_method_name

请注意,测试环境使用临时目录定义 SQLite 数据库,每次调用测试命令组之前都会清除这些数据库。

Superset 代码库中还包含了一个实用脚本来运行 Python 集成测试。 README 可以在这里找到

例如,要运行所有集成测试,请从根目录运行此脚本:

scripts/tests/run.sh

你还可以使用 pytest 运行位于 './tests/unit_tests' 中的单元测试。 这是一种简单的运行不需要任何数据库设置的独立测试的方法。

pytest ./link_to_test.py

前端测试

我们使用 JestEnzyme 来测试 TypeScript/JavaScript。测试可以通过以下命令运行:

cd superset-frontend
npm run test

要运行单一测试文件:

npm run test -- path/to/file.js

集成测试

我们使用 Cypress 进行集成测试。测试可以通过 tox -e cypress 运行。要打开 Cypress 并探索测试,请首先设置并运行测试服务器:

export SUPERSET_CONFIG=tests.integration_tests.superset_test_config
export SUPERSET_TESTENV=true
export CYPRESS_BASE_URL="http://localhost:8081"
superset db upgrade
superset load_test_users
superset load-examples --load-test-data
superset init
superset run --port 8081

运行 Cypress 测试:

cd superset-frontend
npm run build-instrumented

cd cypress-base
npm install

# 通过无头 Chrome 浏览器运行测试(需要 Chrome 64+ 版本)
npm run cypress-run-chrome

# 从特定文件运行测试
npm run cypress-run-chrome -- --spec cypress/e2e/explore/link.test.ts

# 以视频捕获方式运行特定文件
npm run cypress-run-chrome -- --spec cypress/e2e/dashboard/index.test.js --config video=true

# 打开 Cypress UI
npm run cypress-debug

# 要让 Cypress 指向除默认 URL (http://localhost:8088) 之外的其他 URL,请在运行脚本前设置环境变量
# 例如,CYPRESS_BASE_URL="http://localhost:9000"
CYPRESS_BASE_URL=<your url> npm run cypress open

请参阅 superset-frontend/cypress_build.sh

作为替代方案,你可以使用 docker compose 环境进行测试:

请确保你已在你的 /etc/hosts 文件中添加了以下行: 127.0.0.1 db

如果你已经启动了 Docker 环境,请使用以下命令确保有一个全新的数据库实例: docker compose down -v

启动环境:

CYPRESS_CONFIG=true docker compose up

它将在端口 8088 上提供后端和前端服务。

运行 Cypress 测试:

cd cypress-base
npm install
npm run cypress open

调试 Server App

本地

对于使用 VSCode 在本地进行调试,你可以配置一个启动配置文件 .vscode/launch.json 如下:

{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "superset",
"SUPERSET_ENV": "development"
},
"args": ["run", "-p 8088", "--with-threads", "--reload", "--debugger"],
"jinja": true,
"justMyCode": true
}
]
}

原始 Docker(不使用 docker-compose)

按照以下步骤来调试运行在 Docker 容器内的 Flask 应用。注意, 这将运行一个基本的 Superset web server,

首先,在 ./docker-compose.yaml 文件中添加以下内容:

superset:
env_file: docker/.env
image: *superset-image
container_name: superset_app
command: ["/app/docker/docker-bootstrap.sh", "app"]
restart: unless-stopped
+ cap_add:
+ - SYS_PTRACE
ports:
- 8088:8088
+ - 5678:5678
user: "root"
depends_on: *superset-depends-on
volumes: *superset-volumes
environment:
CYPRESS_CONFIG: "${CYPRESS_CONFIG}"

启动 Superset 如常

docker compose up

在 Docker 容器中安装所需的库和包

进入 superset_app 容器

docker exec -it superset_app /bin/bash
root@39ce8cf9d6ab:/app#

在容器内部运行以下命令

apt update
apt install -y gdb
apt install -y net-tools
pip install debugpy

找到 Flask 进程的 PID。确保使用第一个 PID。 Flask app 每次你更改任何 Python 代码时都会重新生成一个子进程。 所以使用第一个 PID 很重要。

ps -ef

UID PID PPID C STIME TTY TIME CMD
root 1 0 0 14:09 ? 00:00:00 bash /app/docker/docker-bootstrap.sh app
root 6 1 4 14:09 ? 00:00:04 /usr/local/bin/python /usr/bin/flask run -p 8088 --with-threads --reload --debugger --host=0.0.0.0
root 10 6 7 14:09 ? 00:00:07 /usr/local/bin/python /usr/bin/flask run -p 8088 --with-threads --reload --debugger --host=0.0.0.0

将 debugpy 注入到正在运行的 Flask 进程中。在这个例子中 PID 为 6。

python3 -m debugpy --listen 0.0.0.0:5678 --pid 6

验证 debugpy 是否正在监听端口 5678

netstat -tunap

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:5678 0.0.0.0:* LISTEN 462/python
tcp 0 0 0.0.0.0:8088 0.0.0.0:* LISTEN 6/python

你现在可以将调试器附加到进程中。使用 VSCode,你可以配置一个启动配置文件 .vscode/launch.json 如下:

{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Superset App in Docker Container",
"type": "python",
"request": "attach",
"connect": {
"host": "127.0.0.1",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
]
}
]
}

VSCode 不会立即在断点处停止。我们已附加到 PID 6,但它还不知道任何子进程。 为了 “唤醒” debugger,你需要修改一个 Python 文件。 这将触发 Flask 重新加载代码并创建一个新的子进程。 这个新的子进程将被 VSCode 检测到,断点将被激活。

在 Kubernetes 环境中调试 Server App

要在 Kubernetes 集群内的 POD 中调试运行的 Flask, 你需要确保 POD 以 root 用户身份运行并且被授予 SYS_TRACE 能力。 这些设置不应该用于生产环境。

  securityContext:
capabilities:
add: ["SYS_PTRACE"]

请参见 为容器设置能力 获取更多详细信息。

一旦 POD 以 root 用户身份运行并且具有 SYS_PTRACE 能力,它将能够调试 Flask 应用。

你可以遵循与 docker-compose 相同的指令。 进入 POD 并安装所需的库和包;gdb、netstat 和 debugpy。

通常在 Kubernetes 环境中,节点无法从集群外部访问。 因此 VSCode 无法远程连接到 Kubernetes 节点上的端口 5678。 为了实现这一点,你需要创建一个隧道,将 5678 端口转发到你的本地机器。

kubectl port-forward  pod/superset-<some random id> 5678:5678

你现在可以使用与上面相同的配置启动你的 VSCode debugger。VSCode 将连接到 127.0.0.1:5678,该端口由 kubectl 转发到你的远程 Kubernetes POD。

Storybook

Superset 包含一个 Storybook, 用于预览各种 Superset 组件及其变体的布局/样式。要打开并查看 Storybook:

cd superset-frontend
npm run storybook

当向 Superset 贡献新的 React 组件时,请尝试在组件的 jsx/tsx 文件旁边添加一个 Story。

Tips

添加新的数据源

  1. 创建数据源的模型(Model)和视图(View),并将它们添加到 superset 文件夹下, 例如一个新的 my_models.py 文件, 其中包含 cluster、datasources、columns 和 metrics 的模型, 以及 my_views.py 文件, 其中包含 clustermodelview 和 datasourcemodelview。

  2. 为新模型创建数据库迁移文件。

  3. config.py 中指定变量,以添加数据源模型及其所属模块:

    For example:

    ADDITIONAL_MODULE_DS_MAP = {'superset.my_models': ['MyDatasource', 'MyOtherDatasource']}

    这意味着它将在 source registry 中注册 MyDatasourceMyOtherDatasource,这两个模型位于 superset.my_models 模块中。

可视化插件

有关编写新插件的主题,无论你是否希望将其贡献回来, 已经在 文档这篇博客文章 中进行了详细的记录。

要向 Superset 贡献一个插件,你的插件必须满足以下标准:

  • 插件应适用于广大社区,而不是特别专业化的使用场景。
  • 插件应使用 TypeScript 编写。
  • 插件应包含足够的 unit/e2e 测试。
  • 插件应使用适当的命名空间,例如文件夹名为 plugin-chart-whatever,包名为 @superset-ui/plugin-chart-whatever
  • 插件应通过 Emotion 使用主题变量,这些变量由 ThemeProvider 传递。
  • 插件应提供充分的错误处理(未返回数据、数据格式错误、无效的控件等)。
  • 插件应包含形式为填充的 README.md 文件的文档。
  • 插件应具有有意义且独特的图标。
  • 最重要的是,插件应附带原始作者(们)的 维护承诺

提交将根据具体情况考虑接受(或移除)。

添加数据库迁移

  1. 修改你想更改的模型。这个示例将向 Column Annotations 模型添加一个字段。

    Example commit

  2. 生成迁移文件

    superset db migrate -m 'add_metadata_column_to_annotation_model'

    这将在 migrations/version/{SHA}_this_will_be_in_the_migration_filename.py 中生成一个文件。

    Example commit

  3. 升级数据库

    superset db upgrade

    输出应该如下所示:

    INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
    INFO [alembic.runtime.migration] Will assume transactional DDL.
    INFO [alembic.runtime.migration] Running upgrade 1a1d627ebd8e -> 40a0a483dd12, add_metadata_column_to_annotation_model.py
  4. 向视图添加字段

    由于有了新字段,我们需要将其添加到 AppBuilder Model 视图中。

    Example commit

  5. 测试迁移的 down 方法

    superset db downgrade

    输出应该如下所示:

    INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
    INFO [alembic.runtime.migration] Will assume transactional DDL.
    INFO [alembic.runtime.migration] Running downgrade 40a0a483dd12 -> 1a1d627ebd8e, add_metadata_column_to_annotation_model.py

合并数据库迁移

当两个数据库迁移发生冲突时,你会收到这样的错误消息:

alembic.util.exc.CommandError: Multiple head revisions are present for
given argument 'head'; please specify a specific target
revision, '<branchname>@head' to narrow to a specific head,
or 'heads' for all heads`

要解决这个问题:

  1. 获取迁移的头部

    superset db heads

    这应该列出两个或更多的迁移哈希值。例如:

    1412ec1e5a7b (head)
    67da9ef1ef9c (head)
  2. 选择其中一个作为父修订版本,打开另一个修订版本的脚本, 并更新 Revisesdown_revision 到新的父修订版本。例如:

    --- a/67da9ef1ef9c_add_hide_left_bar_to_tabstate.py
    +++ b/67da9ef1ef9c_add_hide_left_bar_to_tabstate.py
    @@ -17,14 +17,14 @@
    """add hide_left_bar to tabstate

    Revision ID: 67da9ef1ef9c
    -Revises: c501b7c653a3
    +Revises: 1412ec1e5a7b
    Create Date: 2021-02-22 11:22:10.156942

    """

    # revision identifiers, used by Alembic.
    revision = "67da9ef1ef9c"
    -down_revision = "c501b7c653a3"
    +down_revision = "1412ec1e5a7b"

    import sqlalchemy as sa
    from alembic import op

    或者,你也可以运行 superset db merge 来创建一个仅用于合并头部的迁移脚本。

    superset db merge {HASH1} {HASH2}
  3. 升级数据库到新的检查点

    superset db upgrade