如何使用Supabase原生Fetch API向关联的城市表与位置表插入关联数据?
如何使用Supabase原生Fetch API向关联的城市表与位置表插入关联数据?
嘿,我帮你分析下问题哈~你现在的报错核心原因很明确:你直接把position的JSON对象塞给了city表里的position外键字段(这个字段是bigint类型,只能存数字ID),数据库自然没法把JSON转换成整数,所以才报了那个错。
下面给你两种靠谱的解决办法,都是用Supabase原生Fetch API实现的,你可以根据自己的需求选:
方案一:分两步插入(直观易懂,适合新手)
思路很简单:先把位置数据插入到position表,拿到返回的位置ID,再用这个ID关联插入城市数据到city表。
代码示例
// 第一步:插入位置数据,返回新位置的ID async function addPosition(lat, lng) { const res = await fetch('https://你的项目ID.supabase.co/rest/v1/position', { method: 'POST', headers: { 'Content-Type': 'application/json', 'apikey': '你的Supabase API密钥', 'Authorization': 'Bearer 你的Supabase API密钥' }, body: JSON.stringify({ lat, lng }) }); const positionData = await res.json(); return positionData[0].id; // 取出插入后返回的位置ID } // 第二步:插入城市数据并关联位置ID async function addCityWithPosition(cityInfo, positionId) { const { cityName, date, notes, emoji, country } = cityInfo; const res = await fetch('https://你的项目ID.supabase.co/rest/v1/city', { method: 'POST', headers: { 'Content-Type': 'application/json', 'apikey': '你的Supabase API密钥', 'Authorization': 'Bearer 你的Supabase API密钥' }, body: JSON.stringify({ cityName, date, notes, emoji, country, position_id: positionId // 用拿到的位置ID关联外键 }) }); return await res.json(); } // 整合调用 async function insertAllData(rawData) { try { const posId = await addPosition(rawData.position.lat, rawData.position.lng); const cityResult = await addCityWithPosition(rawData, posId); console.log('数据插入成功!', cityResult); } catch (err) { console.error('插入出错:', err); } } // 你的原始数据 const yourData = { "cityName":"Alfajarin", "date":"2025-12-17T13:52:08.812Z", "notes":"", "emoji":"", "country":"Spain", "position":{"lat":41.623655390686395,"lng":-0.6591796875000001} }; // 执行插入 insertAllData(yourData);
方案二:嵌套插入(一步到位,更简洁)
如果你的两张表已经在Supabase控制台里设置了正确的外键关联(比如city表的position_id关联到position表的id),还可以用Supabase REST API支持的嵌套插入功能,一步完成两张表的数据插入。
代码示例
async function insertCityWithNestedPos(rawData) { const { cityName, date, notes, emoji, country, position } = rawData; const res = await fetch('https://你的项目ID.supabase.co/rest/v1/city?select=*,position(*)', { method: 'POST', headers: { 'Content-Type': 'application/json', 'apikey': '你的Supabase API密钥', 'Authorization': 'Bearer 你的Supabase API密钥', 'Prefer': 'return=representation' // 让API返回插入后的完整数据(包含关联的位置信息) }, body: JSON.stringify({ cityName, date, notes, emoji, country, position: { // 这里的key要和你在Supabase里设置的关系名一致 data: position } }) }); return await res.json(); } // 调用插入 insertCityWithNestedPos(yourData) .then(result => console.log('插入成功:', result)) .catch(error => console.error('插入失败:', error));
重要注意事项
- 记得把代码里的
你的项目ID和你的Supabase API密钥替换成你自己项目的真实信息 - 确保两张表都开启了RLS(行级安全),并且给当前使用的用户(比如前端调用常用的
anon用户)开启了INSERT权限,否则会有权限错误 - 如果用嵌套插入,要注意
position这个key的名称必须和你在Supabase控制台里设置的表关联关系名称一致,你可以在Supabase的API页面查看city表的关联关系,确认名称没错
这样改完之后,就不会再出现那个类型转换的错误啦~




