从 Supabase 迁移到 Insforge:分步式指南

一款开源工具包,助您无损迁移整个 Supabase 项目——包含用户、数据库及文件。

Kyle ChungKyle Chung

分分钟从 Supabase 迁移到 Insforge:一份经过生产环境检验的完整指南

你好!既然你决定将项目从 Supabase 迁移到 Insforge,那么本指南就是为你准备的。数据迁移可能令人望而生畏。你可能会想:如何在不强制用户重置密码的情况下迁移所有用户?如何传输每一个文件并更新所有链接?数据库结构和那些宝贵的数据又该怎么办?

别担心,我们都已为你考虑周全。

本指南将介绍一个经过生产环境检验的完整迁移工具包,旨在将你的整个 Supabase 项目无缝过渡到一个自托管的 Insforge 实例。我们所说的不仅仅是部分数据转储,而是一次完整的迁移,它将保留:

  • 用户认证(包括密码!)
  • 完整的数据库(结构和数据)
  • 所有存储文件(路径完全一致)
  • 外键关系(通过保留用户 ID)

该工具包已在真实的生产环境中经过实战检验,成功迁移了 39 个用户、985 条数据库记录以及超过 1500 个存储文件,无一数据丢失。有关自托管的更多信息,请查看 Insforge GitHub 仓库

让我们开始吧。

开始之前:你的迁移前检查清单

在开始之前,让我们先设置好环境,确保迁移过程顺利。

1. 前提条件

首先,请确保你已具备必要的工具和访问权限:

  • 软件:
    • Node.js (v20+)
    • PostgreSQL 客户端 (psql)
  • 访问权限:
    • 你的 Supabase 项目凭据(API 密钥、数据库 URL)。
    • 一个拥有管理员 API 密钥的有效 Insforge 实例。

2. 环境设置

现在,让我们来配置迁移工具本身。

首先,克隆该工具包的仓库(或下载源码)并安装依赖项。

# 克隆仓库 (如果适用)
# git clone <https://github.com/InsForge/supabase-to-insforge>

# 安装依赖项
npm install

接下来,创建你的环境配置文件。复制示例文件来创建你自己的 .env 文件。

cp .env.example .env

现在,打开新创建的 .env 文件,并填入你决定迁移的 Supabase 项目和新的 Insforge 项目的凭据。

查找你的 Supabase 凭据

要填写 .env 文件,你需要从 Supabase 项目仪表板中获取三项关键信息。

  1. SUPABASE_URLSUPABASE_SERVICE_ROLE_KEY
    • 导航到你的 Supabase 项目。
    • 进入 Project Settings(齿轮图标)。
    • 点击 API
    • 在这里,你将找到你的项目 URL 和 service_role 密钥。
  2. SUPABASE_DB_URL(你的连接字符串)
    • 在你的 Supabase 项目仪表板中,点击页面顶部的 Connect 按钮。
    • 一个面板将会打开,其中包含你的数据库连接详细信息。
    • Direct connection 部分复制 URI。
    • 重要提示: 你必须将字符串中的 [YOUR-PASSWORD] 占位符替换为你的实际数据库密码。如果你忘记了密码,可以在 Project Settings > Database 中重置。

PSQL String

# ============================================
# Supabase 配置
# ============================================
# 在 Supabase 设置中找到这些凭据
SUPABASE_URL=https://你的项目.supabase.co
SUPABASE_SERVICE_ROLE_KEY=你的_supabase_service_role_key
SUPABASE_DB_URL=postgresql://postgres.xxx:[你的密码]@...

# ============================================
# Insforge 配置
# ============================================
# 你的 Insforge 实例详情
INSFORGE_API_URL=http://localhost:7130 # 或你的远程 URL
INSFORGE_API_KEY=你的_insforge_api_key

3. 验证你的连接

在运行迁移之前,让我们确保该工具可以连接到两个数据库。运行以下命令来测试你的连接:

# 测试 Supabase 连接
psql "$SUPABASE_DB_URL" -c "SELECT version();"

# 测试 Insforge 连接 (根据你的本地/远程设置进行调整)
psql postgresql://postgres:postgres@localhost:5432/insforge -c "SELECT version();"

# 退出
\\q

如果两个命令都无误执行,那么你就可以开始正式迁移了!


伟大的迁移:分步指南

迁移过程分为三个逻辑阶段。请按顺序执行以获得最佳效果。

阶段 1:迁移你的用户(无需重置密码!)

这通常是任何迁移中最棘手的部分,但这个工具包让它变得简单。我们将迁移所有用户账户,同时保留他们原有的密码。

步骤 1.1:从 Supabase 导出用户

此命令会连接到你的 Supabase 项目,并将 auth.users 表中的所有用户导出到一个本地 JSON 文件中。

npm run export:auth

预期输出:

✅ 已连接到 Supabase PostgreSQL
✅ 已将 39 个用户导出到 auth-export.json

这将创建一个名为 auth-export.json 的文件,其中包含用户详情,包括他们的 ID 和加密密码。

步骤 1.2:将用户导入 Insforge

现在,我们将从 auth-export.json 文件中将用户导入到你的 Insforge 实例。该脚本会保留原始的用户 ID(对于外键至关重要)和他们经过 bcrypt 哈希的密码。

npm run import:auth

预期输出:

✅ 已连接到 Insforge API
   URL: <https://your-insforge-instance.insforge.app>

