首页
/ Supabase S3 Wrapper 完全指南:用只读外表把 S3 对象存储变成 Postgres 可查询的表

Supabase S3 Wrapper 完全指南:用只读外表把 S3 对象存储变成 Postgres 可查询的表

2026-09-06 15:30:07作者:董斯意

本文基于 Supabase 仓库中 Studio 控制台内置的 S3 Wrapper 集成文档 overview.md 展开,系统讲解 S3 Wrapper 支持的文件格式与压缩算法、CSV/JSONL/Parquet 各自的类型与内存限制,并结合 Studio 前端源码、仪表盘配置项与端到端测试,还原在 Supabase Dashboard 中创建 S3 Wrapper 的完整流程与安全注意事项。

一、S3 Wrapper 是什么:只读的对象存储外表

S3 Wrapper 是 Supabase 基于 Foreign Data Wrapper(FDW)体系封装的 AWS S3 集成。按官方集成文档的原文定义:

AWS S3 is an object storage service offering industry-leading scalability, data availability, security, and performance. It is read-only and supports below file formats.

也就是说,S3 Wrapper 的定位是只读——你可以把 S3 Bucket 中的文件映射为 Postgres 外表并直接 SELECT 查询,但不能通过它向 S3 写入数据。这一点在配置 UI 中也能得到印证:s3_wrapperWrappers.constants.ts 中注册的外表模板只有一个 "S3 File",没有任何写入型选项。

支持的文件格式

格式 说明
CSV 支持带表头(header line)与不带表头两种情况
JSON Lines(JSONL) 每行一个 JSON 对象的流式格式
Parquet Apache Parquet 列式存储格式

支持的压缩算法

S3 Wrapper 在读取上述文件时支持四种压缩算法:

  • gzip
  • bzip2
  • xz
  • zlib

两条重要的使用限制(原文档核心约束)

原文档给出了两条必须牢记的限制,直接决定了实际可用性:

  1. CSV 与 JSONL 文件:S3 文件中的所有列都必须在外表中显式定义,且列类型必须是 text。这意味着查询时如果需要数值、日期等类型,要在 SQL 层自行转换(如 col::int),而不能指望外表直接给出强类型。
  2. Parquet 文件:如果 Parquet 文件是压缩过的,整个文件会被一次性加载进本地内存,因此应尽可能控制文件大小,避免大文件压缩 Parquet 造成内存压力。

这两条限制是原文档中最具实战价值的部分——前者影响建表 DDL 的写法(全部列声明为 text),后者影响数据文件的组织策略(大文件建议不压缩或拆分)。

二、Studio 中的文档注册机制:overview.md 如何被控制台读取

这份 overview.md 并非孤立的静态文件,它是 Studio「集成总览」页面的内容源。从源码结构看,其加载链路如下:

  1. 注册表overviews.ts 维护了一个以集成 id 为键、懒加载 markdown 的映射,其中 S3 Wrapper 的条目为 s3_wrapper: () => import('@/static-data/integrations/s3_wrapper/overview.md')(第 41 行)。
  2. 加载函数:同文件的 loadIntegrationOverview(integrationId)(第 58–63 行)在仪表盘路由 /project/:ref/integrations/s3_wrapper/overview 被访问时异步取回该 markdown 字符串;没有配套 overview 的集成(如 marketplace apps)则返回 null
  3. 同步保证overviews.test.ts 断言注册表映射与磁盘文件保持同步——新增 overview.md 时必须在注册表中补登记。
  4. 构建约束:注册表文件头部注释解释了为何 import 说明符必须是字符串字面量而非模板字符串:webpack/turbopack 依赖静态分析做代码拆分,而 Vite/Rolldown(TanStack 构建)不处理模板字符串动态 import,会在运行时抛 TypeError: Failed to resolve module specifier

理解这一机制的价值在于:你看到 s3_wrapper/overview.md 里描述的格式与压缩能力,正是控制台 UI 对该 Wrapper 的能力声明;当文档与 UI 行为不一致时(见下文 format 选项差异),可以沿这条链路定位是前端元数据还是文档需要更新。

三、在 Dashboard 中创建 S3 Wrapper:配置项全解

S3 Wrapper 在 Studio 中的完整元数据定义在 Wrappers.constants.tsWRAPPERS 数组中:

