跳到主要内容
版本 下一

设置开发环境

本节中的文档是现有多种运行 Superset 方式(docker compose、仅“docker”、在“裸机”上、使用 Makefile)的知识拼凑而成。

注意

现在,我们已经发展到更积极地推荐和支持 docker compose 作为运行 Superset 进行开发并保持理智的主要方式。大多数人应该坚持前几节——(“Fork & Clone”、“docker compose”和“安装开发工具”)

Fork 和 Clone

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

其次,您可以直接克隆主仓库,但您将无法发送 Pull Request。

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

设置 Superset 的任何部分以输出“hello world”应该像这样简单

# getting docker compose to fire up services, and rebuilding if some docker layers have changed
# using the `--build` suffix may be slower and optional if layers like py dependencies haven't changed
docker compose up --build

请注意

  • 这将拉取/构建 Docker 镜像并运行一个服务集群,包括
    • 一个 Superset Flask Web 服务器,挂载本地 Python 仓库/代码
    • 一个 Superset Celery worker,也挂载本地 Python 仓库/代码
    • 一个 Superset Node 服务,挂载、编译和打包 JS/TS 资产
    • 一个 Superset Node WebSocket 服务,为异步后端提供支持
    • Postgres 作为元数据数据库,并存储应在启动时填充的示例数据集、图表和仪表板
    • Redis 作为异步后端和缓存后端的消息队列
  • 首次启动时,它会将示例加载到数据库中
  • 所有其他详细信息和指针可在 docker-compose.yml 中找到
  • 本地仓库被挂载到服务中,这意味着在主机上更新代码将反映在 Docker 镜像中
  • Superset 在 localhost:9000/ 提供服务
  • 您可以使用 admin/admin 登录
注意

superset-node 中安装和构建 Apache Superset 的 Node 模块可能需要很长时间。由于依赖项的大小,这是正常的。请耐心等待此过程完成,长时间等待并不表示您的设置有问题。如果延迟似乎过长,请检查您的互联网连接或系统资源。

注意

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

支持的环境变量

影响 Docker 构建过程

  • SUPERSET_BUILD_TARGET (默认=dev): 要构建的 --target,leandev 常用
  • INCLUDE_FIREFOX (默认=false): 是否在构建中包含 Firefox 无头浏览器
  • INCLUDE_CHROMIUM (默认=false): 是否在构建中包含 Chromium 无头浏览器
  • BUILD_TRANSLATIONS(默认=false): 是否编译可用的 .po 文件中的翻译
  • SUPERSET_LOAD_EXAMPLES (默认=yes): 是否在启动时将示例加载到数据库中,通过 SUPERSET_LOAD_EXAMPLES=no docker compose up 可以节省宝贵的启动时间
  • SUPERSET_LOG_LEVEL (默认=info): 可以设置为 debug、info、warning、error、critical 以获取更详细的日志记录

有关影响您配置的更多环境变量,请参阅 superset_config.py,该文件在 docker compose 上下文中用于将环境变量分配给 superset 配置。

访问 Postgres 数据库

有时直接访问 Docker 容器中的数据库很有用。您可以通过运行以下命令进入 psql shell(官方 Postgres 客户端)

docker compose exec db psql -U superset

另请注意,数据库暴露在端口 5432 上,因此您可以使用您喜欢的 Postgres 客户端,甚至可以直接在 Superset 中通过创建到 localhost:5432 的新数据库连接来使用 SQL Lab 本身连接到它。

清除 Postgres 数据库

有时,您的开发数据库可能会处于糟糕状态,例如在切换包含迁移的分支时,alembic 管理的数据库版本戳在切换分支后不再可用。

在这种情况下,简单的解决方案是清除 Postgres 数据库并重新开始。请注意,执行此操作后,数据库的完整状态将消失,因此请谨慎。

# first stop docker-compose if it's running
docker-compose down
# delete the volume containing the database
docker volume rm superset_db_home
# restart docker-compose, which will init a fresh database and load examples
docker-compose up

GitHub Codespaces (云开发)

GitHub Codespaces 在云中提供了一个完整、预配置的开发环境。这非常适合

  • 无需本地设置即可快速贡献
  • 团队成员之间一致的开发环境
  • 在无法在本地运行 Docker 的设备上工作
  • 在隔离环境中安全实验