📦 已加载导出数据...
⬆️  正在导入用户...
   ✅ 已导入 41/41 个账户
✅ 导入完成!

专业提示: 这个脚本是幂等的,这意味着你可以多次运行它而不会创建重复的用户。如果发现现有记录,它只会更新这些记录。

阶段 2:迁移你的数据库

接下来,我们将迁移你的整个 PostgreSQL 数据库,包括结构、数据,甚至你的行级安全(RLS)策略。

步骤 2.1:导出数据库结构和数据

此命令使用 pg_dump 为你的 Supabase 公共模式创建一个完整的 SQL 备份。

npm run export:db

预期输出:

✅ 数据库导出成功
   文件: database-export.sql (245 KB)

这将生成一个 database-export.sql 文件。

步骤 2.2:为 Insforge 转换 SQL

Supabase 使用了一些特定的函数和扩展。此脚本会清理导出的 SQL 文件,移除 Supabase 特定的代码,更新 RLS 策略(例如,auth.uid() 变为 uid()),并使其与 Insforge 兼容。

npm run transform:db

预期输出:

✅ 已为 Insforge 转换 SQL
   输出: database-export.insforge.sql

这将创建一个新的、为 Insforge 准备好的文件:database-export.insforge.sql

步骤 2.3:将数据库导入 Insforge

最后,让我们将转换后的 SQL 文件导入到你的 Insforge 项目中。

npm run import:db

预期输出:

🗄️  正在将数据库导入 Insforge...
✅ 数据库导入完成!
受影响的表: 12
导入的行数: 985

你的数据库结构和数据现已成功迁移!

阶段 3:迁移你的文件存储

最后一个阶段是将你所有的文件从 Supabase Storage 移动到 Insforge Storage。这个过程会保留精确的文件路径,这对于防止链接失效至关重要。

步骤 3.1:重新创建存储桶

首先,该脚本将从你的 Supabase 项目中读取存储桶列表,并在 Insforge 中创建相同的存储桶,同时保留它们的公共或私有设置。

npm run create:buckets

预期输出:

✅ 已连接到 Supabase PostgreSQL
📦 在 Supabase 中找到 4 个存储桶:
📋 正在创建存储桶: generated-images (public)... ✅ 创建成功
📋 正在创建存储桶: raw-product-images (public)... ✅ 创建成功
...
✅ 存储桶创建完成!

步骤 3.2:从 Supabase 下载所有文件

此命令会从你所有的 Supabase 存储桶中下载每一个文件,并保留原始的目录结构。

npm run export:storage

预期输出:

📦 开始从 Supabase 导出存储...
⬇️  正在下载文件...
   [1/1572] generated-images/user123/image.jpg ✅
   ...
   [1572/1572] reference-images/ref5.jpg ✅

✅ 导出完成!已下载: 1,572 个文件

所有文件都将保存在本地的 storage-downloads/ 目录中。

步骤 3.3:将所有文件上传到 Insforge

现在,我们将所有下载的文件上传到 Insforge 中对应的存储桶。

npm run import:storage

预期输出:

📦 找到 1572 个待导入文件
⬆️  [1/1572] generated-images/user123/scene/image.jpg... ✅ 上传成功
...
✅ 导入完成!成功: 1569/1572

步骤 3.4:点睛之笔 - 更新所有存储 URL

这是见证奇迹的时刻。你的数据库中可能包含数千个指向 Supabase Storage 的 URL。此脚本会连接到你的 Insforge 数据库,并在所有表上执行通用的查找和替换。它会智能地将每个 Supabase 存储 URL 更新为新的 Insforge URL,即使是在复杂的 JSONB 字段内部。

npm run update:storage-urls

预期输出:

✅ 已连接到 Insforge API
🔄 通用 URL 替换...
📊 发现:
   - 997 个生成的输入中包含 Supabase URL
   - 1023 个生成的输出中包含 Supabase URL
⏳ 正在通用更新所有 URL...
✅ 所有 Supabase 存储 URL 均已更新!

就这样!你的整个项目现已迁移完毕。


接下来做什么?迁移后步骤

你的数据已迁移,但工作尚未完成。以下是让你的应用程序在 Insforge 上运行的最后几个步骤。

  1. 更新应用程序代码: 将你的应用程序客户端配置指向你的 Insforge 实例,而不是 Supabase。有关使用 MCP 重新配置 SDK 的详细指导,请查看我们的配套博文

    // 之前 (Supabase)
    const supabase = createClient('SUPABASE_URL', 'SUPABASE_ANON_KEY');
    
    // 之后 (Insforge)
    const insforge = createClient('你的_INSFORGE_API_URL', '你的_INSFORGE_API_KEY');
    
  2. 端到端测试: 全面测试你的应用程序。

    • 用户能用旧密码登录吗?
    • 图片和文件能正常加载吗?
    • 所有与数据相关的功能都按预期工作吗?
  3. 清理工作: 一旦你确认一切正常,就可以删除临时的迁移文件(storage-downloads/.sql.json)。

常见问题排查

  • 存储导入时出现 File too large 错误: 你的文件超出了 Insforge 实例的上传限制。你可能需要提高限制或手动迁移该文件。
  • 密码登录失败: 仔细检查 import:auth 脚本是否成功运行。bcrypt 密码哈希应该被原样保留。
  • 连接超时: 验证你的 IP 是否已在 Supabase 的网络限制中加入白名单,以及你的 .env 连接字符串是否正确。

迁移愉快!🚀