☰
vdsql 版本演进与能力全景:基于 Ibis 的 VisiData 数据库查询接口
2026/9/25 14:23:53 网站建设 项目流程
  • 数据分析
  • CLI
  • 数据可视化

【免费下载链接】visidata

A terminal spreadsheet multitool for discovering and arranging data

项目地址:https://gitcode.com/gh_mirrors/vi/visidata
点击查看免费下载

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.12022-08-08初版:以vdsql文件类型加载 SQLite 与 DuckDB 数据,命令基于 Ibis 表达式实现
0.1.12022-08-08依赖收窄:ibis-framework 依赖仅限 sqlite 和 duckdb
0.22022-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_countFalse是否在每次查询中附带总行数统计
disp_histogram/disp_histolen关闭频率表(freq sheet)中的柱状图显示,默认禁用
clean_namesTrue(仅 ibis sheets)对列名做清洗规范化
load_lazyTrue(仅 ibis sheets)惰性加载
regex_flags不忽略大小写正则匹配默认区分大小写
ibis_limit500单次查询最多抓取的行数
postgres_schema''(仅 public)PostgreSQL 展示的 schema 列表
disp_ibis_sidebarpending_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_sqlSQL(待执行,含选择与排序)
base_sqlSQL(基础查询)
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

项目地址:https://gitcode.com/gh_mirrors/vi/visidata
点击查看免费下载

相关推荐

上一篇:快速上手抖音无水印下载:douyin-downloader 单条、批量与直播下载教程
下一篇:Chaldea:FGO玩家的全能战斗模拟器与养成规划神器

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询