如何把 marimo 接入 MotherDuck 并用 SQL 查询云数据仓库?
【免费下载链接】marimoA reactive notebook for Python — run reproducible experiments, query with SQL, execute as a script, deploy as an app, and version with git. Stored as pure Python. All in a modern, AI-native editor.项目地址: https://gitcode.com/GitHub_Trending/ma/marimo
如果你的数据存放在基于 DuckDB 的云数据仓库 MotherDuck 中,想在 marimo 笔记本里用 SQL 查询它、并把查询结果直接交给 Python 代码处理,操作路径是:安装 marimo 的 SQL 扩展依赖,用ATTACH挂上md:数据库,然后创建 SQL 单元格写查询。完成后,查询结果会作为 Polars 或 Pandas DataFrame 供下游 Python 单元格引用,SQL 的修改会自动触发依赖它的单元格重新计算。以下内容整理自 MotherDuck 集成文档 与 SQL 使用指南。
安装 marimo 与 SQL 依赖
把 MotherDuck 作为数据源,需要先安装marimo[sql]扩展包(含 duckdb 等依赖)。按你的包管理器选择其一:
pip install "marimo[sql]"uv add "marimo[sql]"conda install -c conda-forge marimo duckdb polars其中一点要留意:SQL 查询结果要回到 Python 使用,环境里必须装有polars(结果即为 Polars DataFrame)或pandas(结果为 Pandas DataFrame)二者之一,上面的命令都同时带上了。
安装是否成功可以用文档给出的方式验证——运行下面命令后,一个教程笔记本会在浏览器中打开:
marimo tutorial intro另外官方还提供了 SQL 主题的交互式教程,适合在动手前快速熟悉 SQL 单元格的用法:
marimo tutorial sql认证 MotherDuck:浏览器登录或设置 motherduck_token
首次运行ATTACH单元格时,marimo 会打开一个浏览器窗口,让你登录 MotherDuck 并授权当前笔记本访问你的数据库。每次重新打开笔记本都会再次出现这个提示;要跳过它,可以设置motherduck_token环境变量(集成文档给出的做法):
export motherduck_token="your_token" marimo edityour_token是占位符,替换为你在 MotherDuck 官网设置页创建并复制的 token。官方示例笔记本 connect_to_motherduck.py 会读取motherduck_token或MOTHERDUCK_TOKEN任一环境变量;找不到 token 时,笔记本内会显示一个提示框,其中给出的启动方式是:
motherduck_token="YOUR_TOKEN_HERE" marimo edit <notebook path>这里YOUR_TOKEN_HERE同样是占位符,替换成你自己的 token,<notebook path>替换为你要打开的笔记本路径。如果不想在命令行里携带 token,marimo 默认会加载pyproject.toml旁边的.env文件(见运行时配置文档),把motherduck_token写进.env即可,也便于避免把凭据提交进版本库。
用 ATTACH 连接 MotherDuck 数据库
进入 marimo 编辑器后,连接动作本身就是一条ATTACH语句。两种方式任选:
在 SQL 单元格中运行:
ATTACH IF NOT EXISTS 'md:my_db'my_db是占位符,替换为你自己的 MotherDuck 数据库名。或者在 Python 单元格里直接用 duckdb 执行:
import duckdb # Connect to MotherDuck duckdb.sql("ATTACH IF NOT EXISTS 'md:my_db'")连接成功与否有明确的判断方式:连接后,你的 MotherDuck 表会自动出现在编辑器的 Datasources Panel 中。示例笔记本里还提到,打开左侧边栏的 "Explore data sources" 面板(第 3 个图标),可以看到所有可用表,包括后续新创建的表:
用 SQL 单元格查询 MotherDuck 表
创建 SQL 单元格有三种方式:右键点击单元格旁的 "add cell" 按钮("+" 图标)选择 "SQL cell";通过单元格上下文菜单把空单元格转换为 SQL;或点击笔记本底部出现的 SQL 按钮。
SQL 单元格本质是 Python 代码的语法糖,底层形式是:
output_df = mo.sql(f"SELECT * FROM my_table LIMIT {max_rows.value}")两个要点:
- 变量名就是查询结果的引用名。要让其他 Python 或 SQL 单元格能引用这个结果,变量名不能以下划线开头(带下划线的名字是私有的,外部引用不到)。
- SQL 语句是 f-string,可以用
{}把 Python 值插进查询,因此查询可以依赖 UI 元素或其他 Python 变量的取值,并纳入 marimo 的响应式数据流图。
在 SQL 单元格中对 MotherDuck 的表执行查询,结果就会以 DataFrame 形式显示并可被下游单元格使用:
由于 marimo 的响应式执行模型延伸到 SQL 查询,修改 SQL 会自动触发依赖单元格的下游计算(对于昂贵计算,也可以选择只把单元格标记为 stale)。
官方示例笔记本中有一个可直接运行的查询示例:先ATTACH共享的公开示例库,再查询 Hacker News 表里被分享次数最多的域名。挂载语句(取自示例笔记本原文):
duckdb.sql( "ATTACH 'md:_share/sample_data/23b0d623-1361-421d-ae77-62d701d471e6' AS sample_data" )查询语句:
-- Most shared websites SELECT regexp_extract(url, 'http[s]?://([^/]+)/', 1) AS domain, count(*) AS count FROM sample_data.hn.hacker_news WHERE url IS NOT NULL AND regexp_extract(url, 'http[s]?://([^/]+)/', 1) != '' GROUP BY domain ORDER BY count DESC LIMIT 20;换成自己的库时,把ATTACH指向自己的md:数据库,查询对象相应替换为对应的表即可。
配置查询结果的返回类型
SQL 查询的返回类型可在 marimo 编辑器右上角的应用设置中配置,可选项(来自 SQL 指南):
native:使用 DuckDB 的原生 lazy relation,官方推荐用于大数据集,可避免把整个结果集载入内存,也方便串联多个 SQL 单元格;lazy-polars:返回 lazy Polars DataFrame;polars:返回 eager Polars DataFrame;pandas:返回 Pandas DataFrame;auto:默认值,按已安装的包自动选择(先尝试 polars,再尝试 pandas)。
同时注意:为防止内存问题,UI 默认只显示结果的前 10 行,这是展示层面的限制。
在 Python 中复用查询结果(可选)
示例笔记本展示了典型的"SQL 取数 + Python 加工"路径:mo.sql(...)的结果赋给命名变量后,下游 Python 单元格用 altair 把结果画成图表(altair 已写入笔记本头部的 PEP 723 依赖声明,与 duckdb==1.1.0、polars==1.18.0、pyarrow==18.1.0 并列)。
它同时演示了用 UI 元素参数化 SQL:先从 MotherDuck 表里取出 distinct 类型填入下拉框,再把选中值插进 SQL。示例中的下拉框构造(摘自示例笔记本):
hn_types = duckdb.sql( """ SELECT DISTINCT type as 'HN Type' FROM sample_data.hn.hacker_news WHERE score IS NOT NULL AND descendants IS NOT NULL LIMIT 10; """ ).df() hn_type_select = mo.ui.dropdown.from_series(hn_types["HN Type"], value="story")示例笔记本随后在 SQL 单元格的 f-string 中引用{hn_type_select.value}作为过滤条件。用户在下拉框里换一个类型,SQL 单元格和下游图表就会自动重跑——这就是 SQL 单元格"语法糖"背后 f-string 插值带来的响应式效果。
按需调整数据源自动发现
marimo 会自动发现数据库连接,并在 Data Sources panel 中展示数据库、schema、表和列,方便你浏览结构并把表名、列名拉进 SQL 查询。但默认配置下可能只发现数据库、不深入发现表和列(官方说明是为了避免大型数据库的性能问题)。行为可以在pyproject.toml中调整:
[tool.marimo.datasources] auto_discover_schemas = "auto" # Default: "auto" auto_discover_tables = "auto" # Default: "auto" auto_discover_columns = false # Default: false三个选项都取true、false或"auto";"auto"按数据库类型判断——内省代价低的数据库(如 SQLite、Postgres、MySQL)会被发现,数据仓库(如 Snowflake、BigQuery)则不会。SQL 单元格自动补全依赖这项发现:如果 schema 没被发现,可以在 Data Sources panel 里手动展开你要的 schema 和表来注册补全语义,或修改上述配置。同一组设置也可以在笔记本设置菜单(齿轮图标)的Packages & Data里修改。
完整示例与继续学习
完整的端到端示例见 examples/sql/connect_to_motherduck.py:包含 token 检测与提示、ATTACH共享示例库、多个 SQL 查询、altair 图表以及参数化过滤的响应式流程。集成文档建议用marimo edit <notebook-url>直接打开该笔记本;仓库内的同一文件也可以用marimo edit打开本地路径运行,需要自行装好笔记本头部声明的依赖。examples/sql/README.md 还给出一条可选路径:装好 uv 后用uvx marimo edit --sandbox <notebook-url>打开示例,--sandbox会在隔离的虚拟环境里自动安装笔记本依赖(<notebook-url>替换为要打开的笔记本地址)。
几个执行时的边界,均来自源文档:
- 查询结果要在 Python 中使用,必须装有 polars 或 pandas 之一;
- UI 默认只展示查询结果的前 10 行;
- 数据仓库类数据源在
"auto"发现模式下可能不会被自动展开表和列,补全依赖手动展开或上面的配置调整。
【免费下载链接】marimoA reactive notebook for Python — run reproducible experiments, query with SQL, execute as a script, deploy as an app, and version with git. Stored as pure Python. All in a modern, AI-native editor.项目地址: https://gitcode.com/GitHub_Trending/ma/marimo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考