☰
Polars SQL 之 SHOW TABLES:列出 SQLContext 中已注册的 DataFrame 表
2026/10/10 9:40:18 网站建设 项目流程

Polars SQL 之 SHOW TABLES:列出 SQLContext 中已注册的 DataFrame 表

【免费下载链接】polarsExtremely fast Query Engine for DataFrames, written in Rust项目地址: https://gitcode.com/GitHub_Trending/po/polars

SHOW TABLES是 Polars 内嵌 SQL 方言中用于列出当前SQLContext中所有已注册表的语句。在 Python 侧,每当通过pl.SQLContext(表名=DataFrame)或ctx.register(...)将一张DataFrame/LazyFrame注册为"表"后,它就能在后续 SQL 语句中被引用;SHOW TABLES则负责把这些已注册表的名字一次性列举出来,方便你核对当前会话里到底"有哪些表可用"。读完本文,你将掌握SHOW TABLES的语法、返回结果的结构与排序规则、其底层实现原理,以及如何用它排查表注册与作用域问题。

SHOW TABLES 语句概述

在 Polars 中,SQL 并非独立的数据库引擎,而是统一由SQLContext对象托管。SQLContext内部维护着一个"表名 → 数据集"的映射,用于在 SQL 语句中把标识符解析为实际的数据帧。

SHOW TABLES语句的语法非常简单:

SHOW TABLES

它不带任何参数、子句或分号外的扩展,语义等价于"把我(当前SQLContext)注册过的所有表名列出来"。

  • 官方入门文档可见 docs/source/user-guide/sql/intro.md,其中介绍了SQLContext的初始化与多种表注册方式;
  • 本文所讲解的SHOW TABLES原始文档位于 docs/source/user-guide/sql/show.md。

一个完整的 Python 示例

Polars 用户指南中给出的完整示例如下(对应源码见 docs/source/src/python/user-guide/sql/show.py):

import polars as pl # 创建一些 DataFrame,并注册到 SQLContext df1 = pl.LazyFrame( { "name": ["Alice", "Bob", "Charlie", "David"], "age": [25, 30, 35, 40], } ) df2 = pl.LazyFrame( { "name": ["Ellen", "Frank", "Gina", "Henry"], "age": [45, 50, 55, 60], } ) ctx = pl.SQLContext(mytable1=df1, mytable2=df2) tables = ctx.execute("SHOW TABLES", eager=True) print(tables)

示例逐步拆解

  1. 构造数据帧:这里使用pl.LazyFrame创建了两份name+age的测试数据。SQLContext对注册为表的输入并无"必须懒执行"的限制,示例选择LazyFrame只是 Polars 的惯例用法。
  2. 批量注册:pl.SQLContext(mytable1=df1, mytable2=df2)在构造SQLContext的同时,通过关键字参数把df1、df2分别以mytable1、mytable2的名字注册成两张表。
  3. 执行 SHOW TABLES:调用ctx.execute("SHOW TABLES", eager=True)执行语句。与普通查询一致,execute默认返回一个LazyFrame,传入eager=True后会立刻物化收集为DataFrame以便直接print。

输出结果

上述脚本的运行结果为一个只含单列(列名为name)的DataFrame:

shape: (2, 1) ┌──────────┐ │ name │ │ --- │ │ str │ ╞══════════╡ │ mytable1 │ │ mytable2 │ └──────────┘
  • 每一行对应一张已注册的表;
  • 唯一的name列即注册时使用的表名;
  • 从返回结构看,SHOW TABLES结果本身也是一张普通DataFrame,因此你仍然可以对它做筛选、排序、SELECT等后续处理。

语义边界:只列出"当前 SQLContext"中的表

SHOW TABLES最容易被忽略的一点是它的作用域限定:

  • 它只列出注册在当前SQLContext对象中的表;
  • 如果你把一张DataFrame注册到了另一个SQLContext,或是在另一个 Python 会话里注册,它不会出现在这里返回的结果中;
  • 已通过ctx.unregister(...)移除的表同样不会出现。

每个SQLContext是一份独立的状态。多会话、多上下文并存时,务必对"哪个 context 里有哪张表"保持清醒,否则很容易出现"SQL 查询报找不到表"但SHOW TABLES里却看不到对应名字的情况——此时应回到注册它的那个SQLContext去检查。

底层实现原理(源码级)

语句分发与执行

SQLContext是 Polars SQL 能力的核心类型,其实现位于 crates/polars-sql/src/context.rs。SQL 语句解析完成后,会进入统一的分发入口execute_statement,其中对Statement::ShowTables的专门分支为:

stmt @ Statement::ShowTables { .. } => self.execute_show_tables(stmt)?,

