跳到主要内容

从 Supabase Storage 迁移

PG 模式云存储与 Supabase Storage 在 storage schema、Bucket / Object 元数据模型和 RLS 思路上高度相似。如果你的应用主要使用 Supabase 的 File Buckets,可以按本文迁移到 CloudBase。

迁移前确认

迁移前请先确认现有 Supabase Storage 的使用范围:

检查项说明
Bucket 类型迁移对象应是通用文件 Bucket,例如图片、视频、文档、压缩包
访问模型Public / Private Bucket、Signed URL、Authenticated download
RLS Policystorage.objects 上的 SELECT / INSERT / UPDATE / DELETE 策略
路径规则是否使用 <uid>/<filename><team_id>/<filename> 等路径约定
上传限制文件大小限制、MIME 类型限制
SDK API是否使用 uploaddownloadlistremovecreateSignedUrl 等能力

建议先选一个低风险 Bucket 做试迁移,例如 avatars 或测试附件 Bucket。

可复用的内容

以下内容通常可以复用或少量调整后复用:

Supabase Storage 内容CloudBase 对应内容
storage.bucketsstorage.buckets
storage.objectsstorage.objects
bucket_idbucket_id
name 对象路径name 对象路径
owner_idowner_id
metadata / user_metadatametadata / user_metadata
storage.foldername(name)storage.foldername(name)
storage.filename(name)storage.filename(name)
大部分 RLS Policy 思路可迁移为 CloudBase RLS Policy

例如,按用户目录隔离的策略通常只需确认 auth.uid()、角色名和 Bucket ID 是否一致。

CREATE POLICY user_files_select ON storage.objects
FOR SELECT TO authenticated
USING (
bucket_id = 'user-files'
AND (storage.foldername(name))[1] = auth.uid()
);

需要调整的内容

public 语义需要复核

在 CloudBase PG 模式中,storage.buckets.public 是元数据标记,不会自动绕过 RLS。是否公开可读,仍由 storage.objects 上的 SELECT Policy 决定。

如果 Supabase 中某个 Public Bucket 依赖「知道 URL 即可访问」的语义,迁移后需要显式补充公开读策略:

CREATE POLICY objects_public_read ON storage.objects
FOR SELECT TO anon, authenticated
USING (
EXISTS (
SELECT 1 FROM storage.buckets b
WHERE b.id = storage.objects.bucket_id
AND b.public
)
);

SDK 初始化和项目配置不同

Supabase:

import { createClient } from '@supabase/supabase-js';

const supabase = createClient('<project-url>', '<anon-key>');
const bucket = supabase.storage.from('avatars');

CloudBase:

import cloudbase from '@cloudbase/js-sdk';

const app = cloudbase.init({ env: '<env-id>' });
const bucket = app.storage.from('avatars');

返回字段和 URL 字段需要复核

不同 SDK 的返回字段不完全一致。迁移时请重点检查:

  • 上传返回对象 ID、路径、完整路径;
  • 签名下载链接字段,例如 signedUrl / fullSignedURL
  • 公开 URL 字段;
  • 错误对象结构;
  • 列表分页字段,例如 hasNextnextCursor

上传协议和高级能力需要重新设计

如果 Supabase 项目使用了 TUS 可恢复上传、S3 兼容协议、图片实时转换、特定 CDN Header 或其他高级能力,请先确认 CloudBase 当前对应能力和推荐接入方式,再迁移相关业务逻辑。

对于普通 File Bucket 场景,优先迁移以下稳定能力:

  • Bucket 创建与配置;
  • 文件上传 / 下载;
  • 文件列表;
  • 复制 / 移动 / 删除;
  • 签名下载 / 签名上传;
  • RLS 权限策略。

推荐迁移步骤

1. 梳理 Bucket 清单

为每个 Bucket 记录:

Bucket: avatars
用途:用户头像
Public:false
大小限制:5 MB
MIME:image/png、image/jpeg、image/webp
路径:<uid>/avatar.png
权限:本人写,按业务读取

2. 在 CloudBase 创建 Bucket

INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types)
VALUES (
'avatars',
'avatars',
false,
5 * 1024 * 1024,
ARRAY['image/png', 'image/jpeg', 'image/webp']
);

3. 迁移文件实体

根据源 Bucket 和目标 Bucket 的规模选择迁移方式:

  • 小规模:通过 SDK 下载后重新上传;
  • 中等规模:编写服务端脚本批量迁移;
  • 大规模:结合对象存储后端工具迁移文件实体,再补齐元数据。

迁移脚本必须使用环境变量保存密钥,不要把 Supabase service key、CloudBase API Key 或腾讯云密钥写入代码仓库。

4. 迁移元数据和业务引用

如果业务表中保存了 Supabase 文件 URL,建议迁移为稳定的 Bucket 内对象路径,例如:

avatars/user-123/avatar.png

业务表保存对象路径,展示时再生成公开 URL 或签名 URL。这样后续更换域名、访问方式或 CDN 配置时,不需要批量修改业务数据。

5. 迁移 RLS Policy

按 Bucket 逐条迁移 SELECTINSERTUPDATEDELETE Policy。每条 Policy 迁移后都应验证:

  • owner 可以访问自己的文件;
  • 非 owner 不能访问;
  • 匿名用户权限符合预期;
  • service_role 仅在服务端使用。

6. 替换 SDK 调用

常见替换关系:

SupabaseCloudBase
supabase.storage.from(bucket)app.storage.from(bucket)
bucket.upload(path, file, options)bucket.upload(path, file, options)
bucket.download(path)bucket.download(path)
bucket.list(prefix, options)bucket.list(prefix, options)
bucket.remove(paths)bucket.remove(paths)
bucket.createSignedUrl(path, expiresIn)bucket.createSignedUrl(path, expiresIn)
bucket.getPublicUrl(path)bucket.getPublicUrl(path)

方法名相近不代表返回结构完全一致,迁移时请以 JS SDK Storage API 为准。

7. 做权限回归测试

至少覆盖以下用例:

用例预期
owner 上传自己的文件成功
owner 下载自己的文件成功
非 owner 下载他人私有文件失败
匿名访问公开文件按公开读策略决定
匿名访问私有文件失败
owner 覆盖自己的文件UPDATE Policy 决定
非管理员删除团队文件失败
管理员删除团队文件成功

AI 友好迁移清单

如果你希望让 AI 辅助迁移,建议按 Bucket 提供结构化清单,而不是直接丢一整份 SQL:

源:Supabase Storage
目标:CloudBase PG 云存储
Bucket: avatars
用途:用户头像
路径:<uid>/avatar.png
Public:否
读取:所有登录用户可读
上传:仅本人可上传到自己的 <uid>/ 目录
覆盖:仅本人可覆盖自己的头像
删除:仅本人可删除自己的头像
限制:5 MB;image/png、image/jpeg、image/webp
需要迁移:Bucket 创建 SQL、RLS Policy、JS SDK 上传和签名 URL 代码

这样 AI 可以分别生成 Bucket SQL、RLS、SDK 替换代码和测试用例,减少遗漏。