{
  name: 's3_wrapper',
  handlerName: 's3_fdw_handler',   // 底层 FDW handler
  validatorName: 's3_fdw_validator',
  extensionName: 'S3Fdw',          // 关联的 Postgres 扩展
  label: 'S3',
  description: 'Cloud object storage service',
  docsUrl: `${DOCS_URL}/guides/database/extensions/wrappers/s3`,
  categories: ['storage'],
  server: { options: [ /* 见下 */ ] },
  tables: [ { label: 'S3 File', /* 见下 */ } ],
}

3.1 Server 选项(连接凭据)

选项名 界面标签 必填 默认值 说明
vault_access_key_id Access Key ID AWS Access Key ID,encrypted: true,通过 Vault 加密存储
vault_secret_access_key Access Key Secret AWS Secret Access Key,同样加密入 Vault
aws_region AWS Region us-east-1 S3 所在区域,明文存储

注意选项名中的 vault_ 前缀:Supabase 使用 vault 扩展把密钥写入 vault.secrets 表,FDW 运行时从 Vault 读取凭据,而不是把明文密钥写进 foreign server 的 options 里。端到端测试的清理逻辑直接印证了这一点——见 wrappers.spec.ts 第 106–108 行:

delete from vault.secrets where name = '${wrapperName}_vault_access_key_id';
delete from vault.secrets where name = '${wrapperName}_vault_secret_access_key';

即密钥在 Vault 中的命名规则为 {wrapper_name}_vault_access_key_id{wrapper_name}_vault_secret_access_key

3.2 外表(Foreign Table)选项

外表模板 "S3 File"(描述为 "Map to a file in S3")提供以下选项:

选项名 界面标签 类型 默认值 说明
uri URI text S3 对象地址,占位示例 s3://bucket/s3_table.csv
format Format select csv 取值 csv / jsonl(JSON Lines)
has_header Has Header select true CSV 是否带表头行
compress Compression select 界面仅提供 gzip 一项

一个值得注意的差异:overview 文档声明底层 Wrapper 支持 CSV、JSONL、Parquet 三种格式与四种压缩算法,而当前 UI 的 format 下拉只暴露了 csvjsonlcompress 也只暴露 gzip。从源码结构看,这说明仪表盘 UI 元数据是底层能力的子集——如果你需要 Parquet 或非 gzip 压缩(bzip2/xz/zlib),可以绕过 UI 直接用 SQL 创建外表,在 options (format 'parquet', compress 'xz') 中指定(该能力以原文档的能力声明为准)。UI 未暴露只是界面层面的收敛。

四、端到端测试还原的完整创建流程

wrappers.spec.ts 中的 "can create an S3 wrapper" 用例完整走了一遍仪表盘创建流程,可视为操作步骤的可执行版本:

  1. 前置:create extension if not exists wrappers schema extensions version '0.6.2' cascade;(测试使用的 Wrappers 扩展版本为 0.6.2);
  2. 打开 /project/{ref}/integrations/s3_wrapper/overview,点击 Add new wrapper
  3. 填写 Wrapper Name(如 test_s3_wrapper)、Access Key IDAccess Key Secret
  4. 点击 Add foreign table,在模板下拉中选择 S3 File
  5. 填写 Table name(如 test_s3_wrapper_table)与 URI(如 s3://bucket/s3_table.csv);
  6. 点击 Add column 添加列(如 s3_column,对应上文「所有列必须显式定义且为 text 类型」的要求);
  7. Save 保存外表定义,Create wrapper 创建 Wrapper;
  8. 断言出现 "Successfully created S3 foreign data wrapper" 提示。

测试用 withSetupCleanup 包裹,结束后会 drop foreign data wrapper ... cascade 并清理 Vault 密钥与测试表,这套清理序列也说明了 S3 Wrapper 的资源三件套:foreign data wrapper + vault secrets + 映射的外表

五、底层机制:s3_fdw_handler 与只读语义

Wrappers.constants.tsWRAPPER_HANDLERS 映射表可见,各集成与底层 FDW handler 的对应关系:

S3: 's3_fdw_handler',
S3_VECTORS: 's3_vectors_fdw_handler',

S3: 's3_fdw_handler' 表明 S3 Wrapper 在数据库侧是名为 s3_fdw_handler 的 FDW handler,配套验证器为 s3_fdw_validator,关联扩展为 S3FdwextensionName 字段)。创建 Dashboard Wrapper 本质上是生成一组 DDL:CREATE FOREIGN DATA WRAPPER ... HANDLER s3_fdw_handler VALIDATOR s3_fdw_validatorCREATE SERVER(凭据走 Vault)、CREATE FOREIGN TABLE(带 uri/format/has_header/compress 选项)。

