DB에는 다음과 같이 데이터가 저장되어 있다.
DB에서 { _text: "1234" }
를 jsondata
컬럼의 값으로 가지고 있는 row를 출력하고자 다음과 같은 코드를 작성했다.
const supabaseOutputTest = async () => {
const { data, error } = await supabase
.from("test_table")
.select()
.eq("jsondata", JSON.stringify({ _text: "1234" }));
if (error) {
console.log("에러 발생", error);
} else {
console.log("데이터 출력 성공", data);
}
};
supabaseOutputTest();
하지만 다음과 같은 에러가 발생했다.
에러 발생 {
code: '22P02',
details: 'Token "object" is invalid.',
hint: null,
message: 'invalid input syntax for type json'
}
원인은 eq()
메서드의 작동 방식에 있었다.
.eq('mt20id', 'PF267495')
위와 같은 코드가 있다고 하면, Supabase JS 클라이언트는 eq()
를 HTTP 요청 쿼리 스트링에 다음과 같이 변환하여 Supabase의 PostgREST 서버에 전달한다.
GET https://your-project.supabase.co/rest/v1/your_table?mt20id=eq.PF267495
Headers:
apiKey: [your API key]
Authorization: Bearer [token]
따라서 eq.{value}
에서의 value
는 반드시 문자열(string)로 변환되어야 하며, Supabase JS 클라이언트는 .toString()
을 자동 호출하여 처리한다.
위 에러 상황에서의 코드와 같이 eq()
메서드의 인자로 기본 타입 데이터를 넣지 않고 객체와 같은 참조 타입 데이터를 넣는다면, String()
에 의해 [object Object]
와 같은 형태로 변환되어 서버에 전달되고,
결국 Supabase 서버에서는 이런 쿼리를 구성하게 된다.
WHERE jsondata = [object Object]
저런 데이터는 DB 테이블에 존재하지 않기 때문에 에러가 발생한 것이다.
json 형식의 데이터를 비교하기 위해서는 db 테이블 컬럼의 데이터 형식이 json/jsonb 인 게 좋다. 만약 db 테이블 컬럼의 형식이 문자열(text)이라면 그 데이터와 형식이 공백을 포함하여 정확히 일치해야 하므로 의도치 않은 에러가 발생할 확률이 높다.
객체를 전달할 경우, JSON.stringify()
메서드를 사용해 JSON 문자열로 변환하여 전달한다.