信息

我们感谢 GitHub 提供了这项出色的云开发服务,它使全球开发者更容易为 Apache Superset 做出贡献。

Codespaces 入门

  1. 创建 Codespace:使用此预配置链接,它会设置您所需的一切

    启动 Superset Codespace →

    注意

    重要提示:您必须至少选择 4 CPU / 16GB RAM 机器类型(在上面的链接中已预选)。较小的实例将没有足够的资源来有效运行 Superset。

  2. 等待设置:初始设置需要几分钟。Codespace 将

    • 构建开发容器
    • 安装所有依赖项
    • 启动所有必需的服务(PostgreSQL、Redis 等)
    • 使用示例数据初始化数据库
  3. 访问 Superset:准备就绪后,检查 VS Code 中的 PORTS 选项卡以查找端口 9001。单击地球图标以在浏览器中打开 Superset。

    • 默认凭据:admin / admin

主要功能

  • 自动重新加载:Python 和 TypeScript 文件在保存时都会自动刷新
  • 预装扩展:适用于 Python、TypeScript 和数据库工具的 VS Code 扩展
  • 多个实例:为不同的分支/功能运行多个 Codespace
  • SSH 访问:使用 gh cs ssh 或通过 GitHub Web UI 连接
  • VS Code 集成:与 VS Code 桌面应用程序无缝协作

管理 Codespaces

  • 列出活动 Codespacegh cs list
  • SSH 进入 Codespacegh cs ssh
  • 停止 Codespace:通过 GitHub UI 或 gh cs stop
  • 删除 Codespace:通过 GitHub UI 或 gh cs delete

调试和日志

由于 Codespaces 使用 docker-compose-light.yml,您可以监控所有服务

# Stream logs from all services
docker compose -f docker-compose-light.yml logs -f

# Stream logs from a specific service
docker compose -f docker-compose-light.yml logs -f superset

# View last 100 lines and follow
docker compose -f docker-compose-light.yml logs --tail=100 -f

# List all running services
docker compose -f docker-compose-light.yml ps
提示

Codespaces 会在 30 分钟不活动后自动停止以节省资源。您的工作会得到保留,您可以随时重新启动。

安装开发工具

注意

虽然 docker compose 简化了许多设置,但您仍然需要在本地设置许多东西来支持您的 IDE,以及提交钩子linter测试运行器等。请注意,您可以使用 docker compose exec superset_app bash 等命令在 Docker 镜像中完成这些事情,但许多人喜欢从主机运行这些工具。

Python 环境

假设您已经有设置 Python 环境的方法,例如 pyenvvirtualenv 或其他,您所需要做的就是在安装 OS 依赖项中提到的先决条件后,安装我们的开发、固定 Python 依赖项包。

pip install -r requirements/development.txt

Git 钩子

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

pre-commit install

这将在您的本地仓库中安装钩子。从现在开始,每当您进行 Git 提交时,都会自动运行一系列检查。

手动运行 Pre-commit

您还可以通过多种方式手动运行 pre-commit 检查

  • 在所有文件上运行 pre-commit(与 CI 相同)

    要在仓库中的所有文件上运行 pre-commit 检查,请使用以下命令

    pre-commit run --all-files

    这将与 CI 期间运行的检查集相同,确保您的更改符合项目标准。

  • 在特定文件上运行 pre-commit

    如果您想检查或修复特定文件,可以通过指定文件路径来完成

    pre-commit run --files path/to/your/file.py

    这将仅在您指定的文件上运行检查。

  • 运行特定的 pre-commit 检查

    要在所有文件或特定文件上运行特定检查(钩子),请使用以下命令

    pre-commit run <hook_id> --all-files

    或针对特定文件

    pre-commit run <hook_id> --files path/to/your/file.py

    <hook_id> 替换为您要运行的特定钩子的 ID。您可以在 .pre-commit-config.yaml 文件中找到可用钩子的列表。

使用大型语言模型 (LLM)

环境设置

确保 Docker Compose 在启动 LLM 会话之前正在运行

docker compose up

验证您的环境

curl -f https://:8088/health && echo "✅ Superset ready"

