Sanity中image类型资产引用问题及批量迁移需求
批量迁移Sanity图片引用至新顶级Schema的脚本方案
前置准备
首先确保你已经创建好独立的blogImage顶级Schema,示例如下:
// schemas/blogImage.js export default { name: 'blogImage', type: 'image', title: 'Blog Image', fields: [ { name: 'alt', type: 'string', title: 'Alternative Text' } // 保留原嵌套image类型的所有字段,确保数据兼容 ] }
将该Schema注册到你的Sanity配置文件中,确保Studio能识别新类型。
批量迁移脚本实现
使用Sanity Client API编写脚本,遍历目标文档、提取嵌套图片为独立blogImage文档,并更新原文档的引用关系:
1. 创建脚本文件
在项目根目录新建migrate-image-references.js:
import { createClient } from '@sanity/client' import { groq } from 'next-sanity' import dotenv from 'dotenv' dotenv.config() // 初始化Sanity客户端(需写入权限) const client = createClient({ projectId: process.env.SANITY_PROJECT_ID, dataset: process.env.SANITY_DATASET, apiVersion: '2024-01-01', token: process.env.SANITY_WRITE_TOKEN, useCdn: false }) async function migrateImages() { // 查询所有包含嵌套image的目标文档(此处以blogPost为例,根据你的实际类型调整) const targetDocs = await client.fetch(groq` *[_type == "blogPost" && defined(blogContent.content)] { _id, _rev, blogContent { content } } `) console.log(`检测到 ${targetDocs.length} 个待处理文档`) for (const doc of targetDocs) { const updatedContent = [] const newImageDocs = [] // 遍历content数组,处理每个元素 for (const item of doc.blogContent.content) { if (item._type === 'image') { // 生成新的blogImage文档 const imageId = `blogImage-${Math.random().toString(36).slice(2, 12)}` const newImage = { _id: imageId, _type: 'blogImage', ...item // 继承原嵌套图片的所有字段(asset、alt等) } newImageDocs.push(newImage) // 将原嵌套image替换为引用 updatedContent.push({ _type: 'reference', _ref: imageId }) } else { // 非图片元素直接保留 updatedContent.push(item) } } if (newImageDocs.length === 0) { console.log(`文档 ${doc._id} 无待迁移图片,跳过`) continue } try { // 批量创建新的blogImage文档 await client.create(newImageDocs) // 更新原文档的content数组 await client.patch(doc._id) .set({ 'blogContent.content': updatedContent }) .commit() console.log(`成功迁移文档 ${doc._id} 的 ${newImageDocs.length} 张图片`) } catch (err) { console.error(`迁移文档 ${doc._id} 失败:`, err) } } console.log('所有迁移任务完成') } // 执行迁移 migrateImages().catch(console.error)
2. 配置环境变量
在项目根目录的.env文件中添加以下配置:
SANITY_PROJECT_ID=你的Sanity项目ID SANITY_DATASET=目标数据集名称(如production) SANITY_WRITE_TOKEN=具有写入权限的API Token(在Sanity管理后台生成)
3. 运行脚本
先安装依赖(若未安装):
npm install @sanity/client groq dotenv
执行脚本:
node migrate-image-references.js
关键注意事项
- 数据备份:执行迁移前务必用
sanity dataset export命令备份数据集,防止数据丢失。 - Schema一致性:确保
blogImage的字段与原嵌套image完全一致,避免数据遗漏。 - 分批处理:若文档数量极多,可修改GROQ查询添加分页条件(如
[0..99]),分批执行脚本。 - 验证结果:迁移完成后,在Sanity Studio中检查
blogImage文档是否生成,原文档的图片引用是否正常。
内容的提问来源于stack exchange,提问作者Zaid Ahmed
相关产品推荐
相关产品推荐

