- 数据分析
- CLI
- 数据可视化
【免费下载链接】visidata
A terminal spreadsheet multitool for discovering and arranging data
vdsql 是 VisiData 生态中的数据库查询接口,它把 VisiData 的表格交互范式映射到 SQL 数据库之上,让用户通过按键组合即可完成过滤、排序、聚合与联表查询,而不必手写 SQL。本文以 visidata/apps/vdsql/CHANGELOG.md 的版本记录为主线,结合 vdsql README 与 核心实现 _ibis.py,完整梳理 vdsql 0.1 到 0.2 的功能演进、后端支持、可配置选项、命令行为以及已知限制,帮助读者快速判断 vdsql 是否适合自己的数据库查询场景,并掌握其正确使用姿势。
vdsql 是什么
vdsql 是一个独立的 VisiData 应用(位于 visidata/apps/vdsql),本质是"面向数据库的 VisiData 界面"。它由 Python 查询表达式框架Ibis驱动:用户在 VisiData 中通过命令组合出的每一个操作,都会被翻译成 Ibis 表达式,最终由 Ibis 编译为对应后端(SQLite、PostgreSQL、DuckDB、ClickHouse、BigQuery 等)的 SQL 并执行。
其核心能力可以概括为三点(见 README 的 Features 一节):
- 从任何受支持的后端把数据查询进 VisiData;
- 用 VisiData 命令组合复杂查询,替代手写 SQL;
- 把当前查询结果输出为 SQL、Substrait 或 Python 表达式。
vdsql 独立打包为 PyPI 包(pip install vdsql),安装后同时提供两个入口:常规的vd -f vdsql(以插件形式加载),以及行为与vd完全一致但默认走 Ibis 加载器的vdsql脚本(见 setup.py 的 entry_points 与 scripts 声明)。其版本号定义在about.py 中,当前为0.3dev(即 0.2 之后的开发版)。
版本演进主线
CHANGELOG.md 记录了三个版本的演进:
| 版本 | 发布日期 | 主题 |
|---|---|---|
| 0.1 | 2022-08-08 | 初版:以vdsql文件类型加载 SQLite 与 DuckDB 数据,命令基于 Ibis 表达式实现 |
| 0.1.1 | 2022-08-08 | 依赖收窄:ibis-framework 依赖仅限 sqlite 和 duckdb |
| 0.2 | 2022-10-12 | 大规模扩展:新增 6 类后端、4 类新选项、3 组新命令,并系统化地标注了未实现功能 |
从 0.2 的说明可以看出,vdsql 在早期迭代中已经"把大多数 VisiData 命令和特性实现了第一遍",以至于维护者认为"列举未实现的东西比列举已实现的更容易"(原文:it's easier to talk about what's not implemented, than what is)。这一判断与代码现状吻合:_ibis.py 单文件承载了连接池、索引表、列映射、表达式编译、频率表、联表等完整逻辑。
后端支持矩阵
0.2 确认并测试的后端
根据 CHANGELOG 0.2 条目,以下后端在 0.2 中"已添加并通过测试":
- BigQuery
- ClickHouse
- MySQL
- PostgreSQL
- DuckDB(
.ddb扩展名) - SQLite(
.sqlite3扩展名) - Snowflake(依赖未发布的 Ibis 版本)
README 的 Supported Backends 与之一致,并进一步说明:SQLite 是默认随包安装的唯一后端;其他后端通过pip install 'ibis-framework[postgres]'这类方式单独安装 Ibis backend 后"自动被支持"。
连接方式与文件扩展名映射
vdsql 的file_or_url可以是ibis.connect()支持的任何连接串,也可以是 VisiData 自身支持的文件类型(见 README Usage):
vdsql foo.sqlite # 或 .sqlite3、.db vdsql foo.duckdb # 或 .ddb vdsql mysql://... vdsql postgres://... vdsql clickhouse://play:clickhouse@play.clickhouse.com/?secure=1 vdsql bigquery:///bigquery-public-data在源码层面,这一映射在 open_vdsql 中完成:本地文件按扩展名改写为duckdb://或sqlite://连接串,再交给IbisConnectionPool惰性建立连接。vdsql脚本运行时还会为db、ddb、duckdb、sqlite、sqlite3等扩展名注册open_*加载器,并把所有 Ibis 后端的openurl_*加载器覆盖为 vdsql 版本(见main.py),仅对 bigquery、clickhouse、snowflake 保留其各自目录下的专用实现(bigquery.py、clickhouse.py、snowflake.py)。
后端专属说明
- PostgreSQL:默认只展示
publicschema 的表;通过--postgres-schema='myschema otherschema'指定多个 schema,或--postgres-schema='*'展示所有非系统 schema(命令行中需对*加引号以免 shell 通配展开,见 README PostgreSQL 节)。该选项在源码中由IbisTableIndexSheet读取,并用于过滤数据库列表(_ibis.py)。 - MySQL:Debian/Ubuntu 上需要
libmysqlclient-dev;若遇时区警告,可执行mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql(README MySQL 节)。 - BigQuery:连接串格式为
bigquery://<billing_project>/<dataset_id>,billing project 作为 netloc、dataset 作为 path(bigquery.py 模块 docstring)。 - ClickHouse:vdsql 为其实现了流式读取与真实行数统计(
ClickhouseSheet.countRows覆盖),并把total_rows_to_read用作进度条总量(clickhouse.py)。 - Snowflake:走 Ibis 的异步查询执行(
execute_async+ 轮询),并提供warehouse初始化属性与查询取消能力(snowflake.py)。
此外,README 列出的Apache Impala、Datafusion、Dask、PySpark、HeavyAI属于"Ibis 支持但 vdsql 未专门测试"的后端,使用前需自行验证。
0.2 新增的选项
CHANGELOG 0.2 的 options 部分 与 README Options 节 共同给出了完整选项清单:
| 选项 | 默认值 | 说明 |
|---|---|---|
sql_always_count | False | 是否在每次查询中附带总行数统计 |
disp_histogram/disp_histolen | 关闭 | 频率表(freq sheet)中的柱状图显示,默认禁用 |
clean_names | True(仅 ibis sheets) | 对列名做清洗规范化 |
load_lazy | True(仅 ibis sheets) | 惰性加载 |
regex_flags | 不忽略大小写 | 正则匹配默认区分大小写 |
ibis_limit | 500 | 单次查询最多抓取的行数 |
postgres_schema | ''(仅 public) | PostgreSQL 展示的 schema 列表 |
disp_ibis_sidebar | pending_sql | 侧边栏展示哪个属性 |
这些选项在源码中均有对应注册点:sql_always_count、ibis_limit、disp_ibis_sidebar在 _ibis.py 顶部通过vd.option(...)注册;postgres_schema、load_lazy、clean_names、regex_flags则分别作为IbisTableIndexSheet/IbisTableSheet的 class_options 设置(_ibis.py)。
sql_always_count的底层行为
开启sql_always_count后,vdsql 会把总行数并入查询结果:withRowcount()将查询与聚合计数做 cross join,产出__n__列(_ibis.py)。iterload中con.execute(..., limit=ibis_limit or None)执行查询(_ibis.py),而countRows属性会优先从结果首行的__n__列取值(_ibis.py)。CHANGELOG 特别提醒:该选项"默认关闭",因为部分后端上统计总行数成本高昂甚至不可行——这也正是 0.2 中"rowcount 默认禁用"的原因。
频率表柱状图(histogram)
0.2 起频率表支持柱状图,但默认关闭,需同时设置:
options.disp_histogram = '█' # 任意字符即可,源码中作为 repeat 的填充字符 options.disp_histolen = 40 # 柱状图长度源码实现位于groupBy():在仅有 count 聚合时,用ibis.literal(histogram_char).repeat(...)在 SQL 层生成柱状图列,柱长按histolen*t['count']/t.maxcount计算(_ibis.py),全程在数据库内完成,不把全量数据拉到本地。
0.2 新增的命令
CHANGELOG 命令部分 记录了四组命令行为变化:
exec-sql
exec-sql让用户直接输入任意 SQL 文本,vdsql 将其作为新查询源打开为名为rawsql的 sheet。实现上,IbisTableSheet.rawSql()调用con.sql(qstr)把原始 SQL 包成 Ibis 表达式(_ibis.py),索引表与表 sheet 都注册了该命令(_ibis.py)。适合对 vdsql 组合不出的复杂 SQL 直接兜底。
dup-limit(z")与dup-nolimit(gz")
这两个命令用于控制"派生子表"的行数上限:
"(dup-selected):基于当前选择与排序,以默认ibis_limit打开新查询;z"(dup-limit):提示输入新的行数上限;gz"(dup-nolimit):去掉上限、抓取全部行(CHANGELOG 与 README 均提示"小心使用")。
实现上,dup_limit()以pending_expr作为新 sheet 的 query,并把options.ibis_limit设为指定值(0 表示不限制),sheet 名追加_topN或_all后缀(_ibis.py)。配套地,dup-selected也是基于pending_expr而非已加载的行数据(_ibis.py),这保证了派生查询仍由数据库引擎完成。
侧边栏键位重构:b/zb/gb
0.2 把侧边栏交互统一收拢到b键族:
b:切换侧边栏开/关(从"循环切换"改为"开关切换");zb:选择侧边栏展示内容(待执行 SQL、基础 SQL 等);gb:把侧边栏内容作为独立 sheet 打开。
侧边栏可展示的属性在源码中定义得很明确(_ibis.py):
| 属性 | 展示内容 |
|---|---|
pending_sql | SQL(待执行,含选择与排序) |
base_sql | SQL(基础查询) |
str_current_expr | 当前 Ibis 表达式 |
str_pending_expr | 待执行 Ibis 表达式 |
curcol_sql | 光标所在列的 SQL 片段 |
pending_sql是sqlize(pending_expr)的结果,而pending_expr依次叠加了当前列、选择过滤(ibis_filter)与排序(_ordering)(_ibis.py)。README 给出的经典工作流是:用 VisiData 命令组合出查询 → 打开 SQL 侧边栏 → 把 SQL 存文件或复制进剪贴板(README Sidebar 节)。调试模式下(options.debug),sqlize还会先withRowcount把行数并入 SQL(_ibis.py),方便核对查询规模。
与普通 VisiData 的行为差异
vdsql 尽量让命令行为与 VisiData 一致,但查询是"延迟编译"的,因此少数键位语义有数据库化改造(README 差异清单):
"(dup-sheet):跑一次新的基础查询,包含新增列、当前选择过滤与当前排序;':把当前列 cast 到给定类型,并持久化到后续查询中(addcol-cast在源码中通过query.mutate(**{col.name: expr})改写查询并隐藏旧列,_ibis.py);g'(freeze-sheet):把已加载的行冻结成普通 VisiData sheet,此后所有 VisiData 命令均可用。
已知限制与未实现命令
不适用于多数后端的三类能力
CHANGELOG 明确列出:
- progress(进度):多数后端无法提供;
- rowcount(行数):默认禁用,部分后端昂贵或不可行;
- task cancellation(任务取消):不支持。
ClickHouse 与 Snowflake 是例外:前者通过流式读取拿到total_rows_to_read支撑进度,后者实现了基于SYSTEM$CANCEL_QUERY的异步取消(见上文后端专属说明),但这两者都不改变整体结论。
未实现(可能未来实现)的命令
CHANGELOG 的 not-implemented 清单 覆盖四类:
- 正则与表达式选择:regex select、select-expr、unselect-expr、select-exact-cell/row、select-rows;
- 列变换:addcol-capture、addcol-incr/incr-step、addcol-window、capture-col、contract-col、expand-col-depth/expand-cols/expand-cols-depth、cache-col/cache-cols;
- 元操作:describe-sheet、melt、freq-summary、random-rows、dive-selected-cells;
- 数据修改(依赖 Ibis 支持):增删行、原地改值;duplicate 类命令(dup-rows、dup-rows-deep、dup-selected-deep)。
这些命令在源码中被显式"禁用":notimpl_cmds、neverimpl_cmds、dml_cmds三组命令名逐一注册到notimpl()处理器,触发时给出警告并提示"用g'复制到新的非 Ibis sheet"(_ibis.py)。其中dml_cmds覆盖了编辑、复制粘贴、删除、setcol 系列等数据变更命令,与 CHANGELOG 中"data modification commands(pending Ibis support)"的说明一致。
永远不会实现的命令
CHANGELOG 明确点名两类:transpose,以及select-after、select-error等不常用选择命令。这些在neverimpl_cmds中同样被绑定到notimpl()(_ibis.py)。
绕过限制的标准姿势
CHANGELOG 给出的通用解法是:先freeze-sheet(g')把当前已加载的行拷贝成一个普通 VisiData sheet,再在该 sheet 上执行任何受限命令。README 补充了重要前提:基础 VisiData 命令只能使用已加载的行(默认 500 行),数据集可能不完整,因此大多数未实现命令被禁用;若明知数据不完整仍要使用,先用g'冻结(README)。
依赖策略与测试覆盖
- 0.1.1 的关键调整:把 ibis-framework 依赖收窄到
sqlite与duckdb两个后端,避免默认安装过重。对应到 requirements.txt 与 requirements-extra.txt:默认依赖为ibis-framework[sqlite]、ibis-substrait、sqlparse、pandas>=1.5.0;额外依赖则追加ibis-framework[duckdb,clickhouse,bigquery] >= 12、psycopg2-binary、duckdb-engine、duckdb。 - 0.2 的依赖提示:加载时若缺少
ibis-framework依赖,vdsql 会给出可读的错误提示(CHANGELOG 第 25 行)。 - 测试:visidata/apps/vdsql/tests 目录中每个
.vdj脚本(如 dup-limit.vdj、select-expr.vdj、freq.vdj)都对应一个 golden 输出,覆盖 dup-limit、正则选择、表达式选择、频率表、toggle 等 0.2 重点功能的回归验证;clickhouse-demo.vdx 则提供了 ClickHouse 后端的演示会话。
小结
从 CHANGELOG.md 的版本记录看,vdsql 在 0.2 已形成稳定的能力边界:七个确认后端、以 Ibis 表达式为核心的命令体系、可组合的 SQL/Ibis/Substrait 侧边栏输出,以及一套显式标注"未实现/永不实现"的受限清单。对于需要"用交互式表格手感查询数据库"的场景,vdsql 提供了一条从按键操作到可复用 SQL 的完整路径;对于需要完整 VisiData 命令集的操作,则记住g'(freeze-sheet)这一逃生通道即可。
- 数据分析
- CLI
- 数据可视化
【免费下载链接】visidata
A terminal spreadsheet multitool for discovering and arranging data
相关推荐
Cilium 项目中的 Sprig 模板函数库:基于 CHANGELOG 的版本演进与函数能力全解析
Cilium 项目中的 Sprig 模板函数库:基于 CHANGELOG 的版本演进与函数能力全解析 导读 本文以 Cilium 仓库内 vendored 依赖
云原生网络服务网格可观测性网络安全eBPFSeaTunnel MySQL CDC 连接器版本演进全解:基于 changelog 与源码的 2.3.0 → 2.3.12 能力地图
SeaTunnel MySQL CDC 连接器版本演进全解:基于 changelog 与源码的 2.3.0 → 2.3.12 能力地图 本文以 SeaTunne
数据集成ETL大数据批处理流处理变更数据捕获Knex 查询构建器版本演进全解析:从 0.1.0 到 3.3.0 的核心能力发展脉络(基于官方 Changelog)
Knex 查询构建器版本演进全解析:从 0.1.0 到 3.3.0 的核心能力发展脉络(基于官方 Changelog) Knex 是一款面向 PostgreSQ
数据库后端关系型数据库
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考