# 데이터 읽고 쓰기

PostgREST와 같은 문법이에요. 기존 클라이언트 SDK를 그대로 써요.

```
GET    /rest/v1/<표>?select=id,body&order=created_at.desc&limit=20
GET    /rest/v1/<표>?body=ilike.*서울*
POST   /rest/v1/<표>          본문: {"body":"안녕"}  또는  [{...},{...}]
PATCH  /rest/v1/<표>?id=eq.<값>
DELETE /rest/v1/<표>?id=eq.<값>
```

## 연산자

`eq` `neq` `gt` `gte` `lt` `lte` `like` `ilike` `match` `imatch` `cs` `cd` `ov` `sl` `sr` `nxr` `nxl` `adj` `isdistinct` `is` `in` `fts` `plfts` `phfts` `wfts`

앞에 `not.`을 붙이면 뒤집혀요(`status=not.eq.done`). `or=(a.eq.1,b.gt.2)`, `and=(…)`로
조건을 묶을 수 있고, `like`·`ilike`의 `*`는 `%`와 같아요. `select`에는 별칭(`label:title`),
형 변환(`id::text`), 외래 키로 이어진 표(`*,author(name)`)를 쓸 수 있어요.
함수는 `POST /rest/v1/rpc/<함수>`로 불러요. 포함된 표에 거는 조건과 다대다 관계는 아직 없어요.
없는 것이 필요하면 `run_sql`로 뷰를 만들어 그 뷰를 읽으세요.

**모르는 연산자는 무시하지 않고 이름을 대며 거부해요.** 걸리지 않은 필터는 정보 노출이 되기 때문이에요.

## 한글 부분 검색

`pg_trgm`이 켜져 있어요. 한국어는 조사 때문에 단어 검색이 잘 안 맞으니
세 글자 단위 비교를 써요.

```sql
create index if not exists notes_body_trgm on notes using gin (body extensions.gin_trgm_ops);
select * from notes where body % '서울';
```

임베딩 검색(pgvector)과 지도(PostGIS) 같은 다른 확장은 `blackwall://extensions`를 보세요.

## CSV로 내보내고 가져오기

`export_table_csv`가 표의 줄을 CSV로 돌려줘요(1MB까지, 넘으면 줄 단위로 잘라 `truncated`). `filters`와 `sort`로 범위와 순서를 고르고, 큰 표는 범위를 나눠 여러 번 받아요.
`import_table_csv`는 CSV를 표에 넣어요(2MB, 10,000줄까지). 첫 줄의 열 이름과 같은 열에 들어가고, 한 줄이라도 들어가지 못하면 아무것도 넣지 않고 줄 번호와 이유를 알려 줘요.
REST로는 `GET /v1/projects/<ref>/tables/<표>/csv`와 `POST /v1/projects/<ref>/tables/<표>/csv {csv, columns}`이에요.

---

https://end.blackall.ai/docs/data-api?lang=ko
