Flutter开发:如何用Postgres/Supabase Edge Function查询用户及关联物品?
可以通过单个查询获取目标嵌套结构结果
你有两种可行方案实现需求:
方案一:直接使用Supabase关联查询(无需Edge Function)
Supabase基于PostgreSQL,支持通过SQL聚合函数或SDK的嵌套查询语法生成嵌套结构:
方式1:执行自定义SQL
通过json_agg和json_build_object聚合生成items列表:
SELECT u.user_id, u.name, json_agg(json_build_object('item_id', i.item_id, 'cost', i.cost)) AS items FROM "user" u LEFT JOIN user_items ui ON u.user_id = ui.user_id LEFT JOIN items i ON ui.item_id = i.item_id WHERE u.user_id = 1 GROUP BY u.user_id, u.name;
在Flutter中调用该SQL:
final response = await supabase.rpc('get_user_with_items', params: {'user_id': 1}); // 或者直接执行原始SQL final response = await supabase.from('user').raw(''' SELECT u.user_id, u.name, json_agg(json_build_object('item_id', i.item_id, 'cost', i.cost)) AS items FROM "user" u LEFT JOIN user_items ui ON u.user_id = ui.user_id LEFT JOIN items i ON ui.item_id = i.item_id WHERE u.user_id = 1 GROUP BY u.user_id, u.name ''');
方式2:使用Supabase Flutter SDK的嵌套查询
SDK支持更简洁的嵌套查询语法,自动关联表:
final userData = await supabase .from('user') .select(''' user_id, name, user_items!inner(items(item_id, cost)) ''') .eq('user_id', 1) .single(); // 格式化为目标结构 final result = { 'user_id': userData['user_id'], 'name': userData['name'], 'items': userData['user_items'].map((itemLink) => itemLink['items']).toList(), };
方案二:使用Supabase Edge Function封装查询
如果需要封装逻辑或处理复杂业务,可以创建Edge Function:
1. 编写Edge Function(示例为TypeScript)
import { createClient } from 'https://esm.sh/@supabase/supabase-js'; Deno.serve(async (req) => { const supabase = createClient( Deno.env.get('SUPABASE_URL')!, Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')! ); const { userId } = await req.json(); if (!userId) return new Response('Missing user ID', { status: 400 }); const { data, error } = await supabase .from('user') .select('user_id, name, user_items!inner(items(item_id, cost))') .eq('user_id', userId) .single(); if (error) { return new Response(JSON.stringify({ error: error.message }), { status: 400 }); } // 转换为目标嵌套结构 const formattedResult = { user_id: data.user_id, name: data.name, items: data.user_items.map((link) => link.items) }; return new Response(JSON.stringify(formattedResult), { headers: { 'Content-Type': 'application/json' }, }); });
2. 在Flutter中调用Edge Function
final functionResponse = await supabase.functions.invoke( 'get-user-with-items', body: {'userId': 1}, ); final targetResult = functionResponse.data;
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

