触发器报错:record 'new'无'raw_user_meta_data'字段求助
触发器函数报错:record "new"不存在"raw_user_meta_data"字段
事件信息
{"component":"api","error":"failed to close prepared statement: ERROR: current transaction is aborted, commands ignored until end of transaction block (SQLSTATE 25P02): ERROR: record \"new\" has no field \"raw_user_meta_data\" (SQLSTATE 42703)","level":"error","method":"POST","msg":"500: Database error saving new user","path":"/signup","referer":"http://localhost:3000","remote_addr":"176.232.21.227","request_id":"8b6a13d9e53c0535-OTP","time":"2024-08-21T10:53:07Z"}
问题描述
我遇到上述数据库错误,提示record 'new'不存在'raw_user_meta_data'字段,同时事务终止,后续命令被忽略。以下是我创建的触发器函数:
CREATE OR REPLACE FUNCTION handle_new_user() RETURNS TRIGGER AS $$ BEGIN INSERT INTO public.profiles ( id, username, full_name, avatar_url, country, province, gender, active ) VALUES ( NEW.id, NEW.raw_user_meta_data->>'username', NEW.raw_user_meta_data->>'full_name', NEW.raw_user_meta_data->>'avatar_url', NEW.raw_user_meta_data->>'country', NEW.raw_user_meta_data->>'province', NEW.raw_user_meta_data->>'gender', (NEW.raw_user_meta_data->>'active')::boolean ); RETURN NEW; END; $$ LANGUAGE plpgsql security definer;
我已知STATEMENT级触发器可能引发该问题,但我的触发器已设为ROW级,请问为何仍报错?
问题原因
核心问题是触发器绑定的表中不存在raw_user_meta_data字段——哪怕是ROW级触发器,当函数试图访问NEW记录里不存在的字段时,必然会抛出这个错误。常见诱因包括:
- 触发器绑定的表不是你预期的表(比如误绑定到自定义用户表,而非Auth服务的用户表)
- 目标表的结构发生过变更,
raw_user_meta_data字段被删除或重命名 - 若使用Supabase这类Auth服务,注册接口未传入元数据只会导致字段值为NULL,不会引发“字段不存在”的错误,因此核心还是表结构不匹配。
解决步骤
- 检查触发器绑定的表
执行以下SQL,确认触发器实际绑定的目标表:
SELECT tgrelid::regclass AS table_name FROM pg_trigger WHERE tgfoid = 'handle_new_user'::regproc;
如果该表没有raw_user_meta_data字段,需将触发器绑定到正确的表(比如Supabase的auth.users表)。
- 验证目标表结构
查看目标表的字段列表,确认raw_user_meta_data是否存在:
SELECT column_name FROM information_schema.columns WHERE table_name = '你的表名' AND table_schema = 'public';
若字段确实不存在,要么给目标表添加该字段,要么调整触发器函数逻辑,移除对该字段的依赖。
- 兼容字段缺失的函数修改(可选)
如果无法确保字段始终存在,可以在函数中添加空值判断,避免触发错误:
CREATE OR REPLACE FUNCTION handle_new_user() RETURNS TRIGGER AS $$ BEGIN INSERT INTO public.profiles ( id, username, full_name, avatar_url, country, province, gender, active ) VALUES ( NEW.id, COALESCE(NEW.raw_user_meta_data->>'username', ''), COALESCE(NEW.raw_user_meta_data->>'full_name', ''), COALESCE(NEW.raw_user_meta_data->>'avatar_url', ''), COALESCE(NEW.raw_user_meta_data->>'country', ''), COALESCE(NEW.raw_user_meta_data->>'province', ''), COALESCE(NEW.raw_user_meta_data->>'gender', ''), COALESCE((NEW.raw_user_meta_data->>'active')::boolean, true) ); RETURN NEW; END; $$ LANGUAGE plpgsql security definer;
内容的提问来源于stack exchange,提问作者emirbagdatli
相关产品推荐
相关产品推荐