真正的execute_show_tables实现相当精简(见 crates/polars-sql/src/context.rs#L921-L926):

// SHOW TABLES fn execute_show_tables(&mut self, _: &Statement) -> PolarsResult<LazyFrame> { let tables = Column::new("name".into(), self.get_tables()); let df = DataFrame::new_infer_height(vec![tables])?; Ok(df.lazy()) }

从源码结构看,这里与文档描述完全一致:

  1. 调用self.get_tables()取回全部已注册表名;
  2. 把它们放进一个名为name的Column,构造单列DataFrame;
  3. 包装成LazyFrame返回(与execute的返回约定统一)。

另外,SHOW关键字需要在 SQL 解析阶段被识别,crates/polars-sql/src/keywords.rs中将keywords::SHOW纳入了支持的保留字集合,最终由 polars-sql 依赖的 SQL 解析器把裸的SHOW TABLES解析为上述ShowTables语句节点。

表从哪里来:table_map 与 get_tables

SQLContext内部用一张并发安全的映射保存所有注册表(见 crates/polars-sql/src/context.rs#L220):

pub(crate) table_map: Arc<RwLock<PlHashMap<String, LazyFrame>>>,
  • register(name, lf):向table_map写入name -> lf条目(crates/polars-sql/src/context.rs#L289-L291);
  • unregister(name):从table_map中移除条目(crates/polars-sql/src/context.rs#L294-L296);
  • get_tables():取出全部键并按字典序排序后返回(crates/polars-sql/src/context.rs#L268-L272):
pub fn get_tables(&self) -> Vec<String> { let mut tables = Vec::from_iter(self.table_map.read().unwrap().keys().cloned()); tables.sort_unstable(); tables }

因此**SHOW TABLES返回的结果并非插入顺序,而是按表名的字典序(升序)排列**。文档示例里mytable1排在mytable2之前,既是注册先后、也恰巧符合字典序;如果你注册b_table与a_table,返回时a_table会排在前面。

值得注意的是:SQLContext内部还维护了 CTE 映射(cte_map)、表别名等其它状态,但它们并不属于通过register建立的table_map,因此不会被SHOW TABLES列出来。可以推断,SHOW TABLES呈现的是"会话级、可持久引用"的注册表集合,而非某条查询内部的临时可见名字。

Python 侧的配套 API

Python 的SQLContext只是对 Rust 实现的封装(见 crates/polars-python/src/sql.rs),与之配套的常用方法有:

方法说明
ctx.execute(query, eager=False)执行 SQL 语句,默认返回LazyFrame,eager=True时收集为DataFrame
ctx.get_tables()直接以 Python 列表形式返回当前注册表名(等价于SHOW TABLES的数据来源)
ctx.register(name, frame)用指定名字注册一张DataFrame/LazyFrame为表
ctx.unregister(name)从当前 context 注销一张表
# 用 register / unregister 动态管理表 ctx.register("mytable3", df2) print(ctx.get_tables()) # ['mytable1', 'mytable2', 'mytable3'] ctx.unregister("mytable3") print(ctx.get_tables()) # ['mytable1', 'mytable2']

在日常排错时,ctx.get_tables()与SHOW TABLES读到的是同一份table_map数据,可以互为印证:比如怀疑某张表没注册成功,先在SHOW TABLES里确认表名是否存在,再排查注册代码。

常见的实用排查场景

  1. 确认表名拼写:执行SELECT * FROM mytable1报找不到表时,先跑SHOW TABLES核对实际表名是否多了空格、大小写或拼写错误。注意 Polars 的表名解析会忽略大小写(从relation_in_scope、get_ignoring_case等逻辑可以看出),但表名本身以注册时的字符串为准。
  2. 确认作用域:多个SQLContext并存时,用SHOW TABLES分别查询每个 context,快速定位表注册在哪个会话。
  3. 结合 DROP 语句管理生命周期:Polars SQL 还支持DROP TABLE [IF EXISTS] <表名>等表管理语句,其实现同样围绕table_map展开(见 crates/polars-sql/src/context.rs#L928-L962)。删表后再次执行SHOW TABLES,可以验证表是否已正确移除。

小结

  • SHOW TABLES语法固定、无参数,用于列出当前SQLContext中已注册的全部表;
  • 返回结果是一个仅含name单列、按字典序排列的DataFrame;
  • 作用域严格限定在当前SQLContext,跨 context、跨会话注册的表不可见;
  • 其实现由 crates/polars-sql/src/context.rs 中的execute_statement分发至execute_show_tables,数据来自table_map(通过get_tables()读取并排序);
  • Python 侧可用ctx.get_tables()获得等价信息,用register/unregister动态增删表后再用SHOW TABLES验证结果。

【免费下载链接】polarsExtremely fast Query Engine for DataFrames, written in Rust项目地址: https://gitcode.com/GitHub_Trending/po/polars

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

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

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

立即咨询