LLM 会话最佳实践

  • 始终首先使用上述健康检查验证环境设置
  • 使用聚焦的验证命令:pre-commit run(而不是 --all-files
  • 首先阅读 LLMS.md - 包含全面的开发指南、编码标准和关键重构信息
  • 检查特定平台的文件(如果可用)
    • CLAUDE.md - 适用于 Claude/Anthropic 工具
    • CURSOR.md - 适用于 Cursor 编辑器
    • GEMINI.md - 适用于 Google Gemini 工具
    • GPT.md - 适用于 OpenAI/ChatGPT 工具
  • 遵循 TypeScript 迁移指南,并避免 LLMS.md 中列出的已弃用模式

关键开发命令

# Frontend development
cd superset-frontend
npm run dev # Development server on https://:9000
npm run test # Run all tests
npm run test -- filename.test.tsx # Run single test file
npm run lint # Linting and type checking

# Backend validation
pre-commit run mypy # Type checking
pytest # Run all tests
pytest tests/unit_tests/specific_test.py # Run single test file
pytest tests/unit_tests/ # Run all tests in directory

有关详细的开发上下文、环境设置和编码指南,请参阅 LLMS.md

docker compose 的替代方案

注意

本文档的这部分是关于在没有 docker compose 的情况下设置开发环境的信息拼凑而成,并且其文档和支持程度各不相同。维护这一系列广泛的方法并确保它们在各种环境中正常运行一直很困难。

Flask 服务器

操作系统依赖项

在执行这些步骤之前,请确保您的机器满足 操作系统依赖项。您还需要安装 MySQL。

确保您使用的是 Python 3.9、3.10 或 3.11 版本,然后继续

# Create a virtual environment and activate it (recommended)
python3 -m venv venv # setup a python3 virtualenv
source venv/bin/activate

# Install external dependencies
pip install -r requirements/development.txt

# Install Superset in editable (development) mode
pip install -e .

# Initialize the database
superset db upgrade

# Create an admin user in your metadata database (use `admin` as username to be able to load the examples)
superset fab create-admin

# Create default roles and permissions
superset init

# Load some data to play with.
# Note: you MUST have previously created an admin user with the username `admin` for this command to work.
superset load-examples

# Start the Flask dev web server from inside your virtualenv.
# Note that your page may not have CSS at this point.
# See instructions below on how to build the front-end assets.
superset run -p 8088 --with-threads --reload --debugger --debug

或者您可以通过我们的 Makefile 安装它

# Create a virtual environment and activate it (recommended)
$ python3 -m venv venv # setup a python3 virtualenv
$ source venv/bin/activate

# install pip packages + pre-commit
$ make install

# Install superset pip packages and setup env only
$ make superset

# Setup pre-commit only
$ make pre-commit

注意:FLASK_APP 环境变量应该不需要设置,因为它目前通过 .flaskenv 控制,但是,如果需要,它应该设置为 superset.app:create_app()

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

依赖

如果您添加了新要求或更新了现有要求(根据 setup.py 中的 install_requires 部分),则必须重新编译(冻结)Python 依赖项,以确保 CI、测试等的构建是确定性的。这可以通过以下方式实现,

python3 -m venv venv
source venv/bin/activate
python3 -m pip install -r requirements/development.txt
./scripts/uv-pip-compile.sh

升级单个包的版本号时,应运行带 -P 标志的 ./scripts/uv-pip-compile.sh

./scripts/uv-pip-compile.sh -P some-package-to-upgrade

要根据 setup.pyrequirements/*.in 中定义的限制更新所有依赖项,请运行 ./scripts/uv-pip-compile.sh --upgrade

./scripts/uv-pip-compile.sh --upgrade

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

登录到浏览器控制台

此功能仅在 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)

然后确保您使用正确的工作程序类型运行您的 WSGI 服务器

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

前端

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

先决条件

nvm 和 node

首先,请确保您使用以下版本的 Node.js 和 npm

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

我们建议使用 nvm 来管理您的节点环境

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

如果您使用的是从 Catalina 开始的默认 macOS shell zsh,请尝试

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

对于那些感兴趣的人,您也可以尝试 avn 来自动切换到运行 Superset 前端所需的节点版本。

安装依赖项

通过以下方式安装 package.json 中列出的第三方依赖项

# From the root of the repository
cd superset-frontend

# Install dependencies from `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 经过压缩和优化
  2. npm run dev-server:本地开发资产,支持源映射和热刷新
  3. npm run build-instrumented:用于从 Cypress 测试收集代码覆盖率的插桩应用程序代码

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

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

抛出此错误是因为系统监控的文件数量已达到限制。您可以通过增加 inotify 监视器的数量来解决此错误。

可以通过以下方式检查 max watches 的当前值

cat /proc/sys/fs/inotify/max_user_watches

编辑文件 /etc/sysctl.conf 以增加此值。该值需要根据系统内存决定(有关更多上下文,请参阅此 StackOverflow 答案)

在编辑器中打开文件,并在底部添加一行指定 max watches 值。

fs.inotify.max_user_watches=524288

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

sudo sysctl -p

Webpack 开发服务器

开发服务器默认在 https://:9000 启动,并将后端请求代理到 https://: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. 在网络浏览器中访问 https://:9000(Webpack 服务器,不是 Flask)。这将使用 Webpack 开发服务器的热重载前端资产,同时将后端查询重定向到 Flask/Superset:您对 Superset 代码库(无论是前端还是后端)的更改将实时反映在浏览器中。

可以更改 Webpack 服务器设置

# Start the dev server at https://:9000
npm run dev-server

# Run the dev server on a non-default port
npm run dev-server -- --port=9001

# Proxy backend requests to a Flask server running on a non-default port
npm run dev-server -- --env=--supersetPort=8081

# Proxy to a remote backend but serve local assets
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 支持一个服务器范围的功能标志系统,这有助于功能的增量开发。要添加新的功能标志,只需像下面这样修改 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 }

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

Git 钩子

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

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

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

代码规范

请参阅操作方法

GitHub Actions 和 act

提示

Superset 的 GHA 与 act 的兼容性尚未完全测试。在本地运行 act 可能对不同的操作有效或无效,并且可能需要微调和本地秘密处理。对于那些难以在本地运行的更复杂的 GHA,我们建议直接在 GHA 的基础设施上迭代,通过直接推送到分支并监控 GHA 日志。对于更有针对性的迭代,请参阅 GitHub CLI 的 gh workflow run --ref {BRANCH} 子命令。

对于自动化和 CI/CD,Superset 大量使用了 GitHub Actions (GHA)。您可以在 .github/ 文件夹下找到所有工作流和其他资产。这包括

  • 运行后端单元测试套件(tests/
  • 运行前端测试套件(superset-frontend/src/**.*.test.*
  • 运行我们的 Playwright 端到端测试(superset-frontend/playwright/)和旧版 Cypress 测试(superset-frontend/cypress-base/
  • 对代码库进行 linting,包括所有 Python、Typescript 和 Javascript、yaml 等
  • 检查各种其他规则约定

当您打开拉取请求 (PR) 时,相应的 GitHub Actions (GHA) 工作流将根据您分支中的更改自动运行。依赖此自动化是完全合理(也是必需的!)的。然而,缺点是它大多是一种全有或全无的方法,并且没有提供太多控制来定位特定测试或快速迭代。

有时,在本地运行 GHA 工作流可能更方便。为此,我们使用 act,一个允许您在本地运行 GitHub Actions (GHA) 工作流的工具。它模拟 GitHub Actions 环境,使开发人员能够在将更改推送到仓库之前在本地机器上测试和调试工作流。有关如何使用它的更多信息,请参阅下一节。

注意

在 GHA 和 act 中,我们可以运行一个更复杂的测试矩阵,针对不同的数据库引擎(PostgreSQL、MySQL、SQLite)和不同版本的 Python 执行。这使我们能够确保跨各种环境的兼容性和稳定性。

使用 act

首先,安装 act -> https://nektosact.com/

要列出工作流,只需

act --list

运行特定工作流

act pull_request --job {workflow_name} --secret GITHUB_TOKEN=$GITHUB_TOKEN --container-architecture linux/amd64

在上面的例子中,请注意

  • 我们使用 --job 定位特定工作流
  • 我们使用 --secret 传递一个秘密,因为许多作业需要对仓库的读取访问权限(公共)
  • 我们通过将其指定为第一个参数来模拟 pull_request 事件,类似地,我们可以模拟 push 事件或其他事件
  • 我们指定 --container-architecture,它倾向于更可靠地模拟 GHA
注意

act 是一个功能丰富的工具,提供了各种功能,允许您模拟不同的事件(pull_request、push 等),围绕传递所需秘密的语义等等。有关更多信息,请参阅 act 的文档

注意

有些作业需要秘密才能与您可能没有的外部系统和帐户进行交互。在这些情况下,您可能需要依赖远程 CI 或进一步参数化作业,以将目标设置为不同的环境/沙箱或您自己的环境以及相关秘密。


测试

Python 测试

单元测试

对于位于 tests/unit_tests/ 中的单元测试,通常很容易通过以下方式在本地运行脚本

pytest tests/unit_tests/*

集成测试

对于更复杂的 pytest 定义的集成测试(不要与我们的端到端 Cypress 测试混淆),许多测试将需要一个正常工作的测试环境。有些测试需要数据库、Celery 以及可能安装的其他服务或库。

使用 act 运行测试

要使用 act 在本地运行集成测试,请确保您已遵循 GitHub Actions 和 act 部分中的设置说明。您可以运行包含集成测试的特定工作流或作业。例如

act --job test-python-38 --secret GITHUB_TOKEN=$GITHUB_TOKEN --event pull_request --container-architecture linux/amd64

使用测试脚本在本地运行

Superset 代码库中还包含一个实用脚本,用于运行 Python 集成测试。自述文件可在此处找到

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

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

已知问题和解决方法

Jest 测试挂起(MessageChannel 问题)

如果 Jest 测试挂起并显示“Jest did not exit one second after the test run has completed”,这很可能是由于 rc-overflow(Ant Design v5 组件)的 MessageChannel 问题造成的。

根本原因rc-overflow@1.4.1 为响应式溢出检测创建了 MessageChannel 句柄,这些句柄在测试完成后仍保持打开状态。

当前解决方法:在 spec/helpers/jsDomWithFetchAPI.ts 中将 MessageChannel 模拟为 undefined,强制 rc-overflow 使用 requestAnimationFrame 回退。

验证是否仍需要:删除 MessageChannel 模拟行并运行 npm test -- --shard=4/8。如果测试挂起,则仍需要此解决方法。

未来移除条件:此解决方法可在以下情况移除

  • rc-overflow 更新以在测试环境中正确清理 MessagePorts
  • Jest 更新以更好地处理 MessageChannel/MessagePort 清理
  • Ant Design 不再使用 rc-overflow
  • 我们不再使用 Ant Design v5

参见PR #34871 以获取完整的技术细节。

调试服务器应用程序

本地

对于使用 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 服务器。

首先,将以下内容添加到 ./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 --build

将所需的库和包安装到 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。每次更改任何 Python 代码时,Flask 应用程序都会重新生成一个子进程。因此,使用第一个 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,但它尚不知道任何子进程。为了“唤醒”调试器,您需要修改一个 Python 文件。这将触发 Flask 重新加载代码并创建一个新的子进程。VSCode 将检测到这个新的子进程,并且断点将被激活。

在 Kubernetes 环境中调试服务器应用程序

要在 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 调试器。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。

测试 Stories

Superset 使用 @storybook/test-runner 来验证所有故事是否编译和渲染无误。这有助于在故事合并之前捕获损坏的故事。

# Run against a running Storybook server (start with `npm run storybook` first)
npm run test-storybook

# Build static Storybook and test (CI-friendly, no server needed)
npm run test-storybook:ci

test-storybook 作业会在每次拉取请求时自动在 CI 中运行,确保故事保持功能正常。

技巧

添加新的数据源

  1. 为数据源创建模型和视图,将它们添加到 superset 文件夹下,例如一个新的 my_models.py,其中包含集群、数据源、列和指标的模型,以及一个 my_views.py,其中包含 clustermodelview 和 datasourcemodelview。

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

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

    例如

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

    这意味着它将在源注册表中注册 superset.my_models 模块中的 MyDatasource 和 MyOtherDatasource。

可视化插件

关于创作新插件的主题,无论您是否想将其贡献回来,都已在文档这篇博客文章中得到了很好的记录。

要向 Superset 贡献插件,您的插件必须符合以下标准

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

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

添加数据库迁移

  1. 更改您想要更改的模型。此示例将添加一个 Column 注释模型。

    提交示例

  2. 生成迁移文件

    superset db migrate -m 'add_metadata_column_to_annotation_model'

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

    提交示例

  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 模型视图中。

    提交示例

  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