你好!既然你决定将项目从 Supabase 迁移到 Insforge,那么本指南就是为你准备的。数据迁移可能令人望而生畏。你可能会想:如何在不强制用户重置密码的情况下迁移所有用户?如何传输每一个文件并更新所有链接?数据库结构和那些宝贵的数据又该怎么办?
别担心,我们都已为你考虑周全。
本指南将介绍一个经过生产环境检验的完整迁移工具包,旨在将你的整个 Supabase 项目无缝过渡到一个自托管的 Insforge 实例。我们所说的不仅仅是部分数据转储,而是一次完整的迁移,它将保留:
该工具包已在真实的生产环境中经过实战检验,成功迁移了 39 个用户、985 条数据库记录以及超过 1500 个存储文件,无一数据丢失。有关自托管的更多信息,请查看 Insforge GitHub 仓库。
让我们开始吧。
在开始之前,让我们先设置好环境,确保迁移过程顺利。
首先,请确保你已具备必要的工具和访问权限:
psql)现在,让我们来配置迁移工具本身。
首先,克隆该工具包的仓库(或下载源码)并安装依赖项。
# 克隆仓库 (如果适用)
# git clone <https://github.com/InsForge/supabase-to-insforge>
# 安装依赖项
npm install
接下来,创建你的环境配置文件。复制示例文件来创建你自己的 .env 文件。
cp .env.example .env
现在,打开新创建的 .env 文件,并填入你决定迁移的 Supabase 项目和新的 Insforge 项目的凭据。
要填写 .env 文件,你需要从 Supabase 项目仪表板中获取三项关键信息。
SUPABASE_URL 和 SUPABASE_SERVICE_ROLE_KEY:
service_role 密钥。SUPABASE_DB_URL(你的连接字符串):
[YOUR-PASSWORD] 占位符替换为你的实际数据库密码。如果你忘记了密码,可以在 Project Settings > Database 中重置。
# ============================================
# 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
在运行迁移之前,让我们确保该工具可以连接到两个数据库。运行以下命令来测试你的连接:
# 测试 Supabase 连接
psql "$SUPABASE_DB_URL" -c "SELECT version();"
# 测试 Insforge 连接 (根据你的本地/远程设置进行调整)
psql postgresql://postgres:postgres@localhost:5432/insforge -c "SELECT version();"
# 退出
\\q
如果两个命令都无误执行,那么你就可以开始正式迁移了!
迁移过程分为三个逻辑阶段。请按顺序执行以获得最佳效果。
这通常是任何迁移中最棘手的部分,但这个工具包让它变得简单。我们将迁移所有用户账户,同时保留他们原有的密码。
此命令会连接到你的 Supabase 项目,并将 auth.users 表中的所有用户导出到一个本地 JSON 文件中。
npm run export:auth
预期输出:
✅ 已连接到 Supabase PostgreSQL
✅ 已将 39 个用户导出到 auth-export.json
这将创建一个名为 auth-export.json 的文件,其中包含用户详情,包括他们的 ID 和加密密码。
现在,我们将从 auth-export.json 文件中将用户导入到你的 Insforge 实例。该脚本会保留原始的用户 ID(对于外键至关重要)和他们经过 bcrypt 哈希的密码。
npm run import:auth
预期输出:
✅ 已连接到 Insforge API
URL: <https://your-insforge-instance.insforge.app>
📦 已加载导出数据...
⬆️ 正在导入用户...
✅ 已导入 41/41 个账户
✅ 导入完成!
专业提示: 这个脚本是幂等的,这意味着你可以多次运行它而不会创建重复的用户。如果发现现有记录,它只会更新这些记录。
接下来,我们将迁移你的整个 PostgreSQL 数据库,包括结构、数据,甚至你的行级安全(RLS)策略。
此命令使用 pg_dump 为你的 Supabase 公共模式创建一个完整的 SQL 备份。
npm run export:db
预期输出:
✅ 数据库导出成功
文件: database-export.sql (245 KB)
这将生成一个 database-export.sql 文件。
Supabase 使用了一些特定的函数和扩展。此脚本会清理导出的 SQL 文件,移除 Supabase 特定的代码,更新 RLS 策略(例如,auth.uid() 变为 uid()),并使其与 Insforge 兼容。
npm run transform:db
预期输出:
✅ 已为 Insforge 转换 SQL
输出: database-export.insforge.sql
这将创建一个新的、为 Insforge 准备好的文件:database-export.insforge.sql。
最后,让我们将转换后的 SQL 文件导入到你的 Insforge 项目中。
npm run import:db
预期输出:
🗄️ 正在将数据库导入 Insforge...
✅ 数据库导入完成!
受影响的表: 12
导入的行数: 985
你的数据库结构和数据现已成功迁移!
最后一个阶段是将你所有的文件从 Supabase Storage 移动到 Insforge Storage。这个过程会保留精确的文件路径,这对于防止链接失效至关重要。
首先,该脚本将从你的 Supabase 项目中读取存储桶列表,并在 Insforge 中创建相同的存储桶,同时保留它们的公共或私有设置。
npm run create:buckets
预期输出:
✅ 已连接到 Supabase PostgreSQL
📦 在 Supabase 中找到 4 个存储桶:
📋 正在创建存储桶: generated-images (public)... ✅ 创建成功
📋 正在创建存储桶: raw-product-images (public)... ✅ 创建成功
...
✅ 存储桶创建完成!
此命令会从你所有的 Supabase 存储桶中下载每一个文件,并保留原始的目录结构。
npm run export:storage
预期输出:
📦 开始从 Supabase 导出存储...
⬇️ 正在下载文件...
[1/1572] generated-images/user123/image.jpg ✅
...
[1572/1572] reference-images/ref5.jpg ✅
✅ 导出完成!已下载: 1,572 个文件
所有文件都将保存在本地的 storage-downloads/ 目录中。
现在,我们将所有下载的文件上传到 Insforge 中对应的存储桶。
npm run import:storage
预期输出:
📦 找到 1572 个待导入文件
⬆️ [1/1572] generated-images/user123/scene/image.jpg... ✅ 上传成功
...
✅ 导入完成!成功: 1569/1572
这是见证奇迹的时刻。你的数据库中可能包含数千个指向 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 上运行的最后几个步骤。
更新应用程序代码: 将你的应用程序客户端配置指向你的 Insforge 实例,而不是 Supabase。有关使用 MCP 重新配置 SDK 的详细指导,请查看我们的配套博文。
// 之前 (Supabase)
const supabase = createClient('SUPABASE_URL', 'SUPABASE_ANON_KEY');
// 之后 (Insforge)
const insforge = createClient('你的_INSFORGE_API_URL', '你的_INSFORGE_API_KEY');
端到端测试: 全面测试你的应用程序。
清理工作: 一旦你确认一切正常,就可以删除临时的迁移文件(storage-downloads/、.sql、.json)。
File too large 错误: 你的文件超出了 Insforge 实例的上传限制。你可能需要提高限制或手动迁移该文件。import:auth 脚本是否成功运行。bcrypt 密码哈希应该被原样保留。.env 连接字符串是否正确。迁移愉快!🚀