「只读」语义与整体 Wrappers 生态一致:Supabase 文档站对 FDW 的总述 overview.mdx 解释了 FDW 的核心概念——Remote Server(如 S3 这类外部数据系统)与 Foreign Table(数据仍留在远端、只是映射进 Postgres 的表)。S3 Wrapper 正是「把 S3 对象作为 Remote Server 上的数据源」这一模式的落地。

六、安全与使用建议

Supabase 的 FDW 文档 overview.mdx 在「Security」一节给出了适用于所有 Wrapper(含 S3 Wrapper)的通用安全准则,这里继承三条关键建议:

  1. FDW 不提供 Row Level Security:不要把 foreign server / foreign table 直接暴露到 Supabase API。
  2. 存放在私有 schema:所有 S3 相关外表应放在专用私有 schema 中,且该 schema 不应加入 API 设置里的 "Additional Schemas"。
  3. 确需对外暴露时走 security definer 函数:在 public schema 创建 security definer 函数查询外表并附加过滤条件,同时用 revoke execute ... from public/anon + grant execute ... to authenticated 收窄执行权限。

结合 S3 场景补充一点:由于凭据由 Vault 加密保管(vault_access_key_id / vault_secret_access_key),建议 AWS 侧对该 Access Key 只授予目标 Bucket 的 s3:GetObject 读取权限,与 Wrapper 的只读定位保持一致。

七、与 S3 Vectors Wrapper 的区分

仓库中还有一个易混淆的姊妹集成 s3_vectors_wrapper/overview.md

AWS S3 Vectors is a managed service that stores and queries high-dimensional vectors at scale... The S3 Vectors Wrapper allows you to read, write, and perform vector similarity search operations on S3 Vectors within your Postgres database.

两者定位差异清晰:

维度 s3_wrapper s3_vectors_wrapper
目标 通用 S3 对象(CSV/JSONL/Parquet 文件) AWS S3 Vectors 托管向量服务
读写 只读 读、写、向量相似度检索
FDW handler s3_fdw_handler s3_vectors_fdw_handler
Server 额外选项 endpoint_urlsupabase_target_schema
分类 storage ai_vectorsstorage

如果你要做向量检索(AI 场景),应选择 S3 Vectors Wrapper;如果只是把数据文件(报表 CSV、日志 JSONL、分析用 Parquet)直接纳入 SQL 查询,则使用本文所述的 S3 Wrapper。

八、如何获取更完整的官方文档

S3 Wrapper 的详细操作文档并不内置于本仓库。从 wrappers.ts 的联邦内容源映射可见,文档站构建时会从外部 Wrappers 仓库拉取 s3.md 并映射到本地 slug s3,同时通过 dashboardIntegrationPath: 's3_wrapper' 与控制台集成页互链;Studio 侧 s3_wrapperdocsUrl 也指向 guides/database/extensions/wrappers/s3 这一路由。因此完整建表 DDL、参数取值范围等细节应以该文档页为准,本文则以仓库内可直接验证的集成元数据、能力声明与测试用例为证据边界。

小结

  • 能力边界:S3 Wrapper 只读,支持 CSV(含/不含表头)、JSONL、Parquet,压缩支持 gzip/bzip2/xz/zlib;
  • 两条硬限制:CSV/JSONL 所有列须在外表中定义且为 text 类型;压缩 Parquet 整文件加载进内存,文件宜小;
  • 配置要点:Vault 加密的 Access Key ID/Secret + aws_region(默认 us-east-1)+ 外表选项 uri/format/has_header/compress
  • UI 与底层差异:界面仅暴露 csv/jsonl 与 gzip,Parquet 与其他压缩算法需通过 SQL 直接建表使用;
  • 安全基线:私有 schema 隔离、不加入 API Additional Schemas、必要时用 security definer 函数收窄暴露面。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388